Comparing two input values in a form validation with AngularJS Comparing two input values in a form validation with AngularJS angularjs angularjs

Comparing two input values in a form validation with AngularJS


You should be able to use ng-pattern/regex for comparing 2 input values

Email:<input type="email" name="email1" ng-model="emailReg">Repeat Email:<input type="email" name="email2" ng-model="emailReg2" ng-pattern="emailReg">

and validation with:

<span ng-show="registerForm.email2.$error.pattern">Repeat Email should have the same value with email!</span>


One way to achieve this is with a custom directive. Here's an example using a custom directive (ng-match in this case):

<p>Email:<input type="email" name="email1" ng-model="emailReg">Repeat Email:<input type="email" name="email2" ng-model="emailReg2" ng-match="emailReg"></p><span data-ng-show="myForm.emailReg2.$error.match">Emails have to match!</span>

NOTE: It's not generally recommended to use ng- as a prefix for a custom directive because it may conflict with an official AngularJS directive.

Update

It's also possible to get this functionality without using a custom directive:

HTML

<button ng-click="add()></button><span ng-show="IsMatch">Emails have to match!</span>

Controller

$scope.add = function() {  if ($scope.emailReg != $scope.emailReg2) {    $scope.IsMatch=true;    return false;  }  $scope.IsMatch=false;}


trainosais - you are right, validation should be done on a directive level. It's clean, modular and allows for reusability of code. When you have basic validation like that in a controller you have write it over and over again for different forms. That's super anti-dry.

I had a similar problem recently and sorted it out with a simple directive, which plugs in to the parsers pipeline, therefore stays consistent with Angular architecture. Chaining validators makes it very easy to reuse and that should be considered the only solution in my view.

Without further ado, here's the simplified markup:

<form novalidate="novalidate">    <label>email</label>    <input type="text"        ng-model="email"        name="email" />    <label>email repeated</label>    <input ng-model="emailRepeated"        same-as="email"        name="emailRepeated" /></form>

And the JS code:

angular.module('app', [])    .directive('sameAs', function() {        return {            require: 'ngModel',            link: function(scope, elem, attrs, ngModel) {                ngModel.$parsers.unshift(validate);                // Force-trigger the parsing pipeline.                scope.$watch(attrs.sameAs, function() {                    ngModel.$setViewValue(ngModel.$viewValue);                });                function validate(value) {                    var isValid = scope.$eval(attrs.sameAs) == value;                    ngModel.$setValidity('same-as', isValid);                    return isValid ? value : undefined;                }            }        };    });

The directive hooks into the parsers pipeline in order to get notified of any changes to the view value and set validity based on comparison of the new view value and the value of the reference field. That bit is easy. The tricky bit is sniffing for changes on the reference field. For that the directive sets a watcher on the reference value and force-triggeres the parsing pipeline, in order to get all the validators run again.

If you want to play with it, here is my pen:http://codepen.io/jciolek/pen/kaKEn

I hope it helps,Jacek