
I tried detecting this via change events which didn't work. I also tried checking for value on init but that only worked for non-password inputs and was non-deterministic in terms of its timing.
Possible workarounds:
:autofillThis is clearly the most elegant solution, but looks like it's Chrome only
This will lead to the highest design fidelity, but is extremely inefficient and will incur a significant performance impact, especially on mobile browsers.
autocomplete="off"This would in theory solve the problem. However, it is not only an inconvenience to the user, but it's not guaranteed to work correctly for all types of input.
馃槩
Copied from https://github.com/google/material-design-lite/issues/4827
@traviskaufman what did you do to recreate this? Simply adding the autocomplete attributes doesn't seem to work for me.
Is your screen shot the result of something that autofills outside of the browsers autocomplete functionality? Vis-a-vis Dashlane or 1Password?
Is your screen shot the result of something that autofills outside of the browsers autocomplete functionality?
No, same functionality. autocomplete is a hint as to whether or not browsers (and extensions) should autofill things. However, Chrome for one ignores this.
Vis-a-vis Dashlane or 1Password?
These, and Lastpass that I use, all create this as well as Chrome's native autofill. Basically, anything that queries the node and sets the value pragmatically causes this. As they do document.querySelector('input').value = 'whatever' essentially which fails to trigger our JS to update the styling.
Would MutationObserver be an option? As a more efficient alternative to polling.
I'm not sure. My inclination is no, since adding text to <input> isn't really changing the DOM. Worth a look though.
MutationObserver won't work. Unless every tool sets the value using setAttribute (as it is going through the attribute observation) instead of the value property on the DOM node. Ref: StackOverflow
Okay, so a few updates on this.
TL;DR: There is an opportunity to improve functionality for some of the browser's native autocomplete features, but not when input values are set programmatically by extensions or the user if they only set the value and don't dispatch an event.
1: Webkit and Blink Browsers
For webkit and blink browsers there exists a pseudo class called -webkit-autofill which will allow us to either implement some CSS trickery to hide the label, or listen on the input to check if the event target matches that selector.
2: Firefox and a some IE/Edge
Paul Kinlan found that for Firefox, the onchange event will fire without any other events being invoked. I have implemented his solution in the foundation of mdc-textfield and it appears viable.
3: Extensions and Password Managers
There appears to be absolutely nothing sane we can do. We can poll the page at some frequency and check the value of all inputs on the page, but considering we cannot control for the number of inputs on a page, this could get out of hand very quickly.
There is a 15 year old bug on Bugzilla I bumped yesterday, and I filed one on the Chromium tracker, so there may be hope someday.
I vote for implementing 1 and 2 outlined above. I think that will cover a solid majority of use-cases, and is a best-effort approach for something that is pretty undetectable. For the extensions and password manager portions of it, we can document this in the textfield's README.
Furthermore, I wouldn't be opposed to throwing up a help-wanted issue trying to research some solutions on password manager auto-fill detection 馃槃
As a another possible workaround,
One absolutely grotesque hack we _could_ do, if need be, is actually hack the value property of the input element instance, and use it to determine when to change the styling of the form field.
const inputProto = Object.getPrototypeOf(inputElement);
const valueDesc = Object.getOwnPropertyDescriptor(inputProto, 'value');
if (valueDesc && typeof valueDesc.set === 'function') {
Object.defineProperty(inputElement, 'value', {
get: valueDesc.get || () => '',
set: function(value) {
valueDesc.set.call(this, value);
// custom logic handling when value is programmatically updated
},
enumerable: valueDesc.enumerable,
configurable: valueDesc.configurable,
});
}
We'd do this in an initialization routine, and restore the original descriptor in the destruction routine.
I have no idea if it would even work, and it's a pretty crappy thing to do, but we do something similar for our checkboxes to ensure they animate properly when checked and indeterminate are programmatically changed.
@traviskaufman After looking at the responses from the implementors of Firefox and Chrome regarding the issue of input elements not firing events for programmatic assignments of values, I don't think we should necessarily try to force this. They seem content that since the behavior is not in the standard, that inputs should not behave this way.
@amsheehan is this fixed? i'm still getting this issue with autocomplete data
Most helpful comment
@amsheehan is this fixed? i'm still getting this issue with autocomplete data