Input Matcher
This is a small demo for the input matcher. It showcases using it and displaying custom errors for the specific case where they do not match.
by Evan Sharp
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
<div data-ng-app="myApp">
<p>
This is a very basic example/demo.<br />
It will only fire after the confirm field has been modified (is no longer pristine)
</p>
<hr />
<form name="myForm">
Password: <input ng-model="user.password" type="text" name="password" data-ng-class="{'ng-invalid':myForm.confirmPassword.$error.match}" />
Confirm: <input ng-model="user.passwordConfirm" type="text" data-match="user.password" name="confirmPassword" />
<div data-ng-show="myForm.confirmPassword.$error.match">Passwords do not match!</div>
</form>
<hr />
<p>Mis-match? {{myForm.confirmPassword.$error.match}}</p>
<p>Internal password value: {{user.password}}</p>
<p>Internal confirm value: {{user.passwordConfirm}}</p>
</div>
CSS
input{
border:1px solid black;
outline:none;
}
input.ng-invalid{
border-color: red;
}
JavaScript
'use strict';
angular.module('myApp', []).directive('match', match);
function match ($parse) {
return {
require: '?ngModel',
restrict: 'A',
link: function(scope, elem, attrs, ctrl) {
if(!ctrl) {
console && console.warn('Match validation requires ngModel to be on the element');
return;
}
var matchGetter = $parse(attrs.match);
var modelSetter = $parse(attrs.ngModel).assign;
scope.$watch(attrs.match, function(){
modelSetter(scope, parser(ctrl.$viewValue));
});
ctrl.$parsers.unshift(parser);
ctrl.$formatters.unshift(formatter);
function parser(viewValue){
if((ctrl.$pristine && ctrl.$isEmpty(viewValue)) || viewValue === matchGetter(scope)){
ctrl.$setValidity('match', true);
return viewValue;
}else{
ctrl.$setValidity('match', false);
return undefined;
}
}
function formatter(modelValue){
return modelValue === undefined? ctrl.$isEmpty(ctrl.$viewValue)? undefined : ctrl.$viewValue : modelValue;
}
}
};
}