I currently have an Angular Directive that validates a password and confirm password field as matching. It works to a point, it does throw an error when the passwords do not match. However, it doesn't throw the error until you have entered data in both fields. How can I make it so the error for mismatched passwords is thrown as soon as you enter data in one field or the other?
Here is the directive (it has to be added to both fields that need to 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>
test to check the validation of a password. Some possible validations can be – the password should have a minimum of 8 characters, it should be a mix of uppercase, lowercase, digits, etc., or it should have at least one special character.
Just change the last check:
ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
to:
ngModel.$setValidity('passwordVerify', val1 === val2);
Here's a 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>
I hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With