Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
MatTheCat opened this issue Jul 4, 2024 · 7 comments · May be fixed by #2376
Open

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

MatTheCat opened this issue Jul 4, 2024 · 7 comments · May be fixed by #2376

Comments

@MatTheCat
Copy link
Contributor

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?

@WebMamba
Copy link
Collaborator

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!

@smnandre
Copy link
Member

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
Copy link
Member

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

@smnandre
Copy link
Member

smnandre commented Oct 7, 2024

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 ?

@MatTheCat
Copy link
Contributor Author

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!

@smnandre
Copy link
Member

smnandre commented Oct 8, 2024

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
Copy link
Member

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

component.element.querySelectorAll('[data-model]').forEach((element: Element) => {

smnandre added a commit to smnandre/ux that referenced this issue Nov 14, 2024
@smnandre smnandre linked a pull request Nov 14, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants