111

When submitting a form in AngularJS and use the browser remember password functionality, and in a subsequent login attempt you let the browser fill in the login form with the username and password, the $scope model won't be changed based on the autofill.

The only dirty hack I found is to use the following directive:

app.directive("xsInputSync", ["$timeout" , function($timeout) {
    return {
        restrict : "A",
        require: "?ngModel",
        link : function(scope, element, attrs, ngModel) {
            $timeout(function() {
                if (ngModel.$viewValue && ngModel.$viewValue !== element.val()) {
                    scope.apply(function() {
                        ngModel.$setViewValue(element.val());
                    });
                }
                console.log(scope);
                console.log(ngModel.$name);
                console.log(scope[ngModel.$name]);
            }, 3000);
        }
    };
}]);

The problem is that the ngModel.$setViewValue(element.val()); doesn't change the model nor the view based on the element.val() returned value. How can I accomplish that?

lucassp
  • 4,133
  • 3
  • 27
  • 36
  • This code looks okay at first blush... but where is the rest (markup, etc)? Do you have a fiddle or plunk we can see? – Ben Lesh Feb 19 '13 at 19:50
  • Here's the plunk: http://plnkr.co/edit/CHrBAVU9Ycl2ex2DRr6R I'm not sure if it works directly on plunker because it runs in an iframe. – lucassp Feb 19 '13 at 19:57
  • 1
    You don't need to scope.$apply inside angular's $timeout. You might need it inside native window.setTimeout. But it's a better idea to use angular's one. – gorpacrate Nov 22 '13 at 16:42
  • 1
    There is an **"official" polyfill fix** from Angular dev **tbosch** for this problem. Please see details in answer http://stackoverflow.com/a/25687396/3009639 below. – orszaczky Sep 05 '14 at 15:16
  • Unfortunately the "official" fix is abandonware and doesn't work in many browsers. Issues have been filed but are not addressed so the search continues... – cyberwombat Jun 12 '16 at 18:15

23 Answers23

45

Apparently this is a known issue with Angular and is currently open

I'm not sure what you could do here besides some sort of work around like you're trying. It seems you're on the right track. I couldn't get my browser to try to remember a password for your plunk, so I'm not sure if this will work but have a look:

app.directive('autoFillSync', function($timeout) {
   return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModel) {
          var origVal = elem.val();
          $timeout(function () {
              var newVal = elem.val();
              if(ngModel.$pristine && origVal !== newVal) {
                  ngModel.$setViewValue(newVal);
              }
          }, 500);
      }
   }
});
<form name="myForm" ng-submit="login()">
   <label for="username">Username</label>
   <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>
   <label for="password">Password</label>
   <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>
   <button type="submit">Login</button>
</form>

I think you just need to simplify your approach a bit. The one thing I definitely recommend is to check ngModel.$pristine and make sure you're not overwriting some poor user's input. Also, 3 seconds is probably too long. You shouldn't have to call $apply() in a $timeout, BTW, it should queue a $digest for you automatically.

The real catch: Will your browser beat Angular to execution? What about my browser?

This is probably an unwinnable war, which is why Angular (or Knockout) hasn't been able to solve it readily. There's no guarantee of the state of the data in your input at the time of the directive's initial execution. Not even at the time of Angular's initialization.... So it's a tricky problem to solve.

