Materialize: bug when browser auto fill forms

Created on 5 Dec 2014  Â·  39Comments  Â·  Source: Dogfalo/materialize

hey there, have you noticed that when someone hace already fill a form, the next time they see it the forms inputs have a yellow background and the autofill value gets mess up with the label (the both ocupe the same space making it un readable) or is this just happening to me?
captura de pantalla 2014-12-05 a las 3 01 34 p m

Most helpful comment

My solution was to fix it with good old css:

input:-webkit-autofill { +label { @extend .active; } } }

All 39 comments

I'm getting the same issue using ember.js {{input}} tags when the input is bound to data. The only way I could find to make them readable was to remove the input-field class from the surrounding div and forgo the nice UI behaviour.

EDIT: is this a duplicate of #181?

for me the solution was to avoid the browser from autofilling the form, i did it by adding autocomplete="off" to te form tag, this works with older browsers and to add two extra hiden input fields to the form like:

<pre><code>

<input type="text" style="display:n0ne;">
<input type="password" style="display:n0ne;">

</code></pre>

and that prevented the browser from autofilling my form.

I got a similar issue while using meteor and loading templates after jQuery's document.ready event. Looks like the event listener is not applied and the class="active" attribute is missing.

This should be the line which sets the active class for fields with content...
https://github.com/Dogfalo/materialize/blob/master/js/forms.js#L8

I'm trying to fix this with my meteor setup but not sure about how to get the same events in plain jQuery. A first improvement might be to expose the form setup as a dedicated function so developers can recall the form initialization as they need it...

try this:

$(window).load($.debounce(200,function(){
    $('input:-webkit-autofill').each(function(){
        if ($(this).val().length !== "") {
            $(this).siblings('label, i').addClass('active');
        }
    });
}));

based on:
http://stackoverflow.com/questions/7749689/detecting-chrome-saved-input-information-with-jquery

I suggest to use jquery.ba-throttle-debounce.js
http://benalman.com/projects/jquery-throttle-debounce-plugin/

Fixed in 64ee45d3c06d3c59ed7b46479243b44d59a7bd02 with on change event handler instead.

I'm having the same troubles with the materialize:materialize package. In Chrome autocomplete is messy with the input label and autocompleted text overlapping. There is no problem when the form template is loaded after a different template, but the problem shows up when the page is loaded directly in a new browser tab, or reloaded. (Once focused on the field, the label moves out of the way.) I used the standard Materialize markup for forms. Setting autocomplete="off" on the form or input tags didn't help.

I'm developing in Windows and my current package stack is:

Any suggestions?

_Also posted this in Meteor Forums_

you can also try running Materialize.updateTextFields()

Thanks for the quick response! I tried Materialize.updateTextFields() in various route hooks as well as in a script at the bottom of the template, but there was no improvement.

One further clue may be due to something special with the password field type. The autocompleted email field doesn't have any overlap, but the password text and label do. A few things I attempted:

  1. I changed the input type from password to text and that definitely stopped the behavior, but left the placeholder behind.
  2. I noticed that when I clicked anywhere on the page, the password label would scoot out of the way. So I tried $("body").click() and $("body").focus(), but no luck.
  3. I also used jQuery to focus on a different input, but that wouldn't animate the password label out of the way either.

Here's the markup:

<form class="col s12 m6">
  <h2>Login</h2>

  <div class="input-field">
    <input id="login_email" type="email" class="validate">
    <label for="login_email">Email</label>
  </div>

  <div class="input-field">
    <input id="login_password" type="password" class="validate">
    <label for="login_password">Password</label>
  </div>

</form>

same issue for me, but for all the fields.. not sure what is getting missed. Meteor and materilize platform

Same issue, materialize and ember-cli-materialize.

i had to take off all the placeholder text to make it work... may be try that

You can try also

$( '#myinput').on( 'input', function() {
  Materialize.updateTextFields();
} );

or see the pull request https://github.com/Dogfalo/materialize/pull/1936

