Last active
December 17, 2015 14:19
-
-
Save ferronrsmith/5623489 to your computer and use it in GitHub Desktop.
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 ng-validate directive makes it easy to use any function(s) defined in scope as a validator funct…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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 ng-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 ng-validate=" 'myValidatorFunction($value)' "> | |
* @example <input ng-validate="{ foo : '$value > anotherModel', bar : | |
* 'validateFoo($value)' }"> | |
* @example <input ng-validate="{ foo : '$value > anotherModel' }" | |
* ng-validate-watch=" 'anotherModel' "> | |
* @example <input ng-validate="{ foo : '$value > anotherModel', bar : | |
* 'validateFoo($value)' }" ng-validate-watch=" { foo : 'anotherModel' } "> | |
* | |
* @param ng-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. | |
*/ | |
app.directive('ngValidate', function() { | |
"use strict"; | |
return { | |
restrict : 'A', | |
require : 'ngModel', | |
link : function(scope, elm, attrs, ctrl) { | |
var validateFn, watch, validators = {}, validateExpr = scope | |
.$eval(attrs.ngValidate); | |
if (!validateExpr) { | |
return; | |
} | |
if (angular.isString(validateExpr)) { | |
validateExpr = { | |
validator : validateExpr | |
}; | |
} | |
angular.forEach(validateExpr, function(expression, key) { | |
validateFn = function(valueToValidate) { | |
var result; | |
if (scope.$eval(expression, { | |
'$value' : valueToValidate | |
})) { | |
ctrl.$setValidity(key, true); | |
result = valueToValidate; | |
} else { | |
ctrl.$setValidity(key, false); | |
result = undefined; | |
} | |
return result; | |
}; | |
validators[key] = validateFn; | |
ctrl.$formatters.push(validateFn); | |
ctrl.$parsers.push(validateFn); | |
}); | |
// Support for ng-validate-watch | |
if (attrs.ngValidateWatch) { | |
watch = scope.$eval(attrs.ngValidateWatch); | |
if (angular.isString(watch)) { | |
scope.$watch(watch, function() { | |
angular.forEach(validators, function(validatorFn, key) { | |
validatorFn(ctrl.$modelValue); | |
}); | |
}); | |
} else { | |
angular.forEach(watch, function(expression, key) { | |
scope.$watch(expression, function() { | |
validators[key](ctrl.$modelValue); | |
}); | |
}); | |
} | |
} | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment