jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.98k stars 2.79k forks source link

is There a way to trigger onChange event when Chome autofill feature is used? #1047

Open andriy-fuzz opened 6 years ago

andriy-fuzz commented 6 years ago

❓Question

I came across an issue, where users are using Chrome Autofill to enter saved inputs into the form. The result is that Chrome autofill feature does not trigger onChange events in form. And that results in form being invalid and form values technically empty even though visually they have values. See image below.

This issue is also expressed in react and other libraries. Link: https://github.com/facebook/react/issues/1159

I am curious if anyone came across solutions that are easy to implement?

screen shot 2018-10-25 at 5 03 41 pm

jaredpalmer commented 6 years ago

@crosscompile didn't we fix this somehow on our login form?

andriy-fuzz commented 6 years ago

@jaredpalmer I am trying to programmatically trigger the form to validate. Without going into details, I have a hacky solution, but what would make it easier is if I get programmatically trigger formik to validate the field/forms. I am triggering the fields to focus/blur as can be shown in link below, but formik is not validating for some reason even though validateOnBlur is set to true.

stale[bot] commented 5 years ago

Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.

stale[bot] commented 5 years ago

ProBot automatically closed this due to inactivity. Holler if this is a mistake, and we'll re-open it.

addamove commented 5 years ago

I have the same problem @andriy-fuzz how you solved it?

gsoverini commented 5 years ago

This is still an issue, at least for fields that are validated onBlur. Users have to click on the form field in order to validate it, even if Chrome autofilled them.

svey commented 5 years ago

I also have this problem is there a solution?

jojo-tutor commented 5 years ago

Same here. The same problem.

FatehAK commented 5 years ago

Any updates on this issue? I am having problems with Google Places Autocomplete and Formik

TerrorOnMtHyjal commented 4 years ago

This issue still exists at the end of 2019. Has anyone successfully implemented a solution/workaround for this?

agos commented 4 years ago

same problem here. not so much validation, but for style application when the field is filled. On first render field.value is an empty string (as passed in from initialValues), onChange is not triggered until user interaction, so the field is filled but there is no chance to update the style

colepeters commented 4 years ago

Also seeing this issue. An additional oddity is that the validation seems to kick in when clicking anywhere on the page, even outside of the form. 👻

ioliinyk commented 4 years ago

Same problem and we don`t see appropriate workaround. Please reopen and fix.

Egenie-mih commented 3 years ago

We have the same problem. Please, reopen and fix

pcyglesias commented 3 years ago

I has the same problem. Still no solution?

torocsik-marton commented 3 years ago

We have the same issue...

o1st commented 3 years ago

The same problem..

lironezra commented 3 years ago

Same problem, there is any fix for that? Thanks guys!

mattrockwell commented 3 years ago

Having the same problem.

johnrom commented 3 years ago

Assuming everyone is having the problem on page load and not afterwards, (autofill is populated on page load, instead of clicking the "Fill" button), page-load autofill generally occurs before React has had a chance to initialize and trigger the synthetic events that Formik uses to update its state.

A way to solve this in the Field component would be to create a ref to its underlying input / select / textarea / etc, and then on mount check if the value has changed from the initial value, and is not empty.

If this issue occurs when performing "Fill" commands manually, that's another issue entirely, and would likely be a problem with Autofill vendors setting input.value = "value" without dispatching the actual change event, and I don't know how we'd work around that.

Pseudo-solution, with a few problems.


const Field = (props) => {
  const maybeRef = React.useRef<HTMLElement>(null);

  // we let users pass a ref themselves... I'm sure this typescript won't work
  const ref = props.innerRef || maybeRef;

  // this should already be done somewhere or at least is in my v3 PR.
  const [field, meta, helpers] = useField(propsUsedForUseField);

  const maybeSyncAutofill = useEventCallback(() => {
        // this doesn't work for checkboxes, radios, multi-select, etc
        const input: HTMLElement = ref.current;

        if (
            input instanceof HTMLInputElement &&
            input.type !== "radio" &&
            input.type !== "checkbox" && 
            input.value &&
            input.value !== field.value
        ) {
            helpers.setValue(input.value);
        }
  });

  const useEffect(() => {
    maybeSyncAutofill();
  }, []);

  // there are a bunch of different types of initialization, here's one example
  const {
    validate,
    ...otherNonInputProps,
    ...inputProps,
  }

  return React.createElement(props.as, {...inputProps, ref});
}
handhikadj commented 3 years ago

+1. running into this issue

terrynguyen255 commented 3 years ago

+1

Damilare1 commented 3 years ago

I hope this bug can be resolved on formik but I took inspiration from @johnrom suggestion to fix the bug on my input field as shown below

const Field = (props) => {
  const inputRef = React.useRef<HTMLElement>(null);

  // this should already be done somewhere or at least is in my v3 PR.
  const [{ value }, meta,{ setValue }] = useField(propsUsedForUseField);

  useEffect(() => {
    const input: HTMLElement = inputRef.current
    if (
      input instanceof HTMLInputElement &&
        input.value &&
        input.value !== value
    ) {
      setValue(input.value)
    }
  }, [setValue])

  return ( <Input ref={inputRef} />)
}

Hope this helps unblock somebody

billylo1 commented 1 year ago

It's 2023. This is still a problem (not just for Chrome though). Safari and Firefox too. Google Places Autocomplete doesn't get triggered if field is auto-filled by browser. I worked around it by manually dispatching a change event to take user back to that field.

ljones87 commented 1 year ago

+1 @billylo1 would you be able to provide an abbreviated example of how you went about "manually dispatching a change event to take user back to that field."? I've tried triggering .focus(), input & change events (via dispatchEvent) on the form inputs, but haven't had any success.

Anastasia-kot commented 11 months ago

try: https://www.npmjs.com/package/detect-autofill

add eventListener to Field component and set flag "isAutocompleted" to form state

ljones87 commented 10 months ago

I couldn't get any of the above options working correctly locally, so I put together a very hackey solution. The below code is implemented within our "AddressComponent", which is a component housing of all the Formik Field address inputs and the google address api widget from react-google-autocomplete

  const [addressAutoFilled, setAddressAutoFilled] = useState(false)
  const [autoFillValidated, setAutoFillValidated] = useState(false)

  if (addressAutoFilled && !autoFillValidated) {
    validateForm()
    setTimeout(() => setAutoFillValidated(true), 1)
  }

Just before calling our function, handleAddressSelect, I set both of the autocomplete tracking variables to false so the process will re-validate if they choose a new address

 onPlaceSelected: (addressDetails) => {
      setAutoFillValidated(false)
      setAddressAutoFilled(false)
      handleAddressSelect(addressDetails)
    },

handleAddressSelect then sets all our Formik address fields and finishes with setAddressAutoFilled(true).

I tried briefly using formik state and setFieldValue for the state values above, but did not have the same effect.

Vik2ry commented 3 months ago

Any updates on this issue? I am having problems with Google Places Autocomplete and Formik

Same here

JoanaMalinova commented 2 weeks ago

Having the same problem and finding it hard to believe there is no solution since it is a very common issue. Has anyone had any luck with this ?

Vik2ry commented 2 weeks ago

Having the same problem and finding it hard to believe there is no solution since it is a very common issue. Has anyone had any luck with this ?

Use react-select . This worked for me