[LiveComponent] Fix disabled choices being submitted by live form updates - #3792
[LiveComponent] Fix disabled choices being submitted by live form updates#3792Amoifr wants to merge 1 commit into
Conversation
📊 Packages dist files size differenceThanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.
|
|||||||||
4677a89 to
c64f4f8
Compare
|
Please target 3.x branch |
c64f4f8 to
5e6f268
Compare
|
Done! Rebased onto 3.x, dist rebuilt from the 3.x sources, PHP suite green (391 tests) and JS tests too, base switched. |
smnandre
left a comment
There was a problem hiding this comment.
Guard Breaks Backend State Sync ?
When the backend disables a previously-checked checkbox and sets its data to null/empty, extractFormValues() correctly returns null (line 272).
But setValueOnElement() guard prevents applying this null value because the element is disabled.
Result: DOM shows checked + disabled (contradictory/broken UI), when it should show unchecked + disabled.
Maybe the guard should NOT apply to SetValueOntoModelFieldsPlugin syncs, but only during morphdom to preserve user interactions during DOM updates.
wdyt ?
|
Thanks for the careful review! Applied: return types dropped from the test methods (Fabbot agrees with you), dist rebuilt on top of On the backend sync question, I think the scenario works as expected, because the guard never competes with the server: when the backend disables a previously checked checkbox and clears its data, the re-rendered HTML no longer carries |
77ae5d6 to
fc597e3
Compare
|
@Amoifr to be honest I'd be happy with one :) |
fc597e3 to
14fd667
Compare
|
Here it is, and writing it was instructive: to make the test meaningful the checkbox has to carry |
Browsers never submit disabled controls, but
extractFormValues()(whose contract is precisely "the raw POST data that would be sent if the form were submitted") included them. For an expandedChoiceTypewith a choice disabled throughchoice_attr, the aggregated parent value kept the disabled choice, so every live update re-submitted it: validation failed on live updates while a native submit of the very same form passed (the exact asymmetry reported).The fix makes
extractFormValues()apply browser parity: it drops the values of disabled choices (expanded multiple, expanded single) and treats a checked but disabled standalone checkbox as unsubmitted, whether the field is disabled at the form level (thedisabledoption) or only in HTML (adisabledattribute, e.g. set throughchoice_attr).No JS change:
SetValueOntoModelFieldsPluginonly syncs elements carryingdata-modelthemselves (Symfony forms only put it on<form>), and the twomorphdomsyncs only run for modified or focused elements, which a disabled control cannot be.Covered by a unit test on the extracted values, an end-to-end functional test (initially checked disabled choice, then a live update: the disabled value never reaches the submitted data), and a JS test pinning the server-side sync of a checkbox the server disables and clears (unchecked + disabled).
Note: disabled
<option>elements of a non-expanded<select>have the same theoretical issue through a different code path; left out to keep this focused, happy to follow up if wanted.