Many browsers support autocomplete but do not trigger “change” events on inputs when the user initiates autocomplete. This is a problem for many libraries and code in the wild that rely on performing some action (e.g. input validation) when input data change.
With respect to AngularJS forms, the problem becomes obvious if you are using AngularJS form validation. If you autofill an empty form then press Submit, AngularJS will think the inputs are still empty:

Here is a simple login form subject to this issue:
1 2 3 4 5 6 7 |
<form ng-submit="submitLoginForm()"> <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> |
Unfortunately the underlying issue of not having an appropriate event related to autofill must be addressed by browser vendors. However in the meantime, we can use a custom directive to ensure AngularJS knows about form changes made by autofill at time of form submit.
Patch directive
In CoffeeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 |
myApp.directive 'formAutofillFix', -> (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 autofilled inputs if attrs.ngSubmit setTimeout -> elem.unbind('submit').submit (e) -> e.preventDefault() elem.find('input, textarea, select').trigger('input').trigger('change').trigger 'keydown' scope.$apply attrs.ngSubmit , 0 |
In JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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 autofilled 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); } }; }); |
Directive in use
The directive is simple to use; just apply it to your form and away you go:
1 2 3 4 5 6 7 |
<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> |
14 replies on “Fixing autocomplete (autofill) on AngularJS form submit”
Hello,
I was having issues with this solution : Every two or three refresh of my chrome browser i had the error “Object [object Object] has no method ‘submit'”
I replaced this :
elem.unbind(‘submit’).submit(function(e) {
with this :
elem.unbind(‘submit’).bind(‘submit’, function(e) {
and it seems to work.
Hope that helps anyone who run into the same problem 😉
That’s strange; possible jQuery bug or jQuery version < 1.0. Thanks for the heads up!
Correct, that works. I prefer Firefox, have no problem.
Thx for this piece of code.
I’ve also needed to switch from .submit to bind(‘submit’)
I also needed to reduce arguments in find function to ‘input’ only.
In jqlite (if you aren’t using jquery) this changes things a little:
elem.find(‘input’).triggerHandler(‘change’)
Indeed, thank you!
Worked like a charm – thanks.
Thanks. Works better than tbosch’s autofill-event plugin.
Using Firefox 30.0
had to add event ‘.trigger(‘blur’)’ to make it work, else the form was getting submitted empty, and then the model was getting filled. Don’t know the exact reason why…
Thanks for your report. There is ongoing discussion about this problem and several other solutions offered here: https://github.com/angular/angular.js/issues/1460
for which element we have to add event trigger(‘blur’) ??
Presumably for all form elems (i.e. line 11 of the JavaScript above,
elem.find('input, textarea, select')
).Hi!
Thanks for good solution.
For me it works with native $timeout;
Try to use ng-required=”true”
instead
ng-required
Its work for me