@Digital-Thor I have the same problem with the autofilled password field. Materialize.updateTextFields(); doesn't seem to help. Were you able to solve it?

Hello there, what i did was to put. another password field on my form this
one was unused an hidden but by being there it prevented the browser from
autofilling the form at all.

Hope that helps.
El oct. 29, 2015 3:44 PM, "fabyeah" [email protected] escribió:

@Digital-Thor https://github.com/Digital-Thor I have the same problem
with the autofilled password field. Materialize.updateTextFields();
doesn't seem to help. Were you able to solve it?

—
Reply to this email directly or view it on GitHub
https://github.com/Dogfalo/materialize/issues/194#issuecomment-152314878
.

@orlax Thank you for your reply. The thing is, I WANT the browser to autofill the form. I don't want users to have to put in their login details every time they clear their browser data...?

@fabyeah: This worked for me:

Template.myTemplateName.onRendered (function(){
  Materialize.updateTextFields();
});

You also need to be careful about targeting the appropriate nesting level for the template.

Update: Ooops - Just tested it again, and password label is interfering with anonimization bullets from previous password. Label scoots out of the way once password field gets focus.

I see, i cant test a solution with the library right now but if I recall
correctly the forms respond when you click them and once you do it they all
look fine. You could try to fire the event directly by searching for it In
The materialize code or you could select the forms fields and "click" them
with JavaScript on document ready. I will get back to you if I get my
hands on the project I was working on them.

El jueves, 29 de octubre de 2015, fabyeah [email protected]
escribió:

@orlax https://github.com/orlax Thank you for your reply. The thing is,
I WANT the browser to autofill the form. I don't want users to have to put
in their login details every time they clear their browser data...?

—
Reply to this email directly or view it on GitHub
https://github.com/Dogfalo/materialize/issues/194#issuecomment-152332021
.

http://orlandoalmario.com/

Orlando Almario / Artista Multimedia
[email protected] / (57)3106819792

http://orlandoalmario.com

[image: Twitter] http://orlax22/[image: skype]
https://htmlsig.com/signatures/orlax22

Ok so the problem with the password field, is actually a Chromium 'bug', which prevents password scraping. Read about it in detail here:
https://code.google.com/p/chromium/issues/detail?id=352527

None of the solutions mentioned here work to fix the password field, except polling, because there is no callback / change event for the password field autofill. It's only shown as filled, but not actually filled, until the user interacts with the page (so scripts triggering clicks won't work either).

With polling, you'd check for $("#at-field-password:-webkit-autofill").length (which is still 0 on Meteor's template onRendered callback) and then add active class to the label $("#at-field-password:-webkit-autofill").prev().addClass("active") Use inside try... catch block, because non-webkit browsers can throw an error.

Why was this closed without being solved. Is it a wont-fix?

My solution for this is as follows:

$("input[name=login]").on("change.autofill", function () {
    $("[for=password]").addClass("active");
}).click(function() {
    $(this).unbind("change.autofill");
});

Browser autofill triggers change on username (or login) input, so we add active class to update password label. If user attempts to fill a field manually we unbind our event.

Sign-in forms are a thing. Autofill is a thing. My clients need both.
I've tried every approach listed above. No luck.
This bug alone makes the entire framework non-viable.

I keep slamming into things like this – seemingly small issues with no published solution whose issues get closed – and it drive me crazy. Everything else about Materialize is so gorgeous, I desperately want it to work.

EDIT: Took me 30 minutes, but I found a solution:

`<input id="password" type="password" name="password" value=" ">`

Adding a space to the value. Seriously. Which of course means I have to do $('#password').focus(function(){ $(this).select() }); so users without autofill submit valid passwords. But now the label doesn't crash the autofill party. _Sigh_.

My solution was to add a Placeholder attribute to input tag like this:

<input id="password" placeholder=" " name="password" type="password" class="validate">

hope this help

Adding my own solution to the pile-

I used vicman1200's approach and added a placeholder value on the input, but this resulted in the labels sliding up on page load instead of rendering in the upper position. Adding the active class on the label for each input prevented that.

