@@ -12,29 +12,42 @@ angular.module('bootstrap.angular.validation').factory('BsValidationService', ['
1212 var customFormGroup = '[bs-form-group]' ;
1313 var formGroupClass = '.form-group' ;
1414
15- var genericValidators = {
16- digits : function ( value ) {
15+ var _genericValidators = [ {
16+ name : 'digits' ,
17+ validateFn : function ( value ) {
1718 return ( / ^ \d + $ / ) . test ( value ) ;
18- } ,
19- equalto : function ( value , $scope , attr ) {
19+ }
20+ } , {
21+ name : 'equalto' ,
22+ validateFn : function ( value , $scope , attr ) {
2023 return value + '' === $scope . $eval ( attr . equalto ) + '' ;
21- } ,
22- number : function ( value ) {
24+ }
25+ } , {
26+ name : 'number' ,
27+ validateFn : function ( value ) {
2328 return ( / ^ - ? (?: \d + | \d { 1 , 3 } (?: , \d { 3 } ) + ) ? (?: \. \d + ) ? $ / ) . test ( value ) ;
24- } ,
25- min : function ( value , $scope , attr ) {
29+ }
30+ } , {
31+ name : 'min' ,
32+ validateFn : function ( value , $scope , attr ) {
2633 return parseFloat ( value ) >= parseFloat ( attr . min ) ;
27- } ,
28- max : function ( value , $scope , attr ) {
34+ }
35+ } , {
36+ name : 'max' ,
37+ validateFn : function ( value , $scope , attr ) {
2938 return parseFloat ( value ) <= parseFloat ( attr . max ) ;
30- } ,
31- length : function ( value , $scope , attr ) {
39+ }
40+ } , {
41+ name : 'length' ,
42+ validateFn : function ( value , $scope , attr ) {
3243 return value . length === parseInt ( attr . length ) ;
33- } ,
34- strictemail : function ( value ) {
44+ }
45+ } , {
46+ name : 'strictemail' ,
47+ validateFn : function ( value ) {
3548 return new RegExp ( / ^ [ _ a - z 0 - 9 ] + ( \. [ _ a - z 0 - 9 ] + ) * @ [ a - z 0 - 9 - ] + ( \. [ a - z 0 - 9 - ] + ) * ( \. [ a - z ] { 2 , 4 } ) $ / ) . test ( value ) ;
3649 }
37- } ;
50+ } ] ;
3851
3952 function getTrigger ( $element , triggerEvent ) {
4053 var attributeName = 'bs-trigger' ;
@@ -51,17 +64,17 @@ angular.module('bootstrap.angular.validation').factory('BsValidationService', ['
5164 return validationConfig . shouldValidateOn ( triggerEvent ) ;
5265 }
5366
67+ function removeClassByPrefix ( element , prefix ) {
68+ var regx = new RegExp ( '\\b' + prefix + '.*\\b' , 'g' ) ;
69+ element [ 0 ] . className = element [ 0 ] . className . replace ( regx , '' ) . replace ( / \s \s + / g, ' ' ) ;
70+ return element ;
71+ }
72+
5473 var meta = [ 'matchName' ] ;
5574
5675 return {
57- /**
58- * Search all the input element inside the given DOM element and apply the 'bs-validation' directive so we
59- * need not a add it for every form element.
60- */
6176 getValidators : function ( ) {
62- var builtIn = [ 'equalto' , 'min' , 'max' , 'number' , 'digits' , 'length' ] ;
63- var additional = Object . keys ( genericValidators ) ;
64- return builtIn . concat ( additional ) ;
77+ return _genericValidators ;
6578 } ,
6679
6780 getMetaInformation : function ( $element ) {
@@ -87,13 +100,32 @@ angular.module('bootstrap.angular.validation').factory('BsValidationService', ['
87100 }
88101 } ,
89102
90- addValidator : function ( $scope , $attr , ngModelController , validatorKey ) {
91- ngModelController . $validators [ validatorKey ] = function ( modelValue , viewValue ) {
103+ addValidator : function ( $scope , $element , $ attr, ngModelController , validator ) {
104+ ngModelController . $validators [ validator . name ] = function ( modelValue , viewValue ) {
92105 var value = modelValue || viewValue ;
93- return ngModelController . $isEmpty ( value ) || genericValidators [ validatorKey ] ( value , $scope , $attr ) ;
106+ if ( ngModelController . $isEmpty ( value ) ) {
107+ return true ;
108+ }
109+
110+ // See https://github.com/sagrawal14/angular-extras/blob/v0.1.3/src/extras/array.js#L91 for "find" function
111+ return validator . validateFn ( value , $scope , $attr ) ;
94112 } ;
95113 } ,
96114
115+ /**
116+ * Add a custom validator to the list of generic validators.
117+ * @param genericValidationObject for example, to a add a generic validator to accept either "foo" or "bar":
118+ * {
119+ * name: 'foobar',
120+ * validateFn: function(value, $scope, attr) {
121+ * return value === 'foo' || value === 'bar';
122+ * }
123+ * }
124+ */
125+ addGenericValidator : function ( genericValidationObject ) {
126+ _genericValidators . push ( genericValidationObject ) ;
127+ } ,
128+
97129 displayErrorPreference : function ( $element , $attr ) {
98130 var attrName = displayErrorAsAttrName ;
99131 if ( $attr [ attrName ] ) {
@@ -204,6 +236,21 @@ angular.module('bootstrap.angular.validation').factory('BsValidationService', ['
204236
205237 shouldValidateOnSubmit : function ( $element ) {
206238 return getTrigger ( $element , 'submit' ) ;
239+ } ,
240+
241+ /**
242+ * Add or remove various classes on form-group element. For example, if an input has two errors "required" & "min"
243+ * then whenever the validation fails, form-group element will have classes like "bs-has-error-required" or
244+ * "bs-has-error-min".
245+ * @param $formGroupElement jQLite/jQuery form-group element
246+ * @param errors Errors object as returned by ngModelController.$error
247+ */
248+ toggleErrorKeyClasses : function ( $formGroupElement , errors ) {
249+ removeClassByPrefix ( $formGroupElement , 'bs-has-error-' ) ;
250+
251+ angular . forEach ( errors , function ( value , key ) {
252+ $formGroupElement . addClass ( 'bs-has-error-' + key ) ;
253+ } ) ;
207254 }
208255
209256 } ;
0 commit comments