ui-validate.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. 'use strict';
  2. /**
  3. * General-purpose validator for ngModel.
  4. * angular.js comes with several built-in validation mechanism for input fields (ngRequired, ngPattern etc.) but using
  5. * an arbitrary validation function requires creation of a custom formatters and / or parsers.
  6. * The ui-validate directive makes it easy to use any function(s) defined in scope as a validator function(s).
  7. * A validator function will trigger validation on both model and input changes.
  8. *
  9. * @example <input ui-validate=" 'myValidatorFunction($value)' ">
  10. * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }">
  11. * @example <input ui-validate="{ foo : '$value > anotherModel' }" ui-validate-watch=" 'anotherModel' ">
  12. * @example <input ui-validate="{ foo : '$value > anotherModel', bar : 'validateFoo($value)' }" ui-validate-watch=" { foo : 'anotherModel' } ">
  13. *
  14. * @param ui-validate {string|object literal} If strings is passed it should be a scope's function to be used as a validator.
  15. * If an object literal is passed a key denotes a validation error key while a value should be a validator function.
  16. * In both cases validator function should take a value to validate as its argument and should return true/false indicating a validation result.
  17. */
  18. angular.module('ui.validate',[]).directive('uiValidate', function () {
  19. return {
  20. restrict: 'A',
  21. require: 'ngModel',
  22. link: function (scope, elm, attrs, ctrl) {
  23. var validateFn, validators = {},
  24. validateExpr = scope.$eval(attrs.uiValidate);
  25. if (!validateExpr){ return;}
  26. if (angular.isString(validateExpr)) {
  27. validateExpr = { validator: validateExpr };
  28. }
  29. angular.forEach(validateExpr, function (exprssn, key) {
  30. validateFn = function (valueToValidate) {
  31. var expression = scope.$eval(exprssn, { '$value' : valueToValidate });
  32. if (angular.isObject(expression) && angular.isFunction(expression.then)) {
  33. // expression is a promise
  34. expression.then(function(){
  35. ctrl.$setValidity(key, true);
  36. }, function(){
  37. ctrl.$setValidity(key, false);
  38. });
  39. return valueToValidate;
  40. } else if (expression) {
  41. // expression is true
  42. ctrl.$setValidity(key, true);
  43. return valueToValidate;
  44. } else {
  45. // expression is false
  46. ctrl.$setValidity(key, false);
  47. return valueToValidate;
  48. }
  49. };
  50. validators[key] = validateFn;
  51. ctrl.$formatters.push(validateFn);
  52. ctrl.$parsers.push(validateFn);
  53. });
  54. function apply_watch(watch)
  55. {
  56. //string - update all validators on expression change
  57. if (angular.isString(watch))
  58. {
  59. scope.$watch(watch, function(){
  60. angular.forEach(validators, function(validatorFn){
  61. validatorFn(ctrl.$modelValue);
  62. });
  63. });
  64. return;
  65. }
  66. //array - update all validators on change of any expression
  67. if (angular.isArray(watch))
  68. {
  69. angular.forEach(watch, function(expression){
  70. scope.$watch(expression, function()
  71. {
  72. angular.forEach(validators, function(validatorFn){
  73. validatorFn(ctrl.$modelValue);
  74. });
  75. });
  76. });
  77. return;
  78. }
  79. //object - update appropriate validator
  80. if (angular.isObject(watch))
  81. {
  82. angular.forEach(watch, function(expression, validatorKey)
  83. {
  84. //value is string - look after one expression
  85. if (angular.isString(expression))
  86. {
  87. scope.$watch(expression, function(){
  88. validators[validatorKey](ctrl.$modelValue);
  89. });
  90. }
  91. //value is array - look after all expressions in array
  92. if (angular.isArray(expression))
  93. {
  94. angular.forEach(expression, function(intExpression)
  95. {
  96. scope.$watch(intExpression, function(){
  97. validators[validatorKey](ctrl.$modelValue);
  98. });
  99. });
  100. }
  101. });
  102. }
  103. }
  104. // Support for ui-validate-watch
  105. if (attrs.uiValidateWatch){
  106. apply_watch( scope.$eval(attrs.uiValidateWatch) );
  107. }
  108. }
  109. };
  110. });