Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom form validation directive to compare two fields

I'm an angular newbie, and I'm stumbling over something in how angular's form validation directives work.

I know that I can fairly easily add directives to individual fields, but I'm trying to add a validation which will compare two form fields (both of which are elements of a model).

Here's a form skeleton:

<form name="edit_form" >   <input name="min" type="number" ng-model="field.min"/>   <input name="max" type="number" ng-model="field.max"/> </form>  <div class="error" ng-show="edit_form.min.$dirty || edit_form.max.$dirty">   <small class="error" ng-show="(what goes here?)">     Min cannot exceed max   </small> </div> 

In short, I want to write a directive and use it to show/hide this small.error if min and max both have values but min > max. How can I access both fields inside one directive? Is a directive the right tool for this job?

like image 378
asfallows Avatar asked Jan 07 '14 21:01

asfallows


People also ask

Which of the following validation can be used to compare values of two form fields?

You can perform this type of form validation by using the CompareValidator control. To compare two dates, you need to set the ControlToValidate, ControlToCompare, Operator, and Type properties of the CompareValidator control.

What is cross field validation?

In simple words, making sure our data is correct by using multiple fields to check the validity of another. In fancier terms, this process is called Cross Field Validation. Sanity checking your dataset for data integrity is essential to have accurate analysis and running machine learning models.

How do I create a custom validator?

Custom validators take the value from the FormControl , where every input acts as a FormControl . So let's create a form along with a validator function. Create a new file called customvalidator. validator.

What is Validatorfn?

ValidatorFnlinkA function that receives a control and synchronously returns a map of validation errors if present, otherwise null.


2 Answers

You do not need any directive. Just assign the "min" value of max to min-value. Like:

<input name="min" type="number" ng-model="field.min"/> <input name="max" type="number" ng-model="field.max" min=" {{ field.min }}"/> 

And you do not need any customization.
More: you can do min=" {{ field.min + 1}}"

like image 126
kamil.rak Avatar answered Sep 22 '22 02:09

kamil.rak


Many ways to skin a cat.

PLUNKER

app.directive('lowerThan', [   function() {      var link = function($scope, $element, $attrs, ctrl) {        var validate = function(viewValue) {         var comparisonModel = $attrs.lowerThan;          if(!viewValue || !comparisonModel){           // It's valid because we have nothing to compare against           ctrl.$setValidity('lowerThan', true);         }          // It's valid if model is lower than the model we're comparing against         ctrl.$setValidity('lowerThan', parseInt(viewValue, 10) < parseInt(comparisonModel, 10) );         return viewValue;       };        ctrl.$parsers.unshift(validate);       ctrl.$formatters.push(validate);        $attrs.$observe('lowerThan', function(comparisonModel){         // Whenever the comparison model changes we'll re-validate         return validate(ctrl.$viewValue);       });      };      return {       require: 'ngModel',       link: link     };    } ]); 

Usage:

<input name="min" type="number" ng-model="field.min" lower-than="{{field.max}}" /> <span class="error" ng-show="form.min.$error.lowerThan">   Min cannot exceed max. </span> 
like image 27
Stewie Avatar answered Sep 19 '22 02:09

Stewie