Password verification and confirmation of password fields when changing one or another field model (each keystroke) With Angular directive

I currently have an angular directive that checks the password and confirms the password field as appropriate. This works to some extent, it throws an error when the passwords do not match. However, it does not throw an error until you enter data in both fields. How can I make the error for mismatched passwords appear as soon as you enter data in one or the other field?

Here is the directive (it must be added to both fields that must match):

.directive('passwordVerify', function() { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController link: function(scope, elem, attrs, ngModel) { //if (!ngModel) return; // do nothing if no ng-model // watch own value and re-validate on change scope.$watch(attrs.ngModel, function() { validate(); }); // observe the other value and re-validate on change attrs.$observe('passwordVerify', function(val) { validate(); }); var validate = function() { // values var val1 = ngModel.$viewValue; var val2 = attrs.passwordVerify; // set validity ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2); }; } }; }); 

And here is the directive in my form:

 <div class="small-5 columns"> <div class="small-12 columns"> <label> Password <input ng-class="{ notvalid: submitted && add_user_form.user_password.$invalid }" class="instructor-input" id="user_password" type="password" name='user_password' placeholder="password" value='' required ng-model="user.user_password" password-verify="[[user.confirm_password]]" > </label> <p class="help-text"> <span class=" ">Required</span> </p> <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched || add_user_form.user_password.$dirty" > <span class="red"> <div ng-messages-include="/app/views/messages.html" ></div> </span> </div> </div> <div class="small-12 columns"> <label> Confirm Password <input ng-class="{ notvalid: submitted && add_user_form.confirm_password.$invalid }" class="instructor-input" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" name="user_confirm_passsword" required password-verify="[[user.user_password]]" > </label> <p class="help-text"> <span class=" "> Enter matching password </span> </p> <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$dirty || add_user_form.confirm_password.$touched " > <span class="red"> <div ng-messages-include="/app/views/messages.html" ></div> </span> </div> </div> 
+6
source share
6 answers

Just change the last check:

 ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2); 

in

 ngModel.$setValidity('passwordVerify', val1 === val2); 

Here's the working version:

 (function() { "use strict"; angular .module('app', ['ngMessages']) .controller('mainCtrl', mainCtrl) .directive('passwordVerify', passwordVerify); function mainCtrl($scope) { // Some code } function passwordVerify() { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController link: function(scope, elem, attrs, ngModel) { if (!ngModel) return; // do nothing if no ng-model // watch own value and re-validate on change scope.$watch(attrs.ngModel, function() { validate(); }); // observe the other value and re-validate on change attrs.$observe('passwordVerify', function(val) { validate(); }); var validate = function() { // values var val1 = ngModel.$viewValue; var val2 = attrs.passwordVerify; // set validity ngModel.$setValidity('passwordVerify', val1 === val2); }; } } } })(); 
 <html ng-app="app"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script> </head> <body ng-controller="mainCtrl"> <form name="add_user_form"> <div class="col-md-12"> <div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$dirty && add_user_form.user_password.$invalid }"> <p class="help-text">Enter password</p> <input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}"> <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-if="add_user_form.user_password.$dirty"> <p ng-message="required">This field is required</p> <p ng-message="minlength">This field is too short</p> <p ng-message="maxlength">This field is too long</p> <p ng-message="required">This field is required</p> <p ng-message="passwordVerify">No match!</p> </div> </div> <div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$dirty && add_user_form.confirm_password.$invalid }"> <p class="help-text">Enter matching password</p> <input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}"> <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-if="add_user_form.confirm_password.$dirty"> <p ng-message="required">This field is required</p> <p ng-message="minlength">This field is too short</p> <p ng-message="maxlength">This field is too long</p> <p ng-message="required">This field is required</p> <p ng-message="passwordVerify">No match!</p> </div> </div> </div> </form> </body> </html> 

Hope this helps.

+8
source

Here is a simple working solution. We can simply use the $validators introduced in Angular 1.3.0 to achieve the same:

 var app = angular.module("sa", []); app.controller("FooController", function($scope) { }); app.directive('passwordVerify', function() { return { restrict: 'A', require: '?ngModel', link: function(scope, elem, attrs, ngModel) { ngModel.$validators.myPwdInvalid = function(modelValue, viewValue) { return viewValue === scope.$eval(attrs.passwordVerify); }; } }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <form name="add_user_form" ng-app="sa" ng-controller="FooController"> <div class="small-12 columns"> <label>Password <input ng-class="{ notvalid: add_user_form.user_password.$invalid }" type="password" name='user_password' placeholder="password" required ng-model="user.user_password" password-verify="user.confirm_password"> </label> <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$error.$dirty || add_user_form.user_password.$touched"> <div ng-messages="myPwdInvalid">Password do not match</div> </div> </div> <div class="small-12 columns"> <label>Confirm Password <input ng-class="{ notvalid: add_user_form.confirm_password.$invalid }" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="user.user_password"> </label> <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$error.$dirty || add_user_form.confirm_password.$touched"> <div ng-messages="myPwdInvalid">Password do not match</div> </div> </div> </form> 
+1
source

This is what worked for me (ugly and hacky):

HTML:

 <h1>Password Verification</h1> <form name="pw" ng-controller="pw"> <p> <label for="password">New Password <input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword"> <p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p> <p ng-show="pw.user_password.$error.required">This field is required</p> </label> </p> <p> <label for="password">Confirm Password <input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password"> <p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p> <p ng-show="pw.confirm_password.$error.required">This field is required</p> </label> </p> </form> 

Then the script:

 angular.module('app', []) .controller('pw', ['$scope', function($scope){ $scope.user_password = ""; $scope.confirm_password = ""; }]) .directive('passwordVerify', function() { return { restrict: 'A', require: '?ngModel', link: function(scope, elem, attrs, ngModel) { scope.$watch(attrs.ngModel, function() { if (scope.confirm_password === scope.user_password) { scope.pw.confirm_password.$setValidity('passwordVerify', true); scope.pw.user_password.$setValidity('passwordVerify', true); } else if (scope.confirm_password !== scope.user_password) { scope.pw.confirm_password.$setValidity('passwordVerify', false); scope.pw.user_password.$setValidity('passwordVerify', false); } }); } }; }); 
0
source

Here is a simple solution to understand:

 <input class="form-control" type="password" name="newpass" ng-model="newpass"> <input class="form-control" type="password" name="confirmpass" ng-model="confirmpass"> <div ng-show="confirmpass != newpass"><hr>Password not matched</div> 
0
source

You can simply use the following.

 <span class="error" ng-if="!register_frm.password.$invalid && !register_frm.confirm_password.$invalid && register_frm.password.$viewValue != register_frm.confirm_password.$viewValue"> Confirm Password must match with Password </span> 
0
source

Although the answers above are correct, there is a very simple solution for this situation:

You can use the ng-class directive to set a class other than the built-in angularjs ( ng-invalid ) class and add a simple style to it in your CSS. DON'T FORGET to add !important to your style, because angularjs overrides it;)

-one
source

All Articles