Angularjs Chrome autocomplete dilemma

后端 未结 15 1700
野性不改
野性不改 2020-12-05 06:56

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

相关标签:
15条回答
  • 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.

    0 讨论(0)
  • 2020-12-05 06:56

    It could be much simpler solution to the problem.

    1. Angularjs couldn't "see" the value
    2. Take the value via DOM (jQuery) then put it back into Angularjs.

    ```

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

    ```

    0 讨论(0)
  • 2020-12-05 07:02

    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:

    • set autocomplete="new-password" on the password field
    • set autocomplete="off" in the username field.

    I hope that it works for you too :)

    0 讨论(0)
  • 2020-12-05 07:02

    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?

    0 讨论(0)
  • 2020-12-05 07:03

    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>
    
    0 讨论(0)
  • 2020-12-05 07:05

    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.

    0 讨论(0)
提交回复
热议问题