Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I programmatically apply Angular validation directives inside a custom directive?

I have found great many occurrences of the following pattern for html inputs, this being for phone numbers:

<input type="text" ng-model="CellPhoneNumber" required ng-pattern="/^[0-9]+$/" ng-minlength="10" /> 

I would like to create a custom directive that, wherever applied, will tell Angular to apply all three of these rules, e.g:

<input type="text" ng-model="CellPhoneNumber" bk-ng-validation="phoneNumber"/> 

Then, code in my directive would find and invoke a function called phoneNumber, in which I would like to see something like:

Listing 1:

function bkNgPhoneNumber(model) {     // This is purely SPECULATIVE pseudo-code, just to convey an idea.     model.errors.add(applyMinLength(10, model));     model.errors.add(applyMaxLength(15, model));     model.errors.add(applyPattern("/^[0-9]+$/", model)); } 

I would prefer the above approach over 'rewriting code for these rules, e.g:

Listing 2:

function phoneNumber(model) {     if (model.length < 10 || model.length > 15) {         model.errors.add("Must be 10 to 15 chars!");     } } 

I don't want to do away with all attribute based directives, but preferably create a 'macro' directive that will invoke my Listing 1 code, which will intern invoke a set of more 'micro' validations.

like image 855
ProfK Avatar asked May 10 '15 09:05

ProfK


People also ask

Is Validator a directive Angular?

(NG_VALIDATORS) will be part of this link. Explanations: This class is a directive because of @directive decorator can be used as an attribute on any form element for validating the input, can be as an attribute like we used above on input tag. These kind of directives are known as attribute directives in angular.

Which of the below configures the queries that will be injected into directive?

querieslink Configures the queries that will be injected into the directive.

What is @directive in Angular?

What is meant by directives in Angular? Directives are classes that add new behavior or modify the existing behavior to the elements in the template. Basically directives are used to manipulate the DOM, for example adding/removing the element from DOM or changing the appearance of the DOM elements.

Which of the following are applicable for directives in Angular?

The three types of directives in Angular are attribute directives, structural directives, and components.


2 Answers

One way to do this (i.e. apply existing validators without writing their code again) would be to add the validation directives' respective attributes and force a re-compile. This would require your directive to have a high-enough priority and also be terminal: true.

app.directive("bkNgValidation", function($compile){   return {     priority: 10000,     terminal: true,     link: function(scope, element){       element.attr("ng-required", "true");       element.attr("ng-minlength", 20);       element.attr("ng-maxlength", 30);        // prevent infinite loop       element.removeAttr("bk-ng-validation");        $compile(element)(scope);     }   }; }); 

Demo

like image 99
New Dev Avatar answered Oct 05 '22 05:10

New Dev


If you're using more validations, you can create a service that is responsible for identifying and validating the elements, without any limitation. Default directives of angular remain.

Example:

    module.service('$Validation', ["$compile",function($compile){          this.validators = {             'phoneNumber': [['required', 1], ['minlength',6], ['maxlength', 10], ['pattern', /^[0-9]+$/.source]],             'phoneNumber2Custom': function(value){                  return /^[0-9]{6,10}$/.test(value)              },             'userTwitter': function(value){                 return /^@(.+)/.test(value)             }             // ...etc... /         }          this.add = function(scope, element, attrs, model){             var name = attrs.bkNgValidation, type;             if(!(type = this.validators[name])) return;             else if(angular.isFunction(type)) return (model.$validators[name] = type);              element.removeAttr("bk-ng-validation");             angular.forEach(type, function(expr){                 element.attr(expr[0], expr[1])             });             $compile(element)(scope)                 };      }]).directive('bkNgValidation', ["$Validation", function ($Validation) {         return {             require: '?ngModel',             priority: 1e5,             link: function(){                 $Validation.add.apply($Validation, arguments);             }         }     }]) 

Demo

like image 26
Walter Chapilliquen - wZVanG Avatar answered Oct 05 '22 05:10

Walter Chapilliquen - wZVanG