Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofill does not trigger onChange

I have a login form, when the page is opened, Chrome automatically fills the credentials. However, onChange event of input elements are not being triggered.

Clicking anywhere on the page makes them registered in value attribute of the input, which is what we need. I tried doing event.target.click(), that did not help.

In the onChange I set the values into state like:

this.setState({ email: event.target.value })

And the submit button is disabled if email.length === 0.

So even if page shows that credentials are filled, submit button still looks disabled.

Since clicking anywhere registers the values, clicking the submit button also registers them before submitting. So it works perfectly.

It is not about timing though, field is never being filled. When I open the Developer Console and check, the value field is empty, until I click somewhere.

Only issue here is that the button looks disabled because email input value is empty until something is clicked. Is there a hacky solution for this?

like image 356
naezith Avatar asked Mar 19 '19 15:03

naezith


2 Answers

I stumbled across this issue because I had the same problem. Not in React, but the problem is universal. Maybe this will help anyone else who stumbles upon this.

None of the other answers actually answer the problem. The problem as described by the OP is that Chrome doesn't set the value of the inputs until there has been user interaction with the page. This can be clicking on the page, or even typing random things into the console.

After user interaction has occurred the value of the inputs are set and the change event is fired.

You can even visually see this, as the styling of the autofilled text is different when first presented and changes to the styling of the inputs once interaction has taken place.

Also: triggering a click or setting focus or whatever from code doesn't help, only real human interaction.

So polling for the value is not a solution, because the value will stay empty if the page is not clicked. Also stating that you can't rely on the change event is not really relevant, since the event is properly fired, upon the delayed setting of the value. It's the indefinite delay that's the problem.

You can however poll for the existence of Chrome's pseudo CSS classes. In Chrome 83 (june 2020) these are :-internal-autofill-selected and :-internal-autofill-previewed. These do change regularly however. Also, they are not directly present after rendering. So you should set a sufficient timeout, or poll for it.

Sloppy example in vanilla JavaScript:

var input = document.getElementById('#someinput');

setTimeout(() => {
   if (input.matches(':-internal-autofill-selected')) {
      /* do something */
   }
}, 500);

You still can't get the value at this point, so in that regard it still doesn't solve the problem, but at least you can enable the submit button based on the existence of autofilled data (as the OP wanted to do). Or do some other visual stuff.

like image 75
Karim Ayachi Avatar answered Oct 10 '22 08:10

Karim Ayachi


Using oninput instead of onchange would do the trick

like image 45
Cyber Valdez Avatar answered Oct 10 '22 07:10

Cyber Valdez