Elia Weiss
  • 8,324
  • 13
  • 70
  • 110
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • 1
    Good point about $pristine. Well, 3 seconds is there just for testing purposes. The "Save Password" dialog seems to work on Safari. That's another issue which I have to investigate. – lucassp Feb 19 '13 at 20:28
  • Just fool him with local storage. :) ... I'll keep thinking about it. But I have my doubts about the feasability of making autofill work with any two-way bindings. – Ben Lesh Feb 19 '13 at 20:32
  • Yes, but I still need to be able to update the model from a directive for it to work. – lucassp Feb 19 '13 at 20:37
  • 1
    I was kidding about localStorage, you wouldn't want to keep passwords there. – Ben Lesh Feb 19 '13 at 20:46
  • What about putting a hidden form on the page? something with `width:0; height:0; overflow: hidden`... then setting up a timeout to pull the value from it and use that to update your form you're using in Angular... it would be a complete and total hack, of course. – Ben Lesh Feb 19 '13 at 20:47
  • I've added a method in the scope which updates the model properties and I'm calling it from the directive based on the conditions you mentioned in your answer...and it works. Now, I hope I didn't level up in my dirtiness skill :) – lucassp Feb 19 '13 at 20:58
  • If it works it works... $setViewValue should have worked though... and it executes all of your validation, etc. ... But that's probably not necessary in this case. – Ben Lesh Feb 19 '13 at 21:04
  • If you find a way to make $setViewValue work inside the $timeout, please let me know. I can't see a reason why it shouldn't work. – lucassp Feb 19 '13 at 21:12
  • Model doesn't updates :) I found even more dirty but... working solution. I'll post it as another answer - maybe will be useful for somebody. – OZ_ May 28 '13 at 20:31
  • Does anyone realize this code does not work with one of the major browser ? – Gabriel Oct 31 '13 at 14:45
  • Yes. I'm sure that it doesn't work in some browsers, or worse, some circumstances. This is a classic race-condition type issue made horrible by the fact that one of the racers is completely out of the developer's control. This is a really tricky problem to solve. – Ben Lesh Nov 03 '13 at 15:40
  • I guess you want `ngModel` in your link function as well? (`link: function(scope, elem, attrs, ngModel)`) – swenedo Dec 06 '13 at 14:59
  • Shouldn't it be ngModel.$setViewValue(origVal); ? – Van Nguyen Apr 25 '14 at 00:43
  • Confirmed this doesn't work in Firefox 31. The `&& origVal !== newVal` test fails. – tester Aug 15 '14 at 00:43
  • 1
    This won't work with Safari and the credit card autofill, as this autofill is triggered at any time by the user – Dallas Clark Oct 08 '14 at 03:29
  • Is it the best solution for Angular2 as well? It seems that when the user chooses a Chrome's suggestion to fill the form, the model doesn't pick up changes. – Alex Klaus Sep 28 '16 at 04:03
  • This breaks the expected functionality of **ngTrim**, so users who put spaces on their username will not benefit from ngTrim to remove those spaces. I added `if ('password' != attrs.name){ newVal = ('string' == typeof newVal) ? newVal.trim() : newVal; }` – steampowered Apr 19 '19 at 17:35
35

You don't have to use a $timeout or anything like this. You can use an event system.

I think it's more Angularish and does not depend on jQuery or custom event catching.

For example on your submit handler:

$scope.doLogin = function() {
    $scope.$broadcast("autofill:update");

    // Continue with the login.....
};

And then you can have an autofill directive like this:

.directive("autofill", function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModel) {
            scope.$on("autofill:update", function() {
                ngModel.$setViewValue(element.val());
            });
        }
    }
});

Finally, your HTML will be like:

<input type="text" name="username" ng-model="user.id" autofill="autofill"/>
Richard
  • 1,117
  • 11
  • 31
bekos
  • 1,303
  • 1
  • 13
  • 11
  • 14
    In my case submit button is disabled while inputs are empty. – gorpacrate Nov 22 '13 at 16:04
  • 4
    don't you ever have trouble with this as it is async? where the login call to the server already leaves before the event was replicated and the directive had time to update the scope? – Sander Jan 13 '14 at 10:17
35

Here is a solution that is far less hacky than other solutions presented and is semantically sound AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/

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);
    }
  };
});

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>
Richard
  • 1,117
  • 11
  • 31
Ezekiel Victor
  • 3,877
  • 1
  • 27
  • 28
12

No need to hack anymore! Angular dev tbosch made a polyfill that triggers a change event when the browser changes form fields without triggering a change event:

https://github.com/tbosch/autofill-event

For now they won't build this into the Angular code, as this is a bugfix for the browser, and also works without Angular (e.g. for plain jQuery apps).

"The polyfill will check for changes on document load and also when an input is left (only in the same form). However, you can trigger the check manually if you want to.

The project has unit tests as well as semi automatic tests, so we finally have a place to collect all the different use case together with the required browser settings.

