Problem/Motivation
Field widgets are using #limit_validation_errors to inform the validation handlers that they only need to care about a specific field being edited/updated in partial form updates (e.g. AJAX interactions).
Examples of these are the 'Add another item' button for multi-valued fields (\Drupal\Core\Field\WidgetBase::formMultipleElements()) and the 'Upload' buttons for File/Image fields (\Drupal\file\Plugin\Field\FieldWidget\FileWidget::process()).
The problem is that \Drupal\Core\Entity\ContentEntityForm::validateForm() does not take this into account when filtering validation errors to fields that are being edited by the form, which, combined with the fact that some $form_state properties are being stripped by Form API to the element(s) specified in #limit_validation_errors, leads to constraint violations that are built incorrectly (i.e. without a proper validation path). This further leads to confusing errors like #2614250: Number widget validation can break AJAX actions and #2553983: Required textarea with summary breaks ajax events for other fields..
Proposed resolution
Restrict validation errors to the field(s) that were actually edited in the entity form, as specified by $form_state->getLimitValidationErrors().
Remaining tasks
Review.
User interface changes
Nope.
API changes
Nope.
Data model changes
Nope.
| Comment | File | Size | Author |
|---|---|---|---|
| #18 | interdiff-18.txt | 743 bytes | amateescu |
| #18 | 2901943-18.patch | 7.7 KB | amateescu |
| #6 | interdiff-6.txt | 2.82 KB | amateescu |
| #6 | 2901943-6.patch | 7.65 KB | amateescu |
| #6 | 2901943-6-test-only.patch | 6.02 KB | amateescu |
Comments
Comment #2
amateescu commentedThis should fix all the (seemingly separate) problems we're seeing in this area.
This problem has already been triaged as major in #2027059-60: Improve the documentation of WidgetBase::errorElement() for mapping violation property paths to form elements, so I'm borrowing some tags from that issue.
Comment #4
amateescu commentedJust closed *a lot* of duplicates..
Comment #5
berdirNice. @amateescu++
Wondering if we could make this a bit shorter by always starting with the edited field names, an array filter on the limit validation errors and then an array intersect but that might not actually be easier to understand and quite possibly slower as when we have limit validation errors, it is almost always for a single field. So this seems fine.
do we care about renaming the method if we specifically use the trait, I think we usually just do that for BC in the base classes?
Does it make sense to also verify that we do get validation errors when e.g. trying to save now with an empty required field?
I guess we have plenty of tests that already do that, but might not hurt to do it in the context of this scenario too?
Comment #6
amateescu commented@Berdir, thanks for taking a look :)
Re #5:
Comment #8
berdirLooks good to me and fix tons of issues.
Comment #9
drupalfan2 commentedsubscribe
Comment #10
drupalfan2 commentedI temporarily solved this removing the following 4 lines:
Works great then.
Comment #11
amateescu commented@drupalfan2, or you could apply the patch from #6 and have it fixed properly until this issue lands in core.
Comment #12
drupalfan2 commentedBut removing this 4 lines (see #10) is much easier.
Hoping for a solution in core.
Comment #14
amateescu commentedThat was a random fail in
Drupal\KernelTests\Core\Entity\ContentEntityChangedTest.Comment #15
ibustos@amateescu suggested that #2784015: Widget validation crashes on ItemList violations for widgets with a custom errorElement() implementation would be fixed by this issue but the latest patch here doesn't fix that so either this needs some more work or that other issue can be reopened.
Comment #16
amateescu commented@ibustos, I looked a bit more into that issue and you're right, the patch here does not fix it. I just reopened it and posted a test-only patch, so it can be fixed on its own.
Comment #17
catchMinor but what's wrong with $edited_fields[] here? Do we really need the explicit +=, and if so could use a comment explaining why.
Comment #18
amateescu commentedWe don't really need it, I think I wanted to be sure that we don't have duplicate field names in that array, but we can also do it like this.
Comment #19
catchThanks that's a bit more explicit.
Committed 12a28a5 and pushed to 8.5.x. Thanks!
We're in a freeze for the 8.4.0 release, I think this is backportable for 8.4.1 though so leaving RTBC to cherry-pick later.
Comment #21
catchComment #24
jds1Can we get this reopened/RTBC so it doesn't fall off the radar for 8.4.1? Just ran into this issue and see it is auto-closed. Thanks!
Comment #25
amateescu commented@if-jds, this patch was already committed to the 8.4.x branch so it will be part of the 8.4.1 release.