123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- 'use strict';
- /**
- * General-purpose validator for ngModel.
- * angular.js comes with several built-in validation mechanism for input fields (ngRequired, ngPattern etc.) but using
- * an arbitrary validation function requires creation of a custom formatters and / or parsers.
- * The ui-validate directive makes it easy to use any function(s) defined in scope as a validator function(s).
- * A validator function will trigger validation on both model and input changes.
- *
- * @example <input ui-validate=" 'myValidatorFunction($value)' ">
- * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }">
- * @example <input ui-validate="{ foo : '$value > anotherModel' }" ui-validate-watch=" 'anotherModel' ">
- * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }" ui-validate-watch=" { foo : 'anotherModel' } ">
- *
- * @param ui-validate {string|object literal} If strings is passed it should be a scope's function to be used as a validator.
- * If an object literal is passed a key denotes a validation error key while a value should be a validator function.
- * In both cases validator function should take a value to validate as its argument and should return true/false indicating a validation result.
- */
- angular.module('ui.validate',[]).directive('uiValidate', function () {
- return {
- restrict: 'A',
- require: 'ngModel',
- link: function (scope, elm, attrs, ctrl) {
- var validateFn, validators = {},
- validateExpr = scope.$eval(attrs.uiValidate);
- if (!validateExpr){ return;}
- if (angular.isString(validateExpr)) {
- validateExpr = { validator: validateExpr };
- }
- angular.forEach(validateExpr, function (exprssn, key) {
- validateFn = function (valueToValidate) {
- var expression = scope.$eval(exprssn, { '$value' : valueToValidate });
- if (angular.isObject(expression) && angular.isFunction(expression.then)) {
- // expression is a promise
- expression.then(function(){
- ctrl.$setValidity(key, true);
- }, function(){
- ctrl.$setValidity(key, false);
- });
- return valueToValidate;
- } else if (expression) {
- // expression is true
- ctrl.$setValidity(key, true);
- return valueToValidate;
- } else {
- // expression is false
- ctrl.$setValidity(key, false);
- return valueToValidate;
- }
- };
- validators[key] = validateFn;
- ctrl.$formatters.push(validateFn);
- ctrl.$parsers.push(validateFn);
- });
- function apply_watch(watch)
- {
- //string - update all validators on expression change
- if (angular.isString(watch))
- {
- scope.$watch(watch, function(){
- angular.forEach(validators, function(validatorFn){
- validatorFn(ctrl.$modelValue);
- });
- });
- return;
- }
- //array - update all validators on change of any expression
- if (angular.isArray(watch))
- {
- angular.forEach(watch, function(expression){
- scope.$watch(expression, function()
- {
- angular.forEach(validators, function(validatorFn){
- validatorFn(ctrl.$modelValue);
- });
- });
- });
- return;
- }
- //object - update appropriate validator
- if (angular.isObject(watch))
- {
- angular.forEach(watch, function(expression, validatorKey)
- {
- //value is string - look after one expression
- if (angular.isString(expression))
- {
- scope.$watch(expression, function(){
- validators[validatorKey](ctrl.$modelValue);
- });
- }
- //value is array - look after all expressions in array
- if (angular.isArray(expression))
- {
- angular.forEach(expression, function(intExpression)
- {
- scope.$watch(intExpression, function(){
- validators[validatorKey](ctrl.$modelValue);
- });
- });
- }
- });
- }
- }
- // Support for ui-validate-watch
- if (attrs.uiValidateWatch){
- apply_watch( scope.$eval(attrs.uiValidateWatch) );
- }
- }
- };
- });
|