Problem/Motivation
The Field UI attaches a change event listener to every form element inside field storage config edit form to update the field config form based on changes made to the storage settings. However, if user submits the form while the change event is still being processed, this leads to a race condition where incomplete or invalid data may be saved.
For example, creating field with a negative value in the Allowed number of values, and directly clicking save button on the form (without unfocusing the field) then the form is successfully saved instead of showing the validation error.
In some cases, such as the list field, this could lead into losing changes made to the options.
Steps to reproduce
- Navigate to the add field page of the of any content type.
- Select the date type as filed.
- Manually enter any negative value in Allowed number of values in the form.
- Save the form.
Proposed resolution
The quick fix for this would be to disable the submit button while the AJAX is processing. This would not be the ideal UX but would address the critical data loss issue. We could open a follow-up issue to submit the form without first triggering the change event.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | Screenshot 2023-10-30 at 9.09.38 AM.png | 118.24 KB | lauriii |
Issue fork drupal-3397594
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3397594-form-validation-is
changes, plain diff MR !5184
Comments
Comment #2
lauriiiI'm wondering if there's a step missing from the steps to reproduce? Tried to follow the steps but it looks like validation is preventing this from happening. Also looked at the code and didn't find anything risky in the field type.
Comment #3
utkarsh_33 commentedSo if we enter any negative value in the given field( which updates the message shown using Ajax) and save the form directly without waiting for the Ajax response then it saves the form even after the message is shown up. I'll write a test to demonstrate this.
Comment #5
utkarsh_33 commentedComment #6
smustgrave commentedRebased to run test-only feature
Which is good.
Manually testing I can confirm the issue following the steps in the issue summary.
Applying the MR I was unable to advance the form and got the correct error message.
Comment #7
alexpottDiscussed this issue with @lauriii. This issue can cause a problem for list fields where you enter some values in the allowed values and then press submit and they are not saved as you've pressed the submit before the ajax has run. So this causes data loss - hence making it critical.
I'm not sure about the fix as form.js is loaded on every form.
Comment #8
lauriiiComment #9
utkarsh_33 commentedComment #10
lauriiiThanks @Utkarsh_33! I looked into the APIs AJAX system provides and couldn't figure out a better way to do this in the Field UI module. Maybe this is something the AJAX system should handle so that we wouldn't have to override and listen to the AJAX events? Can we file a follow-up to investigate a better solution. This seems fine since it addresses a critical bug.
Comment #11
catchDouble click prevention was added in #1705618: Double click prevention on form submission in 2014. There are open issues like #3251249: Should double-click prevention return early when isDefaultPrevented?. I have no idea if that prevention is supposed to work in that situation and is broken, or never worked for it though.
Comment #12
lauriiiThis is different from the double click scenario. This is when you have two events triggered at the same time. This can happen with blur/change event listeners when users clicks a button that triggers the click event. What the MR does is it marks the submit button (in Field UI specifically) disabled while the other AJAX request is triggering to avoid the race condition caused by triggering multiple events at once.
Comment #13
alexpottI think this is good for now - it's a specific fix caused by the issue of have field storage and field config on the same form. I think there is a possible follow up to think about whethere we should prevent all form submission whilst we're ajaxing.
Committed and pushed 27f9fa664c0 to 11.x and 07830391275 to 10.2.x. Thanks!
Comment #16
utkarsh_33 commentedI have opened a follow-up for finding a better(more generic) solution this problem in Find a generic way to resolve race condition on AJAX change event and form submission.