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

[TextField] Autofill values not triggering onChange in Chrome #22488

Closed
2 tasks done
ntbosscher opened this issue Sep 4, 2020 · 16 comments
Closed
2 tasks done

[TextField] Autofill values not triggering onChange in Chrome #22488

ntbosscher opened this issue Sep 4, 2020 · 16 comments
Labels
component: text field This is the name of the generic UI component, not the React module!

Comments

@ntbosscher
Copy link

Autofilled values don't trigger onChange event immediately in Chrome

This is a more specific issue originating from #17436 / #14427. Those issues deal with the more broad issue of labels not being positioned correctly. This is just about the onChange values not working correctly.

#14427 partially fixes the onChange issue. With #14427 if you click on the page somewhere, it will trigger onChange, but not immediately after the autofill

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

Autofilled inputs don't trigger onChange events in chrome when filled. In @next branch, they trigger onChange, but only after the user clicks somewhere on the page.

Expected Behavior 🤔

Autofilled inputs trigger onChange events in chrome when filled.

Steps to Reproduce 🕹

reproduce: https://react-ts-xphhbf.stackblitz.io/ (you must use the full screen view to reproduce, doesn't happen in the editor iframe)
code: https://stackblitz.com/edit/react-ts-xphhbf?file=index.tsx

Steps:

  1. Fill out the form with some bogus info and submit
  2. When prompted, save the password into your keychain
  3. Refresh the page
  4. Verify that your email/password has been autofilled
  5. Verify that the debug state doesn't show your autofilled values (the bug)

Context 🔦

I'm trying to setup a login screen where the login button is enabled only when you fill out the necessary inputs.

Your Environment 🌎

Tech Version
Material-UI v5.0.0-alpha.8
React 16.9.49
Browser Chrome 85.0.4183.83
@ntbosscher ntbosscher added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Sep 4, 2020
@ntbosscher
Copy link
Author

As mentioned elsewhere, this is related to facebook/react#1159. At the end of that thread, it seems to say that this issue is caused by react ignoring on-change events that come immediately after the input is mounted.

Based on that, probably the best solution is to use a setTimeout for a couple ms after the input is mounted and trigger an on-change if applicable then. I know using setTimeout is generally a hacky way to deal with things. But I think it might be the best solution here.

If we can agree on a solution, I'd be happy to write up a PR for it.

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 4, 2020

A couple of thoughts:

@oliviertassinari oliviertassinari added component: text field This is the name of the generic UI component, not the React module! and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Sep 4, 2020
@ntbosscher
Copy link
Author

ntbosscher commented Sep 4, 2020

Thanks for the reply @oliviertassinari

You can retrieve the value with the form submit event. How does the form libraries handle this problem?

I'd prefer not to do this b/c my UI function is to disable the submit button until the form values are filled out. As for other libraries, I don't know how they handle that.

I'm on my phone, I haven't looked at your codesandbox, however, what you are describing seems to be Chrome that doesn't trigger onChange nor give access to the value of the field until the page is focused for security reasons.

Hmm, that's interesting. I hadn't considered that. If I test my codesandbox by focusing the page before the inputs are rendered and they correctly trigger on-change events. Strange tho, that I can trigger an artificial click event on the input field to bypass that functionality... Doesn't really seem like a security feature to me...

I'd like to solve this b/c the use-case still stands. When I go to login to my webapp, I can't press the login button until I've clicked elsewhere on the page. Since there is a solution (albeit, not a great one), I think it would be helpful to address.

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 4, 2020

I can trigger an artificial click event on the input field to bypass that functionality...

Do you get the correct value back or is it empty?

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 4, 2020

b/c my UI function is to disable the submit button until the form values are filled out

Do you have a specific reason for doing such? If not, please don't. Let users understand why the form can't go through when they click on the submit button.

@ntbosscher
Copy link
Author

I can trigger an artificial click event on the input field to bypass that functionality...

Do you get the correct value back or is it empty?

I get the correct value

@ntbosscher
Copy link
Author

b/c my UI function is to disable the submit button until the form values are filled out

Do you have a specific reason for doing such? If not, please don't. Let users understand why the form can't go through when they click on the submit button.

It's following the pattern of "only actions when the required information is present". I think that's a pretty common UX pattern and doesn't seem unreasonably weird.

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 4, 2020

I had a look at the reproduction, I don't see any significant issue. The change event is fired. If you are not focusing the window, Chrome waits for this action. Also, unless there is a specific opportunity to solve the issue here, better close it.

@ntbosscher
Copy link
Author

Ok, I'll stick with my artificial click hack then.
Thanks for the discussion @oliviertassinari 👍

@sanzhardanybayev
Copy link

I have a simple solution for that, return null for a value.

Here's an example:

          <TextField
              label={errors.email || "Email"}
              name={'adminEmail'}
              error={!!errors.email}
              onChange={handleChange}
              value={values.email || null}
              variant="outlined"
              className={`mb-8 `}
              autoComplete="new-password"
          />

@gustavoeidt
Copy link

I have a simple solution for that, return null for a value.

Here's an example:

          <TextField
              label={errors.email || "Email"}
              name={'adminEmail'}
              error={!!errors.email}
              onChange={handleChange}
              value={values.email || null}
              variant="outlined"
              className={`mb-8 `}
              autoComplete="new-password"
          />

this solution throws a console error but visually it kinda works.

@sandroweb
Copy link

Does Not work for me! The problem continued...

@michele6000
Copy link

Any news about that?

@sandroweb
Copy link

sandroweb commented Jul 12, 2023

Any news about that?

Unfortunately, no. The problem persists. The Chrome browser can't follow my commands to deactivate the autofill feature.

@x8er
Copy link

x8er commented Oct 24, 2023

I have a simple solution for that, return null for a value.

Here's an example:

          <TextField
              label={errors.email || "Email"}
              name={'adminEmail'}
              error={!!errors.email}
              onChange={handleChange}
              value={values.email || null}
              variant="outlined"
              className={`mb-8 `}
              autoComplete="new-password"
          />

Works like a charm

@sajitkhadka
Copy link

I have a simple solution for that, return null for a value.

Here's an example:

          <TextField
              label={errors.email || "Email"}
              name={'adminEmail'}
              error={!!errors.email}
              onChange={handleChange}
              value={values.email || null}
              variant="outlined"
              className={`mb-8 `}
              autoComplete="new-password"
          />

It works but it gave me the following warning, so I put undefined instead and the problem went away.
Warning: value prop on input should not be null. Consider using an empty string to clear the component or undefined for uncontrolled components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module!
Projects
None yet
Development

No branches or pull requests

8 participants