I have a simple login form which works just peachy unless you use Chrome\'s auto complete feature.
If you start typing and use the auto complete feature and it auto
Old question, but whatever
I came across the same problem and I've got a small "hack" solution. This problem happened at many different places in my app, so I created a directive for reusability.
module.directive("fakeAutocomplete", [
function () {
return {
restrict: "EA",
replace: true,
template: "<div><input/><input type=\"password\"/></div>",
link: function (scope, elem, attrs) {
elem.css({
"overflow": "hidden",
"width": "0px",
"height": "0px"
});
}
}
}
]);
And simply add
<fake-autocomplete></fake-autocomplete>
At the beginning of your form and the browser will detect the fake fields as the ones that should autocomplete. Simply putting display:none
on the fields also does not seem to work anymore, I've tested it.
It could be much simpler solution to the problem.
```
angular.module('someModule').directive('chromeAutofillHack', function()
{
return {
require: '^ngModel',
restrict: 'A',
priority: 500, // set higher priority then other custom directives
link: function(scope, element, attrs , ngModelCtrl)
{
ngModelCtrl.$parsers.unshift(function(email)
{
if (!email) { // only do this when angular think there is no value
email = $(element).val();
ngModel.$setViewValue(email);
}
return email;
});
}
};
});
```
From: Developer.mozilla.org docs Turning_off_form_autocompletion
If an author would like to prevent the auto-filling of password fields in user management pages where a user can specify a new password for someone other than themselves, autocomplete="new-password" should be specified, though support for this has not been implemented in all browsers yet.
So, what makes it work for me:
I hope that it works for you too :)
My solution for Chrome 35.0, Firefox 30.0, angular 1.2.18 (login page with password manager, autofill, angular method and redirect):
How does browser know when to prompt user to save password?
Below directive worked for me. It's simple and clean fix. Hope that helps!
Ref: AngularJS browser autofill workaround by using a directive
Here is a solution that is far less hacky than other solutions presented and is semantically sound AngularJS: VictorBlog.com
myApp.directive('formAutofillFix', function() {
return function(scope, elem, attrs) {
// Fixes Chrome bug: https://groups.google.com/forum/#!topic/angular/6NlucSskQjY
elem.prop('method', 'POST');
// Fix autofill issues where Angular doesn't know about auto-filled inputs
if(attrs.ngSubmit) {
setTimeout(function() {
elem.unbind('submit').submit(function(e) {
e.preventDefault();
elem.find('input, textarea, select').trigger('input').trigger('change').trigger('keydown');
scope.$apply(attrs.ngSubmit);
});
}, 0);
}
};
});
Then you simply attach the directive to your form:
<form ng-submit="submitLoginForm()" form-autofill-fix>
<div>
<input type="email" ng-model="email" ng-required />
<input type="password" ng-model="password" ng-required />
<button type="submit">Log In</button>
</div>
</form>
I ended up with a different solution that I don't see here yet. From what I found, the password value isn't exposed to the model (or possibly even the js api) until the user interacts with the page. Clicking the login button is enough interaction to make the value available, and the data binding will succeed early enough for the click handler on the button to access the password from the model. So if I could detect that the browser has auto-filled, I could enable the login button even though my model hadn't been updated yet. So I wrote a simple helper service to see if Chrome has auto-filled any inputs:
utilApp.service('autoFillDetectionService', [function () {
return {
hasAutoFillInputs: function () {
try{
return !!$(':-webkit-autofill').length;
}
catch (x) {
// IE gets here, it/jquery complains about an invalid pseudo-class
return false;
}
}
};
}]);
From the login controller, I have an interval checking if any input fields are marked as autofill and if so enable the login button.