Please note: This polyfill works with plain AngularJS apps, with AngularJS/jQuery apps but also with plain jQuery apps that do not use Angular."

It can be installed with:

bower install autofill-event --save

Add the script autofill-event.js after jQuery or Angular in your page.

This will do the following:

  • after DOMContentLoaded: check all input fields
  • a field is left: check all other fields in the same form

API (to manually trigger the check):

  • $el.checkAndTriggerAutoFillEvent(): Execute the check for all DOM elements in the given jQuery / jQLite element.

How it works

  1. Remember all changes to input elements by the user (listening for change events) and also by JavaScript (by intercepting $el.val() for jQuery / jQLite elements). That changed value is stored on the element in a private property.

  2. Checking an element for auto fill: Compare the current value of the element with the remembered value. If it's different, trigger a change event.

Dependencies

AngularJS or jQuery (works with either one or both)

More info and source on the github page.

Original Angular Issue #1460 on Github can be read here.

orszaczky
  • 13,301
  • 8
  • 47
  • 54
  • 2
    This does not work for my cases. checkAndTriggerAutoFillEvent() is triggered and generates events, but AngularJS never updates its models and thinks that the fields are empty. – Splaktar Oct 23 '14 at 18:17
  • I haven't had any problems using this polyill. If you can't get it to work properly, you should create a separate question including some code. If you find a bug, you should check the tickets on github, or open a new one. – orszaczky Oct 24 '14 at 15:43
  • Yep, I think that it is related to this bug: https://github.com/tbosch/autofill-event/issues/11 – Splaktar Oct 24 '14 at 17:34
  • 1
    `ngModelOptions` combined with `autofill-event` means you can now specify `change` as one of the `updateOn` events to make sure your model is correctly synced. – morloch Oct 07 '15 at 11:47
10

Dirty code, check if issue https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 is fixed before using this code. This directive triggers events when field is filled, not only before submit (it's necessary if you have to handle input before submit)

 .directive('autoFillableField', function() {
    return {
                   restrict: "A",
                   require: "?ngModel",
                   link: function(scope, element, attrs, ngModel) {
                       setInterval(function() {
                           var prev_val = '';
                           if (!angular.isUndefined(attrs.xAutoFillPrevVal)) {
                               prev_val = attrs.xAutoFillPrevVal;
                           }
                           if (element.val()!=prev_val) {
                               if (!angular.isUndefined(ngModel)) {
                                   if (!(element.val()=='' && ngModel.$pristine)) {
                                       attrs.xAutoFillPrevVal = element.val();
                                       scope.$apply(function() {
                                           ngModel.$setViewValue(element.val());
                                       });
                                   }
                               }
                               else {
                                   element.trigger('input');
                                   element.trigger('change');
                                   element.trigger('keyup');
                                   attrs.xAutoFillPrevVal = element.val();
                               }
                           }
                       }, 300);
                   }
               };
});
OZ_
  • 12,492
  • 7
  • 50
  • 68
5

Seems like clear straight ahead solution. No jQuery needed.

UPDATE:

  • Model is updated only when model value isn't equal to actual input value.
  • Checking doesn't stop on first autofill. In case if you wish to use another account for example.

app.directive('autofillable', ['$timeout', function ($timeout) {
    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            scope.check = function(){
                var val = elem[0].value;
                if(ctrl.$viewValue !== val){
                    ctrl.$setViewValue(val)
                }
                $timeout(scope.check, 300);
            };
            scope.check();
        }
    }
}]);
gorpacrate
  • 5,109
  • 3
  • 21
  • 18
  • 4
    +1 good solution, similar to what I came up with. The only addition I would suggest is to first check if the model is `$pristine` before changing it, and then after changing it keep it's `$pristine` state. Otherwise you'll find that if a form is loaded with no autofill data, the above directive will still update the model and subsequently make it `dirty` even though the form control should be still considered untouched. example here, using your directive. I've commented out the code I would add to it: http://jsfiddle.net/OACDesigns/L8Sja/4/ – OACDesigns Dec 16 '13 at 17:24
  • 1
    also, I think `scope:true` should be `scope:{}` – OACDesigns Dec 16 '13 at 17:31
4

