Closed lamoni closed 9 years ago
Have you enabled the autofill option?
@FezVrasta How can I try that?
$.material.options.autofill = true
Before you run the init script
@FezVrasta still the same result
It's weird, I never had problems with autofill
enabled... Maybe you could provide a live demo on codpen or similar.
Yeah it's odd. The floating-label "activates" correctly if I click anywhere on the screen, but not until then. The floating-label and activation of it work just fine on text inputs
$.material.options.autofill = true; $.material.init(); using this floating label overlap problem sloves.
@PratibhaP this is exactly what I have suggested to @lamoni, please @lamoni may you doublecheck?
Yeah, Its working properly, @lamoni .
Using the same html as listed in my original comment, and using the following, it is NOT working.
<script>
$(document).ready(function() {
$.material.options.autofill = true;
$.material.init();
});
</script>
[IMAGE REDACTED FOR PRIVACY REASONS - PLEASE SEE BELOW COMMENT FOR VIDEO CAPTURE OF THE ISSUE]
I should note that this is in Chrome, where its auto-fill behavior puts the credentials into the text-box automatically (on Safari, you have to select the credentials from the dropbox, which indirectly fires the events, and it works as expected). This seems to be a problem with Bootstrap Material not detecting that there is input in the password box.
Also, if you're testing this in something like CodePen, you are polluting the test since, assumedly, events are being fired when it compiles / is drawn. This issue happens when the following requirements are met:
I've decided to grab a screen cap of this in action.
[REMOVED VIDEO LINK FOR PRIVACY REASONS]
Every test I did ended up correctly, if you can provide a working demo I can study it.
I have tested autofill of password in chrome and firefox also. Its working.
@PratibhaP The screenshot and video screen capture say otherwise, but I digress.
@FezVrasta If this helps at all, here is the full form (maybe it's the existence of a checkbox or something causing this to break, and thus your tests aren't failing).
<form class="form" role="form" method="POST" action="{{ url('/auth/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<input type="email" class="form-control floating-label" placeholder="Email" name="email" value="{{ old('email') }}">
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<input type="password" class="form-control floating-label input-lg" name="password" placeholder="Password" value="">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-8 col-md-offset-2 text-right">
<button type="submit" class="btn btn-primary btn-lg">Login</button>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-6 col-md-offset-2 text-left">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
<div class="col-md-2 text-right">
<a class="btn btn-sm text-danger" href="{{ url('/password/email') }}" >Forgot</a>
</div>
</div>
</div>
</form>
And the javascript:
<script>
$(document).ready(function() {
$.material.options.autofill = true;
$.material.init();
});
</script>
this is my firefox browser screenshot. Its working properly.
@PratibhaP I'm not doubting it's working correctly for you. I'm doubting it's working correctly in every situation, which is obvious from my video capture. Also, your screencap shows the cursor in the text box, meaning you activated an event, meaning of course it will show the floating-label where it needs to be. My whole premise is based on the fact that if you actually have the credentials saved, refresh the page and DON'T touch anything, then the auto-fill doesn't activate properly.
you are using "input-lg" class. what property it has?
@lamoni I've not time to prepare a working demo, if you can provide me one (codepen, live website etc) then I can investigate
@lamoni : without activating input event, still its coming. I have tested it on firefox and chrome. Don't know about safari and opera.
I should note that I've tried this in Firefox and it works fine (Safari is a moot point since they don't auto-fill, apparently. You have to actually select your credentials from a drop-down box, which will, of course, fire an event), it seems to just be Google Chrome. @PratibhaP I've tried removing it, and it made no difference in the behavior.
@FezVrasta [REMOVED COMMENT TEXT FOR PRIVACY REASONS]
In dom "empty" class attached to password field thats why its not working. In dom removed empty class from input, then its working.
@PratibhaP Thanks for quick feedback. Is there anything I should be doing to avoid that, or does this need to be handled/fixed within bootstrap-material?
the empty
class is added by BS Material when it detects the field is empty, it should just remove it once autofill adds some value to it...
But In my case empty class is not added to password field or in any input field.
Probably there's something different in this case. Maybe Angular is doing something weird. I have to check once @lamoni enables my beta account.
@lamoni : You have to remove that empty class for resolving this issue. @FezVrasta : how do we resloved it, because I checked it, The field is not empty. There is value in password field.
@FezVrasta : I am AngularJS framework but its working properly. No issues with angular, i think so.
@FezVrasta It's actually Laravel's Blade templating engine, but that page is doing very minimal Blade (only filling the values for the text areas), and I think that it is irrelevant since it doesn't touch anything client-side. Blade is only "active" on the server where it generates the HTML.
Example of the actual source code:
<form class="form" role="form" method="POST" action="{{ url('/auth/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<input type="email" class="form-control floating-label" placeholder="Email" name="email" value="{{ old('email') }}">
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<input type="password" class="form-control floating-label" name="password" placeholder="Password" value="">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-8 col-md-offset-2 text-right">
<button type="submit" class="btn btn-primary btn-lg">Login</button>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-6 col-md-offset-2 text-left">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
<div class="col-md-2 text-right">
<a class="btn btn-sm text-danger" href="{{ url('/password/email') }}" >Forgot</a>
</div>
</div>
</div>
</form>
Writing $.material.options.autofill
it returns false
.
Seems like you have not that option enabled, maybe you are enabling it in some different page..
@FezVrasta if you check the source of that login page, I have:
<script>
$(document).ready(function() {
$.material.options.autofill = true;
$.material.init();
});
</script>
Can you confirm that is the correct way to set that?
Its correct way to enable to autofill.
It appears to be an issue with the way Google Chrome handles auto-filling password fields and how bootstrap-material relies on checking for an empty field to remove the empty class.
If you refresh the login page, and then on console run: console.log(document.getElementsByName("password")[0].value)
You'll see there is no value (which the autofill section of bootstrap-material relies on checking... it is empty, despite Google Chrome showing the * characters in the text box). Once you fire an event, run that console.log command again and you'll see it has a value. So it looks like Chrome doesn't actually fill the value in the DOM until an event has been fired, thus bootstrap-material won't remove the empty class
No, the problem is that you have not enabled $.material.options.autofill = true;
.
I've added a breakpoint before the document.ready
event and enabled it manually and this is the result:
@FezVrasta Did you look at the source code?! I am doing exactly that.
@FezVrasta Even changing autofill to "true" in materials.js doesn't fix it. Unbelievable that this is going to be closed despite being an obvious bug.
After setting "autofill" to true in material.js AND confirming that it is true from console after doing so:
I don't know what are you doing wrong in your source code. I've just enabled the correct option of my framework and everything works correctly. I'm not paid to fix problems with the source code of other peoples (well, I'm not paid at all...)
I would doublecheck your source code to understand why it happens.
I'm not expecting you to fix this alone, I've been more than willing to dedicate time to helping because I like your framework, but to close an issue despite obvious evidence that there is an issue is just scary. It's not a "problem with the source code of others".
@lamoni : remove that value="" from password field and try it again.
@PratibhaP Removed the value="" for the password input, but still seeing same results.
I could even keep it open, but I fixed it locally editing your code so I wonder why I should..
@lamoni then i have to take a look into it.
@FezVrasta I've even changed autofill to true in material.js. Take a look at the page again and see for yourself that despite being hard-coded to true in your code, that it does NOT work.
I put this together for you to test on: [REDACTED]
I have stripped out ANYTHING that is not bootstrap-material-design related, to further prove my point that it's not "the source code of others" causing this issue.
The only included Javascript libraries are the boostrap-material-design dependencies (jquery 2.1.3, bootstrap 3.3.1, ripples.js, and material.js). The only other javascript code is the $(document).ready() which is assigning autofill to true AND init()'ing material. I believe this is probably an issue with the following code due to Chrome not actually filling in the password box (or firing an event) until an event has been fired for a different element (until then, it "fakes" the asterisks):
.on("keyup change", ".form-control", function() {
var $this = $(this);
if ($this.val() === "" && (typeof $this[0].checkValidity != "undefined" && $this[0].checkValidity())) {
$this.addClass("empty");
} else {
$this.removeClass("empty");
}
To further stomp this into the ground, here's a Google Chrome bug report stating this very behavior:
I am experiencing the same issue. After a lot of reading and research, I've found the problem, and a fix!
The problem happens because password fields in chrome are not really auto-filled until the user interacts with the page, in order to avoid security risks in password harvesting. To make it harder, it is auto filled if you hit F5 (because it means the user is on that page), but not if the page was loaded in any other way (programatically or by typing the URL).
This is why `$.material.options.autofill' does not do anything - because you can't identify this is the case,
Luckily, after a lot of pressure, someone in the chrome team added a css selector to identify auto-filled fields in chrome.
So the fix is quite simple, just add a special handling for chrome in the material css
.form-control-wrapper .form-control:focus ~ .floating-label,
.form-control-wrapper .form-control:not(.empty) ~ .floating-label,
.form-control-wrapper .form-control:-webkit-autofill ~ .floating-label {
top: -10px;
font-size: 10px;
opacity: 1;
}
A PR would be very welcome
This issue is not resolved in 0.4.0. It needs the -webkit-autofill selector change.
When using the following input code, floating labels aren't triggering on auto-fill for the Password inputs (they're working fine for text inputs):
Screenshot: