Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - using a form and auto-completion

I have the following code in a partial page used for login...

<div class="container">
    <form autocomplete="on" data-ng-submit="checkCredentials()" class="form-signin">
        <h2 class="form-signin-heading">Login page</h2>
        <label for="email"> <b>User e-mail</b> </label>
        <input required autocomplete="on" name="email" type="text" data-ng-model="modelLogin.email" class="input-block-level" placeholder="Email address">
        <label for="pass"> <b>Password</b> </label>
        <input required autocomplete="on" name="pass" type="password" data-ng-model="modelLogin.password" class="input-block-level" placeholder="Password">
        <button style="margin-bottom:1em" class="btn btn-large btn-primary" type="submit">Log in</button>
    </form>
</div>

...which is ng-included from my one and only main page (index.html):

<body data-ng-controller="controllerLogin">
    <div data-ng-include="getMainpageBasedOnLoginStatus()">
    </div>
</body>

...with the getMainpageBasedOnLoginStatus() function returning the appropriate path to either the partials/loginPage.html shown above or the partials/mainApplicationPage.html (my main app entrypoint). The checkCredentials() call done via ng-submit performs a webservice call to get back login success/failure, and does the proper update in a global model variable - so that subsequent calls to getMainpageBasedOnLoginStatus() return the 'ok-you-are-logged-in' page (partials/mainApplicationPage.html).

This login scheme cannot be hacked, because even if the client code is somehow changed to direct to the main app partial instead of the login partial, the server side will simply not function properly (web service requests simply won't function and return 406 errors).

All is well - it works. Except for... autofill.

The login/password fields are neither autocompleted, nor autofilled with Chrome 29. Same in Firefox 23: the login/password fields are not autofilled, but the login one (only the login one, not the password one!) is autocompleted - but not auto-filled.

Note that I have used the HTML5 attribute 'autocomplete' in both the form and the two inputs - with no result whatsoever.

Googling has revealed others who face related issues ( Remember Password with AngularJS and ng-submit ) , with no answer... I could not upvote that question (I am too green yet, SO-wise).

There is also an open ticket on AngularJS ( https://github.com/angular/angular.js/issues/1460 ) that is there for 7 months, and tells the rather sad tale of people where autofill was actually "working", browser-wise, for some people, except that the underlying model was not updated... and a comment there from someone called "bigbag" that the feature is now disabled, for that reason.

I find this rather unacceptable from the point of view of AngularJS - surely I am not the first one that needs autofill/autocomplete in his app's forms, am I? Or do I have to abandon the Single Page theory and revert back to the nasty form action and separate server-side provided login.html/main.html responses to get autofill/autocomplete working?

Any help/advice most appreciated and desperately needed...

like image 844
angularJsNewbie Avatar asked Mar 23 '23 09:03

angularJsNewbie


1 Answers

Here is an alternative solution that 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 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>
like image 109
Ezekiel Victor Avatar answered Apr 17 '23 04:04

Ezekiel Victor