Well, the easiest way it's to emulate the browser's behavior, so if there is a problem with the change event, just fire it yourself. Much simpler.

Directive:

yourModule.directive('triggerChange', function($sniffer) {
    return {
        link : function(scope, elem, attrs) {
            elem.on('click', function(){
                $(attrs.triggerChange).trigger(
                    $sniffer.hasEvent('input') ? 'input' : 'change'
                );
            });
        },
        priority : 1
    }
});

HTML:

<form >
    <input data-ng-model="user.nome" type="text" id="username">

    <input data-ng-model="user.senha" type="password" id="password" >

    <input type="submit" data-ng-click="login.connect()" id="btnlogin" 
           data-trigger-change="#password,#username"/>
</form>

You can do some variations, like putting the directive on the form and firing the event on all inputs with the .dirty class on form submit.

isherwood
  • 58,414
  • 16
  • 114
  • 157
pedroassis
  • 177
  • 1
  • 8
4

Solution 1 [Using $timeout]:

Directive:

app.directive('autoFillSync', function($timeout) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, model) {
          var origVal = elem.val();
          $timeout(function () {
              var newVal = elem.val();
              if(model.$pristine && origVal !== newVal) {
                  model.$setViewValue(newVal);
              }
          }, 500);
      }
    };
});

HTML:

<form name="myForm" ng-submit="login()">
  <label for="username">Username</label>
  <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>
  <label for="password">Password</label>
  <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>
  <button type="submit">Login</button>
</form>

Solution 2 [Using angular events]:

Ref: Becko's answer

Directive:

app.directive("autofill", function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModel) {
            scope.$on("autofill:update", function() {
                ngModel.$setViewValue(element.val());
            });
        }
    };
});

HTML:

<form name="myForm" ng-submit="login()">
  <label for="username">Username</label>
  <input type="text" id="username" name="username" ng-model="username" autofill/><br/>
  <label for="password">Password</label>
  <input type="password" id="password" name="password" ng-model="password" autofill/><br/>
  <button type="submit">Login</button>
</form>

Solution 3 [Using relay method calls]:

Directive:

app.directive('autoFill', function() {
    return {
        restrict: 'A',
        link: function(scope,element) {
            scope.submit = function(){
                scope.username = element.find("#username").val();
                scope.password = element.find("#password").val();
                scope.login();//call a login method in your controller or write the code here itself
            }

        }
    };
});

HTML:

<form name="myForm" auto-fill ng-submit="submit()">
   <label for="username">Username</label>
   <input type="text" id="username" name="username" ng-model="username" />
   <label for="password">Password</label>
   <input type="password" id="password" name="password" ng-model="password" />
   <button type="submit">Login</button>
</form>
Community
  • 1
  • 1
Robin Rizvi
  • 5,113
  • 4
  • 27
  • 35
  • 2
    Solution 1 worked very well for a time, but now on angularjs 1.4.9 it doesn't work anymore. Checking `model.$valid` in directive returns true both before and after `$setViewValue`, but the element is still with `ng-invalid` class – Jānis Feb 10 '16 at 11:13
3

This is jQuery way :

$(window).load(function() {
   // updates autofilled fields
   window.setTimeout(function() {
     $('input[ng-model]').trigger('input');
   }, 100);
 });

This is Angular way :

 app.directive('autofill', ['$timeout', function ($timeout) {
    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            $timeout(function(){
                $(elem[0]).trigger('input');
                // elem.trigger('input'); try this if above don't work
            }, 200)
        }
    }
}]);

HTML

<input type="number" autofill /> 
Frizi
  • 2,900
  • 1
  • 19
  • 25
Nishchit
  • 18,284
  • 12
  • 54
  • 81
1

Here's another workaround that's less hacky, but requires some extra code in the controller.

HTML:

<form ng-submit="submitForm()" ng-controller="FormController">
    <input type="text" ng-model="username" autocomplete-username>
    <input type="submit">
</form>

Directive (CoffeeScript):

directives.directive 'autocompleteUsername', ->
    return (scope, element) ->
        scope.getUsername = ->
            element.val()

Controller:

