Problem/Motivation
I have a form with a textfield element with an ajax callback. I use the ajax callback to display possible duplicate nodes.
Whenever the value of the textfield changes, an ajax request is triggered and the element will be temporarily disabled untill the ajax request finishes. The change event is triggered when the texfield loses focus and its value was changed.
If I submit the form during the ajax request, the value of the textfield will not be submitted and its old value will be used. This happens if I select the textfield, change its value and then directly click the save button of the form.
The reason AJAX elements are disabled, is to prevent the user from changing the element's value during the request. Ideally we should make the element readonly but the readonly property isn't available for all input elements. The current implementation uses the jQuery Form plugin's options.extraData to post the data of the disabled field. This works fine if there's only
one active ajax request.
Steps to reproduce
TBA
Proposed resolution
The solution I propose is to create a hidden input element for any ajax-disabled element and remove it when the ajax event finishes.
Remaining tasks
Confirm the solution
Review
Commit
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#57 | interdiff-55_57.txt | 639 bytes | Gauravvvv |
#57 | 1736308-57.patch | 6.94 KB | Gauravvvv |
#55 | 1736308-55.patch | 6.92 KB | Jelle_S |
Comments
Comment #1
kenneth.venken CreditAttribution: kenneth.venken commentedAttached is a patch with the proposed solution.
Comment #2
nod_Um not a bug as far as I can tell. And the solution is kinda hacky.
Comment #3
Damien Tournoud CreditAttribution: Damien Tournoud commentedDon't we also disable all the submit buttons during the AJAX request?
Comment #4
kenneth.venken CreditAttribution: kenneth.venken commented[Edited: Duplicate post]
Comment #5
kenneth.venken CreditAttribution: kenneth.venken commentedAttached is a simple Drupal 8 test module that illustrates the behaviour. After you enable the module, visit /ajax-form-test and change some of the textfield values. The module will print the form_state['values'] as received by the ajax callback.
To reproduce:
1) Change the value of element 1 to 1
2) Change the value of element 2 to 2 during the ajax request of element 1.
3) Wait for both ajax requests to finish.
The output returned by the last ajax request will be
while the expected result would be
Comment #6
kenneth.venken CreditAttribution: kenneth.venken commented@Damien Tournoud: Submit buttons aren't disabled during the ajax request as far as i can tell.
Comment #9
Nephele CreditAttribution: Nephele commentedI'm changing this issue into a major bug, because it causes loss of data -- specifically, user input data on a form can be lost when the form is submitted, without warning or explanation.
In particular, this issue always causes loss of data if a user simply edits any textfield that uses an ajax callback, and then clicks the Save button. Because the blur event (the trigger for the ajax processing) occurs simultaneously with the submit event, the modified field is always disabled and therefore missing when the form data is submitted to the server. Users are likely to repeat their edit, get the same result, and simply conclude that it is impossible to make edits on the website.
Re: "the solution is kinda hacky". The solution is functionally equivalent to putting the value into extraData: jquery.form.js puts all the extraData values into hidden input elements. If the jquery developers use this mechanism to add data to the submitted form, presumably it is the most reliable mechanism. Plus it is far preferable to telling users "Stop -- don't hit the Save button unless you have first made sure to click some other random location on your screen and then waited 5 to 10 seconds. Otherwise the Save button will NOT save your data."
I have tweaked the original patch and rerolled it against 8.0.x-dev. I'm also including a 7.x version of the patch, since I needed to roll it for my website.
Comment #12
Nephele CreditAttribution: Nephele commentedComment #13
Nephele CreditAttribution: Nephele commentedComment #14
abogomolov CreditAttribution: abogomolov commented@Nephele thank you! Patch works perfekt.
Comment #15
lokapujyaThere must already exist a more standard way of dealing with this?
Comment #17
vadim.hirbu CreditAttribution: vadim.hirbu at FFW commentedThanks @Nephele. Patch #12 works like a charm
Comment #18
lokapujyaIt might be ok, but should consider other solutions too. Such as: make the submit to wait for the blur to finish (or have the submit function perform the blur before submitting.) Hopefully, it can also be tested.
Comment #19
BerdirWas just bitten by this on a project, definitely a bug IMHO and fairly hard to identify.
Not submitting a form until ajax sounds interesting but I guess that might also be more complicated to implement?
Comment #21
_Archy_ CreditAttribution: _Archy_ at PitechPlus commentedConfirming that @Nephele's patch #12 fixes the issue. I think that his fix is better than waiting for the ajax to complete. Either way we have to do validation again (obviously when submitted) so why wait for it?
Comment #23
tomz0r CreditAttribution: tomz0r commentedAlso confirming Nephele's patch #12 fixes the issue.
Comment #24
Pavan B S CreditAttribution: Pavan B S at Valuebound commentedLine exceeding 80 characters, please review.
Comment #26
DedMoroz CreditAttribution: DedMoroz commentedRe-roll for 8.4
Comment #27
edurenye CreditAttribution: edurenye at ENDPHASYS Technologies commentedThis is working, but IMHO not in the best way.
This could confuse the user, as blocking the submit this way, the user has to click again in the submit button to submit the form.
I think that after the AJAX call finishes, we should trigger the submit or give the validation error in case the field validation did not pass.
At least this happens in 8.4.
Comment #28
edurenye CreditAttribution: edurenye at ENDPHASYS Technologies commentedThis is not the way, but works. Just as a workaround for the people.
Comment #29
edurenye CreditAttribution: edurenye at ENDPHASYS Technologies commentedMy patch does not work either is getting the previous value :(
Comment #30
edurenye CreditAttribution: edurenye at ENDPHASYS Technologies commentedMaybe we could try to do something like this somehow: https://stackoverflow.com/questions/4901899/action-on-blur-except-when-specific-element-clicked-with-jquery
So if we lose the focus for the submit button, we do not run AJAX call.
Comment #32
divined CreditAttribution: divined commentedIt is not a right solution. Most cases need to wait untill ajax complete before submit.
Image uploading i.e.
So, the right solution, in my opinion, it is disabling submit buttons during ajax requests,
Comment #34
jonathanshawThere are 2 separate issues:
1) We should disable the submit button during ajax requests
2) If clicking the submit button triggers an unrelated ajax request (as can happen e.g. if the ajax request is triggered by a changing textfield and clicking the submit button is the first thing a user does after typing in that textfield) then allow that have that unrelated ajax happen first before other submit handling.
Comment #37
gilsbert CreditAttribution: gilsbert commentedHello my friends. This issue has more than 8 years and is a major because the data loss.
I'm sorry to put extra pressure on it specially because I'm not able to help to conclude it but are we getting a solution soon?
Comment #39
trwill CreditAttribution: trwill commentedRerolling patch against 9.3.x
Comment #40
JeroenTTried to add a test that checks if the right values are submitted.
Comment #41
JeroenTComment #43
JeroenTComment #44
JeroenTComment #45
Eric_A CreditAttribution: Eric_A at RIVM, Dutch Open Projects commentedIs this related to #2830295: Concurrent ajax submits cause user data loss?
Comment #47
sukanya.ramakrishnan CreditAttribution: sukanya.ramakrishnan commentedThis patch is a life saver. I was totally lost debugging in the backend code as to why my input value was getting lost.
After a long search, found this issue and the patch. Hope this is committed to core soon. Will save a lot of headache!!
Thanks a million!!
regards,
Sukanya
Comment #48
mohangathala CreditAttribution: mohangathala as a volunteer and at TATA Consultancy Services for Pfizer, Inc. commented#43 is working for me.
Comment #49
quietone CreditAttribution: quietone at PreviousNext commentedIt is nice to see progress on an old issue, thanks everyone!
Reviewing the issue comments I see several that are questioning the solution, #2, #15, #18, #27, #32. I see that #21 supports the solution. Based on that it doesn't seem like there is consensus here on the solution. This needs some discussion. And the result placed in the Issue Summary.
I don't see a code review in this issue. That needs to be done as well.
This should also have a fail patch, to prove the fix is working.
I am removing the Ajax tag because this is in the 'ajax component', per the issue tag guidelines.
Comment #50
mohangathala CreditAttribution: mohangathala as a volunteer and at TA Digital commentedComment #52
Jelle_SReroll for 9.5.x
Comment #53
_utsavsharma CreditAttribution: _utsavsharma at OpenSense Labs for DrupalFit commentedFixed CCF for #52.
Please review.
Comment #55
Jelle_SReroll against 10.1.x
Comment #56
smustgrave CreditAttribution: smustgrave at Mobomo commented#49 called for issue summary update which believe still needs to happen.
Comment #57
Gauravvvv CreditAttribution: Gauravvvv at Axelerant for Drupal India Association commentedFixed, CCF in #55. Attached interdiff for same. leaving as NW, as issue summary still needs to update.