JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.js"></script>
<div ng-controller='Ctrl'>
<h2>Plain version (nxEqual)</h2>
<form name="form">
<input ng-model="login.password" type="password" name="password" placeholder="Password" required><br>
<div class="error" ng-show="form.password.$error.required">Required</div>
<input ng-model="login.verify" type="password" name="verify" placeholder="Confirm Password" required nx-equal="login.password"><br>
<div class="error" ng-show="form.verify.$error.required">Required!</div>
<div class="error" ng-show="form.verify.$error.nxEqual">Must be equal!</div>
</form>
<h2>Extended version (nxEqualEx)</h2>
<form name="formEx">
<input ng-model="loginEx.password" type="password" name="password" placeholder="Password" required><br>
<div class="error" ng-show="formEx.password.$error.required">Required</div>
<input ng-model="loginEx.verify" type="password" name="verify" placeholder="Confirm Password" required nx-equal-ex="loginEx.password"><br>
<div class="error" ng-show="formEx.verify.$error.required">Required!</div>
<div class="error" ng-show="formEx.verify.$error.nxEqualEx">Must be equal!</div>
</form>
</div>
CSS
body {
margin: 10px;
}
h2 {
margin: 20px 0 5px 0;
}
.error {
color: darkred;
margin: 2px 0 5px 0;
}
JavaScript
var app = angular.module('myApp', []);
app.directive('nxEqual', function() {
return {
require: 'ngModel',
link: function (scope, elem, attrs, model) {
if (!attrs.nxEqual) {
console.error('nxEqual expects a model as an argument!');
return;
}
scope.$watch(attrs.nxEqual, function (value) {
model.$setValidity('nxEqual', value === model.$viewValue);
});
model.$parsers.push(function (value) {
var isValid = value === scope.$eval(attrs.nxEqual);
model.$setValidity('nxEqual', isValid);
return isValid ? value : undefined;
});
}
};
});
app.directive('nxEqualEx', function() {
return {
require: 'ngModel',
link: function (scope, elem, attrs, model) {
if (!attrs.nxEqualEx) {
console.error('nxEqualEx expects a model as an argument!');
return;
}
scope.$watch(attrs.nxEqualEx, function (value) {
// Only compare values if the second ctrl has a value.
if (model.$viewValue !== undefined && model.$viewValue !== '') {
model.$setValidity('nxEqualEx', value === model.$viewValue);
}
});
model.$parsers.push(function (value) {
// Mute the nxEqual error if the second ctrl is empty.
if (value === undefined || value === '') {
model.$setValidity('nxEqualEx', true);
return value;
}
var isValid = value === scope.$eval(attrs.nxEqualEx);
model.$setValidity('nxEqualEx', isValid);
return isValid ? value : undefined;
});
}
};
});
function Ctrl($scope) {}