ux icon indicating copy to clipboard operation
ux copied to clipboard

[LiveComponent] `ComponentWithFormTrait` out-of-sync with browsers’ changes

Open MatTheCat opened this issue 1 year ago • 6 comments

While working with symfonycasts/dynamic-forms I observed two issues which seem to stem from the same cause:

  • A not-expanded ChoiceType without placeholder whose value is null will appear as a <select> with the first <option> selected. The state of the component is then out-of-sync.
  • When refreshing a page with a form, browsers will populate fields with the value the user previously changed. As this happens without any user interaction, the component won’t be aware of these changes and will keep its default state.

The first issue can be worked around by adding a placeholder, and the second by setting to the fields which must keep their value the autocomplete attribute to off.

Maybe the component could react to the load event to update its state?

MatTheCat avatar Jul 04 '24 14:07 MatTheCat

Hey @MatTheCat could you move your issue to symfonycasts/dynamic-forms repo. I don't have any answer since I don't use this bundle sorry!

WebMamba avatar Jul 13 '24 13:07 WebMamba

The problem here is more global (and almost concerns classic forms too)..

You can experience it on the demo https://ux.symfony.com/demos/live-component/dependent-form-fields

Select something in the first input.

Submit

Then refresh (just once) your browser.

The browser select the choice you did select the first time, but the inner value is not set... and from there starts a desync.

There is no easy way out of this... but in term of UX this is not good :/

So the questiion is not "do we have a bug", but .... "how can we think about something smart to improve DX/UX when browsers autofill fields"

cc this Slack conversation too : https://symfony-devs.slack.com/archives/C01FN4EQNLX/p1720614759376709

smnandre avatar Jul 13 '24 14:07 smnandre

The solution seems to be some live changes on the form attributes (autocomplete / inert / etc..) executed during the component/form lifetime.

But this is something that must be done in userland i fear... as this could have negative impact on accessibility, or side effect on style, other scripts, etc...

Capture d’écran 2024-08-28 à 02 41 10
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
  • https://bugzilla.mozilla.org/show_bug.cgi?id=1688183

smnandre avatar Aug 28 '24 00:08 smnandre

Took me time, but i check tested all this deeply, on Firefox at least.

TL;DR; "autocomplete=off" on the form tag itself solves almost everything.

    {{ form_start(form, {
        attr: {
            autocomplete: 'off',
        }
    }) }}

You still can enjoy autocompletion if you specify it's type

 ->add('phone', TelType::class, [
      'mapped' => false,
      'label' => 'Phone',
      'attr' => ['autocomplete' => 'phone'],
  ])

This field will benefic from autocompletion "on focus"... but thanks to the root "autcomplete=off" attribute, no problem at all during loading.


So i guess this is mainly a matter of ... docs ?

smnandre avatar Oct 07 '24 23:10 smnandre

Thanks for testing!

Sadly, live components being incompatible with browsers keeping user-modified form values on reload seems like quite the deal-breaker 😅

In addition of being a workaround, autocomplete=off also wonʼt solve the non-nullable <select> null default value problem.

But if one has to live with it, this should indeed be documented!

MatTheCat avatar Oct 08 '24 05:10 MatTheCat

I'm more and more thinking there is something not clear about the state in live component forms. In the end there must be "one source of truth", not two.

What would you suggest for the select?

Because i also checked some (dirty) js things and i think we can trigger some change évent when the browser fill data. Not sure for the select as it is indeterminate.

smnandre avatar Oct 08 '24 12:10 smnandre

SO!

This is probably (partially at least) due to this code, that has not be updated since we allow "name" on inputs and not only data-model

https://github.com/symfony/ux/blob/89c7fa95d8d71af01fb604533755b2acbeb26ce5/src/LiveComponent/assets/src/Component/plugins/SetValueOntoModelFieldsPlugin.ts#L33

smnandre avatar Nov 14 '24 18:11 smnandre