<input placeholder=" " type="email" id="user_email">
<label class="active" for="user_email">Email</label>

This effectively kills the floating label transitions, but it works much better when dealing with fields that are commonly autofilled.

My solution was to fix it with good old css:

input:-webkit-autofill { +label { @extend .active; } } }

If you want to get rid the yellow background too, you can use this snippet (ultimate solution):

input:-webkit-autofill {
    &,
    &:hover,
    &:focus,
    &:active {
        -webkit-box-shadow: inset 0 0 0 500px white !important;
    }
    +label {
        font-size: 0.8rem;
        -webkit-transform: translateY(-140%);
        transform: translateY(-140%);
    }
}

If you do not want/cant rewrite scss, and/or you do like hardcoding 140% into css, we have solved this with this small and dirty piece of JS:

$(':input').one('input', function () {
    setTimeout($('input[type=password]:-webkit-autofill').siblings('label').addClass('active')}, 0);
});

And for the placeholder problem use:

input:placeholder-shown {
    +label {
        @extend .active;
    }
}

I have a similiar problem!
Angular 4 (react form) when setValue in a controlForm, label tag doesn't change class css to "active".

Strangely, when running Materialize.updateTextFields(); in console it works, but in code it does not

For those on AngularJs, you can bind the class 'active' by ng-class:

<label for="inputname" ng-class="{'active': formname.inputname.$viewValue}">InputLabel</label>

working... is parent div "md-input-container"

$(document).ready(function () {
setTimeout(function () {
var $pwdInput = $('input[type="password"]:-webkit-autofill');
$pwdInput.closest("md-input-container").addClass('md-input-has-value');
}, 500);
});

I did same as @abraaoz done

input:-webkit-autofill + label {
    font-size: 0.8rem !important;
    transform: translateY(-140%);
}
    var count = 0;
    var interval = setInterval(function () {
      count++;
      $('input[type=password]:-webkit-autofill').siblings('label').addClass('active');
      if (count > 500) {
        clearInterval(interval);
      }
    }, 10);

checking input for autofill for 5 seconds.

Tried by adding default value one's autofill event raised.

$("input[name=UserName]").on("change.autofill", function () {
$('#password').val('check');
})

This is working for me :)

Another possible solution based on this answer:

$.fn.onAutoFill = function(callback) {
    var me = this;
    var last = "";
    var infunc = function() {
        var text = $(me).val();
        if(text != last) {
            last = text;
            callback(me);
        }
        setTimeout(infunc, 100);
    }
    setTimeout(infunc, 100);
};

$('input').onAutoFill(function(input) {
    $(input).siblings('label').addClass('active');
});

Here is my solution, and it does the trick :

/* to get ride of the yellow color in chrome*/
input[type]:-webkit-autofill,
input[type]:-webkit-autofill:hover,
input[type]:-webkit-autofill:focus,
input[type]:-webkit-autofill:active {
    transition: background-color 5500s ease-in-out 0s;
    -webkit-box-shadow: inset 0 0 0 500px transparent;
}

/* Materialize fix labels overlapping */
input[type]:-webkit-autofill + label{
    -webkit-transform: translateY(-140%);
    transform: translateY(-140%);
}

/* fix clicking label does not activate text input */
.input-field label {
    pointer-events: all;
}

@pmaclot I added a fix for the overlapping problem here: 573e754a822c1cbf963f50d5ae6c0a249787b607

We aren't removing the yellow color since that is a helpful cue to the user that the autofill took place.

simple solution just autofucus to the element
eg




`

$('.input-field input').each(function () {
if (this.value.length > 0) {
$('label[for=' + this.id + ']').addClass('active');
}
});

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexknipfer picture alexknipfer  Â·  3Comments

ruslandzhumaev picture ruslandzhumaev  Â·  3Comments

locomain picture locomain  Â·  3Comments

serkandurusoy picture serkandurusoy  Â·  3Comments

samybob1 picture samybob1  Â·  3Comments