Vuetify: [Bug Report] v-text-field labels need to raise when browser autofill completes the field

Created on 27 Mar 2018  路  10Comments  路  Source: vuetifyjs/vuetify

screen shot 2018-03-27 at 13 11 16

Versions and Environment

Vuetify: 1.0.10
Vue: 2.5.16
Browsers: Chrome 65.0.3325.181
OS: Mac OS 10.11.6

Steps to reproduce

Fill in a dummy email and password such as

[email protected]
testtest

Allow Chrome browser to offer autosave. Re-visit the page and you will see that the v-text-field labels are rendered over the top of the input text.

Expected Behavior

Expect the labels to raise above the input field.

Actual Behavior

Labels are rendered over the top of the input field text.

Reproduction Link

https://codepen.io/mr6502/pen/geXxZQ

Other comments

This can be achieved by detecting browser autofill within the UI JavaScript:

https://stackoverflow.com/questions/11708092/detecting-browser-autofill

Note, this is not to be confused with autocomplete.

bug enhancement wontfix

Most helpful comment

I see. Thanks @KaelWD. In further reading, I came across this unhappy bug. Looks like it's a "feature". I came up with a workaround for my own login needs. Maybe it will help future visitors to this page. I'd prefer to use $refs rather than access the DOM directly, but the pseudo-class was throwing me off so I abandoned that path.

<template>
  <div>
    ... other markup ...
    <v-text-field
      v-model="email"
      :class="{ 'input-group--dirty': dirtyEmail }"
      label="Email"
      type="email"
    />
    <v-text-field
      v-model="password"
      :class="{ 'input-group--dirty': dirtyPwd }"
      label="Password"
      type="password"
    />
    ... other markup ...
  </div>
</template>

<script>
export default {
  name: 'Login',
  data () {
    return {
      dirtyEmail: null,
      dirtyPwd: null,
      email: '',
      password: '',
    };
  },
  mounted () {
    let times = 0;
    const interval = setInterval(() => {
      times += 1;
      if ((this.dirtyEmail && this.dirtyPwd) || times === 20) {
        clearInterval(interval);
      }
      this.dirtyEmail = document.querySelector('input[type="email"]:-webkit-autofill');
      this.dirtyPwd = document.querySelector('input[type="password"]:-webkit-autofill');
    }, 100);
  }
}
</script>

All 10 comments

To add clarification as @kgrosvenor mentioned in #2792 "this is a UI bug, i just raised the same issue - if field has some text in it, we could add the class that adds the label above on the page render, can we re open this issue?"

@manico also points out "That does not sound like autocomplete but Chrome autofill feature." which I agree with.

Normally this affects the password field, as chrome does not register the autofill as an input event. I'll take another look as we progress in the form refactor for v1.1

+1 on a desire to see this rectified. It happens for me on each field Chrome autofills, not just the password.

An observation: input-group--dirty doesn't get applied to an auto-filled input until I interact with the view. I need only to mouse click anywhere on the page and input-group--dirty gets applied.

I'm looking for a workaround in the interim. I've tried:

  mounted () {
    this.$nextTick(function () {
      console.log(this.password);
    });
  }

but no joy. Thanks for your help.

To be fair, even google's own login form has the same problem. I believe that was the justification for closing the other issues as wontfix.

I see. Thanks @KaelWD. In further reading, I came across this unhappy bug. Looks like it's a "feature". I came up with a workaround for my own login needs. Maybe it will help future visitors to this page. I'd prefer to use $refs rather than access the DOM directly, but the pseudo-class was throwing me off so I abandoned that path.

<template>
  <div>
    ... other markup ...
    <v-text-field
      v-model="email"
      :class="{ 'input-group--dirty': dirtyEmail }"
      label="Email"
      type="email"
    />
    <v-text-field
      v-model="password"
      :class="{ 'input-group--dirty': dirtyPwd }"
      label="Password"
      type="password"
    />
    ... other markup ...
  </div>
</template>

<script>
export default {
  name: 'Login',
  data () {
    return {
      dirtyEmail: null,
      dirtyPwd: null,
      email: '',
      password: '',
    };
  },
  mounted () {
    let times = 0;
    const interval = setInterval(() => {
      times += 1;
      if ((this.dirtyEmail && this.dirtyPwd) || times === 20) {
        clearInterval(interval);
      }
      this.dirtyEmail = document.querySelector('input[type="email"]:-webkit-autofill');
      this.dirtyPwd = document.querySelector('input[type="password"]:-webkit-autofill');
    }, 100);
  }
}
</script>

This is due to a bug with Chrome. We can revisit this later in life if they ever fix it.

vuetify 1.1.1
I put a placeholder :)

I still this this is a UI bug and not browser related, as it doesn't happen with other frameworks i am using, surely its a CSS class and extra stylings to remove the default behaviour, or an autocomplete prop with boolean value?

Just add a fake text-field on the top, like below:

v-text-field(label="hidden" style="display:none")
v-text-field(v-model="username" ...)
...

@Partoo it does not worked for me:

...<v-flex>
                      <v-text-field label="hidden" style="display:none"></v-text-field>
                      <v-text-field name="email" label="Email" id="email" type="email" v-model="email" required></v-text-field>
                    </v-flex>...

The UI in chrome (Version 67.0.3396.99 (Official Build) (64-bit)):

screen shot 2018-07-26 at 10 53 35 am

Was this page helpful?
0 / 5 - 0 ratings