I'm writing a password verify directive :
Directives.directive("passwordVerify",function(){
return {
require:"ngModel",
link: function(scope,element,attrs,ctrl){
ctrl.$parsers.unshift(function(viewValue){
var origin = scope.$eval(attrs["passwordVerify"]);
if(origin!==viewValue){
ctrl.$setValidity("passwordVerify",false);
return undefined;
}else{
ctrl.$setValidity("passwordVerify",true);
return viewValue;
}
});
}
};
});
html :
<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<input data-ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">
Given 2 password fields in a form, if both password values are equal then the field affected by the directive is valid. The issue is that it works one way (i.e. when I type a password in the password-verify field). However, when the original password field is updated, the password-verify doesn't become valid.
Any idea how I could have a "two way binding verify?"
I use the following directive because I want to re-validate both input field regardless of whether value 1 or value 2 was changed:
directive:
'use strict';
angular.module('myApp').directive('equals', 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('equals', function (val) {
validate();
});
var validate = function() {
// values
var val1 = ngModel.$viewValue;
var val2 = attrs.equals;
// set validity
ngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2);
};
}
}
});
usage
<input type="password" ng-model="value1" equals="{{value2}}" required>
<input type="password" ng-model="value2" equals="{{value1}}" required>
Creating a separate directive for this is not needed. There is already a build in Angular UI password validation tool. With this you could do:
<input name="password" required ng-model="password">
<input name="confirm_password"
ui-validate=" '$value==password' "
ui-validate-watch=" 'password' ">
Passwords match? {{!!form.confirm_password.$error.validator}}
This should solve it:
View:
<div ng-controller='Ctrl'>
<form name='form'>
<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<div ng-show="form.password.$error.required">
Field required</div>
<input ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">
<div ng-show="form.confirm_password.$error.required">
Field required!</div>
<div ng-show="form.confirm_password.$error.passwordVerify">
Fields are not equal!</div>
</form
</div>
Directive
var app = angular.module('myApp', []);
app.directive("passwordVerify", function() {
return {
require: "ngModel",
scope: {
passwordVerify: '='
},
link: function(scope, element, attrs, ctrl) {
scope.$watch(function() {
var combined;
if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + ctrl.$viewValue;
}
return combined;
}, function(value) {
if (value) {
ctrl.$parsers.unshift(function(viewValue) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
ctrl.$setValidity("passwordVerify", false);
return undefined;
} else {
ctrl.$setValidity("passwordVerify", true);
return viewValue;
}
});
}
});
}
};
});
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