Vue: Vue not detecting autofill changes

Created on 17 Sep 2015  ·  27Comments  ·  Source: vuejs/vue

This was previously discussed

Here's my SPA login
login

The submit button is disabled, when the browser autofills my user/pass

Submit Markup

           <input type="submit" value="LOG IN" v-on="click: login($event)" class="btn btn-block btn-info btn-lg"
                       v-attr="disabled: (!email||!password||processing)"
                       tabindex="3">
Initial State
       data: function () {
            return {
                email: '',
                password: '',
                processing: false
            }
        },

Focusing the textboxes, causes the LOG IN button to be enabled

Google Chrome 45.0.2454.85 m

Most helpful comment

@krivoops
I ran into a similar situation as you and ended up basing a solution off of this article https://medium.com/@brunn/detecting-autofilled-fields-in-javascript-aed598d25da7

My mounted function ended up looking like this (dont copy paste this as this has code unique to my component 😊)

mounted() {
    var el = this.$el.getElementsByTagName('input')[0];
    const autoFillClass = 'input-dirty',
        onAutoFillStart = (el) => el.parentNode.classList.add(autoFillClass),
        onAutoFillCancel = (el) => el.parentNode.classList.remove(autoFillClass),
    onAnimationStart = ({ target, animationName }) => {
        switch (animationName) {
            case 'onAutoFillStart':
                this.updateInput(el)
                return onAutoFillStart(target)
            case 'onAutoFillCancel':
                this.updateInput(el)
                if (!el.value && !el.placeholder) {
                    return onAutoFillCancel(target)
                }
        }
    }
    el.addEventListener('animationstart', onAnimationStart, false)
}

This is not a beautiful solution but it does what we need it to do for our app. Good luck!

All 27 comments

This applies to ANY autofill, not just login pages

Have you tried the autofill-event polyfill from the original Angular thread? If the polyfill correctly fires change event Vue should be able to catch it: https://github.com/tbosch/autofill-event

Meh, that polyfill only works with jQuery/Angular. I guess we need an even more generic polyfill.

Autocomplete seems to work fine. Is this only for the case where the browser autofills on page load?

Actually, I'm having issues on initial page load, and later autofill on a separate form

That polyfill also doesn't appear to work, even though I have jquery loading

Can you try this: in your Vue instance's compiled hook, do the following:

var el = this.$el
setTimeout(function () {
  $(el).find('input').trigger('change')
}, 20)

That doesn't fix it sadly.

I added this

<pre>{{$data | json}}</pre>

And now I notice everything is being autofilled except the password input

tmp
Once I click _anywhere_ in the DOM, the login button gets enabled

Perhaps this is a security feature?

Are you saying the email data is now updated but not the password?

The email appears to be loaded even without the polyfill

Perhaps this is related to https://bugzilla.mozilla.org/show_bug.cgi?id=87943

Sounds like a browser autofill implementation issue... btw what version of Vue are you using?

0.12.14

Just to update, vue autofills fine on Firefox 38, not sure why chrome's password manager doesn't work too. Anyway, thanks for looking into the issue :)

Theoretically, you can always wait for a short period after page load, then force trigger change events on the input fields - unless Chrome has security limitations for this approach.

@yyx990803 同样遇到了这个问题,该怎样绕过去呢,延时触发change事件也不起作用

Hi guys, is there any advice how to correctly solve this in 2017?

I have the same problem too, any advice?

Ya me too ! Anything new about this issue since ?

Hi everyone
My solution is to turn input into component and give a ref for it.
<template> <div> <input ref="input" type="text" v-model="localValue" /> </div> </template>
Then use a mounted hook with emitting 'input' with js input element value
mounted() { this.$emit('input', this.$refs.input.value) },

Its seems possible to do so without component for input but you should not. I am convinced that turning inputs into separated components is a good practice

@krivoops
I ran into a similar situation as you and ended up basing a solution off of this article https://medium.com/@brunn/detecting-autofilled-fields-in-javascript-aed598d25da7

My mounted function ended up looking like this (dont copy paste this as this has code unique to my component 😊)

mounted() {
    var el = this.$el.getElementsByTagName('input')[0];
    const autoFillClass = 'input-dirty',
        onAutoFillStart = (el) => el.parentNode.classList.add(autoFillClass),
        onAutoFillCancel = (el) => el.parentNode.classList.remove(autoFillClass),
    onAnimationStart = ({ target, animationName }) => {
        switch (animationName) {
            case 'onAutoFillStart':
                this.updateInput(el)
                return onAutoFillStart(target)
            case 'onAutoFillCancel':
                this.updateInput(el)
                if (!el.value && !el.placeholder) {
                    return onAutoFillCancel(target)
                }
        }
    }
    el.addEventListener('animationstart', onAnimationStart, false)
}

This is not a beautiful solution but it does what we need it to do for our app. Good luck!

@christophernewton This is best solution so far

Still not get better solution to overcome this issue...

still I could not fixed out.

I am using password manager called as "Lastpass".So Same issue is happening with me. Anyone knows quick fix?

@pratikshaparsewar Did you look at my answer earlier?
https://github.com/vuejs/vue/issues/1331#issuecomment-353494416
This covers the browsers implementation but with last pass I'm not certain how they inject the values into the input, I think you would have better luck sending a message to the last pass team because its to do with their implementation rather then this thread which is based on the browsers saved password approach.

I will try to integrate in my code.Earlier for fixing that issue I removed
v-model and replaced with
this.email = event.target.value;
this.password = event.target.value; within the method.

On Fri, Sep 14, 2018 at 11:30 PM Jon Leibham notifications@github.com
wrote:

I found a workaround for autofill on page load:

mounted() {
setTimeout(function () {
document.querySelector('.form-input').blur
}, 100);
}

The setTimeout might not be necessary but I did notice some
inconsistencies without it.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/vuejs/vue/issues/1331#issuecomment-421436819, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIgYjXPo_pHNQewW7187cBaAVpHwkqR5ks5ua-7OgaJpZM4F_Zj-
.

--

https://about.me/pratikshaparsewar?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links

Pratiksha Parsewar
[image: https://]about.me/pratikshaparsewar
https://about.me/pratikshaparsewar?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links

Wrap your inputs in a form element

Solution for WebKit browsers, this work for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

julianxhokaxhiu picture julianxhokaxhiu  ·  3Comments

paceband picture paceband  ·  3Comments

seemsindie picture seemsindie  ·  3Comments

hiendv picture hiendv  ·  3Comments

franciscolourenco picture franciscolourenco  ·  3Comments