controllers.controller 'FormController', [->
    $scope.submitForm = ->
        username = $scope.getUsername?() ? $scope.username
        # HTTP stuff...
]
jab
  • 4,053
  • 3
  • 33
  • 40
  • You have this in vanilla JavaScript? – f1lt3r Nov 30 '15 at 19:13
  • CoffeeScript.org provides a translator: [done here](http://coffeescript.org/#try:directives.directive%20'autocompleteUsername'%2C%20-%3E%0A%20%20%20%20return%20(scope%2C%20element)%20-%3E%0A%20%20%20%20%20%20%20%20scope.getUsername%20%3D%20-%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20element.val()%0A%0A%0A%0A%0Acontrollers.controller%20'FormController'%2C%20%5B-%3E%0A%20%20%20%20%24scope.submitForm%20%3D%20-%3E%0A%20%20%20%20%20%20%20%20username%20%3D%20%24scope.getUsername%3F()%20%3F%20%24scope.username%0A%20%20%20%20%20%20%20%20%23%20HTTP%20stuff...%0A%5D) – jab Dec 04 '15 at 22:48
1

One-liner workaround in the submit handler (requires jQuery):

if (!$scope.model) $scope.model = $('#input_field').val();
isherwood
  • 58,414
  • 16
  • 114
  • 157
archpollux
  • 77
  • 2
1

This is the only solution I've found that allowed all of my Angular' validations to work as designed including disable/enable of submit button. Installs with bower and 1 script tag. Bazinga!

https://github.com/tbosch/autofill-event

Roland Hordos
  • 11
  • 1
  • 1
  • 1
    this poly fill doesn't fit with a submit button/input binding to the form state. unless you click on the page any point you want to trigger a digest (it seems the action trigger the browser to do some real filling), then the button become enable.[Test page with manual tests](http://e-cloud.github.io/autofill-event/) – e-cloud Mar 12 '15 at 09:33
1

Changing the model value, instead of using a timeout function worked for me.

Here is my code:

module.directive('autoFill', [ function() {
    return {
        require: 'ngModel',
        link:function(scope, element, attr, ngModel) {
            var origVal = element.val();
            if(origVal){
                ngModel.$modelValue = ngModel.$modelValue || origVal;
            }
        }
    };
}]);
Wyetro
  • 8,439
  • 9
  • 46
  • 64
0

I force a $setValue(val()) on submit: (this works without jQuery)

   var ValidSubmit = ['$parse', function ($parse) {
    return {
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                post: function postLink(scope, element, iAttrs, controller) {
                    var form = element.controller('form');
                    form.$submitted = false;
                    var fn = $parse(iAttrs.validSubmit);
                    element.on('submit', function(event) {
                        scope.$apply(function() {
                            var inputs = element.find('input');
                            for(var i=0; i < inputs.length; i++) {
                                var ele = inputs.eq(i);
                                var field = form[inputs[i].name];
                                field.$setViewValue(ele.val());
                            }
                            element.addClass('ng-submitted');
                            form.$submitted = true;
                            if(form.$valid) {
                                fn(scope, {$event:event});
                            }
                        });
                    });
                    scope.$watch(function() { return form.$valid}, function(isValid) {
                        if(form.$submitted == false) return;
                        if(isValid) {
                            element.removeClass('has-error').addClass('has-success');
                        } else {
                            element.removeClass('has-success');
                            element.addClass('has-error');
                        }
                    });
                }
            }
        }
    }
}]
app.directive('validSubmit', ValidSubmit);
malix
  • 3,566
  • 1
  • 31
  • 41
0

I am very new to Angularjs, but I found a simple solution to that problem=> Force Angular to reevaluate expression... by changing it! (of course you need to remember the initial value to revert to initial state) Here is the way it goes in your controller function for submitting the form:

    $scope.submit = function () {
                var oldpassword = $scope.password;
                $scope.password = '';
                $scope.password = oldpassword;
//rest of your code of the submit function goes here...

where of course, the value entered in your password input has been set by windows and not by user.

Le neveu
  • 1
  • 1
0

You can try this code :

yourapp.directive('autofill',function () {

    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            var origVal = elem.val();
            if (origVal != '') {
                elem.trigger('input');
            }
        }
    }
});
Andros
  • 4,069
  • 1
  • 22
  • 30
Rohit
  • 1
  • 1
0

A minor modification to this answer (https://stackoverflow.com/a/14966711/3443828): use an $interval instead of a $timeout so you don't have to race the browser.

mod.directive('autoFillSync', function($interval) {
    function link(scope, element, attrs, ngModel) {
        var origVal = element.val();
        var refresh = $interval(function() {
          if (!ngModel.$pristine) {
            $interval.cancel(refresh);
          }else{
            var newVal = element.val();
            if (origVal !== newVal) {
              ngModel.$setViewValue(newVal);
              $interval.cancel(refresh);
            }
          }
        }, 100);
    }

    return {
      require: 'ngModel',
      link: link
    }
  });
Community
  • 1
  • 1
0

This is the solution I ended up using in my forms.

.directive('autofillSync', [ function(){
  var link = function(scope, element, attrs, ngFormCtrl){
    element.on('submit', function(event){
      if(ngFormCtrl.$dirty){
        console.log('returning as form is dirty');
        return;
      }   
      element.find('input').each(function(index, input){
        angular.element(input).trigger('input');
      }); 
    }); 
  };  
  return {
    /* negative priority to make this post link function run first */
    priority:-1,
    link: link,
    require: 'form'
  };  
}]);

And the form's template will be

<form autofill-sync name="user.loginForm" class="login-form" novalidate ng-submit="signIn()">
    <!-- Input fields here -->
</form>

This way I was able to run any parsers/formatters I have on my ng-model and have the submit functionality transparent.

Anirudhan J
  • 2,072
  • 6
  • 27
  • 45
0

Solution without directives:

.run(["$window", "$rootElement", "$timeout", function($window, $rootElement, $timeout){

        var event =$window.document.createEvent("HTMLEvents");
        event.initEvent("change", true, true);

        $timeout(function(){

            Array.apply(null, $rootElement.find("input")).forEach(function(item){
                if (item.value.length) {
                    item.$$currentValue = item.value;
                    item.dispatchEvent(event);
                }
            });

        }, 500);
    }])
ReklatsMasters
  • 708
  • 9
  • 20
0

This is a simple fix that works for all the cases I've tested in both Firefox and Chrome. Note that with the top answer (directive w/ timeout) I had issues with -

  • Browser back / forward buttons, don't re-fire page load events (so the fix doesn't apply)
  • Loading of credentials some time after page load. e.g. in Firefox, double click on the login box and select from stored credentials.
  • Need a solution that updates before form submission since I disable the Login button until valid input provided

This fix is obviously very dumb and hacky, but it works 100% of the time -

function myScope($scope, $timeout) {
    // ...
    (function autoFillFix() {
        $timeout(function() { 
            $('#username').trigger('change'); 
            $('#password').trigger('change'); 
            autoFillFix(); }, 500);                    
    })();
}
Richard Nichols
  • 1,910
  • 17
  • 19
  • 1
    could replace `$timeout` with `$interval` to give future devs a bit more context and get rid of the strange looking recursive calls going on there – O'Mutt Mar 24 '15 at 20:36
0

None of these solutions worked for my use case. I have some form fields that use ng-change to watch for change. Using $watch is no help as it is not triggered by autofill. Since I have no submit button there is no easy way to run some of the solutions and I was not successful using intervals.

I ended up disabling autofill - not ideal but a lot less confusing to the user.

<input readonly onfocus="this.removeAttribute('readonly');">

Found the answer here

Community
  • 1
  • 1
cyberwombat
  • 38,105
  • 35
  • 175
  • 251
-1

If you are using jQuery you could do this on form submit:

HTML:

<form ng-submit="submit()">
    <input id="email" ng-model="password" required 
           type="text" placeholder="Your email">
    <input id="password" ng-model="password" required 
           type="password" placeholder="Password">
</form>

JS:

 $scope.submit = function() {
     $scope.password = $('#password').val();
}
Hans Kerkhof
  • 442
  • 3
  • 7
-1

If you want to keep it simple just get the value using javascript

In your angular js controller :

var username = document.getElementById('username').value;

user361697
  • 1,093
  • 2
  • 12
  • 21