| OLD | NEW |
| 1 part of angular.directive; | 1 part of angular.directive; |
| 2 | 2 |
| 3 abstract class NgValidatable { | 3 /** |
| 4 String get name; | 4 * _NgModelValidator refers to the required super-class which is used when creat
ing |
| 5 bool isValid(value); | 5 * validation services that are used with [ngModel]. It is expected that any chi
ld-classes |
| 6 * that inherit from this perform the necessary logic to return a simple true/fa
lse response |
| 7 * when validating the contents of the model data. |
| 8 */ |
| 9 abstract class _NgModelValidator { |
| 10 final dom.Element inputElement; |
| 11 final NgModel ngModel; |
| 12 final Scope scope; |
| 13 bool _listening = false; |
| 14 |
| 15 _NgModelValidator(dom.Element this.inputElement, NgModel this.ngModel, Scope t
his.scope); |
| 16 |
| 17 /** |
| 18 * Registers the validator with to attached model. |
| 19 */ |
| 20 bool listen() { |
| 21 if(!_listening) { |
| 22 _listening = true; |
| 23 this.ngModel.addValidator(this); |
| 24 } |
| 25 } |
| 26 |
| 27 get value => ngModel.viewValue; |
| 28 |
| 29 /** |
| 30 * De-registers the validator with to attached model. |
| 31 */ |
| 32 bool unlisten() { |
| 33 if(_listening) { |
| 34 _listening = false; |
| 35 this.ngModel.removeValidator(this); |
| 36 } |
| 37 } |
| 38 |
| 39 /** |
| 40 * Returns true/false depending on the status of the validator's validation me
chanism |
| 41 */ |
| 42 bool isValid(); |
| 6 } | 43 } |
| 7 | 44 |
| 8 /** | 45 /** |
| 9 * Validates the model depending if required or ng-required is present on the el
ement. | 46 * Validates the model depending if required or ng-required is present on the el
ement. |
| 10 */ | 47 */ |
| 11 @NgDirective( | 48 @NgDirective(selector: '[ng-model][required]') |
| 12 selector: '[ng-model][required]') | 49 @NgDirective(selector: '[ng-model][ng-required]', map: const {'ng-required': '=>
required'}) |
| 13 @NgDirective( | 50 class NgModelRequiredValidator extends _NgModelValidator { |
| 14 selector: '[ng-model][ng-required]', | 51 bool _required; |
| 15 map: const {'ng-required': '=>required'}) | 52 get name => 'required'; |
| 16 class NgModelRequiredValidator implements NgValidatable { | |
| 17 bool _required = true; | |
| 18 | 53 |
| 19 String get name => 'required'; | 54 NgModelRequiredValidator(dom.Element inputElement, NgModel ngModel, Scope scop
e, NodeAttrs attrs): |
| 55 super(inputElement, ngModel, scope) { |
| 56 if(attrs['required'] != null) { |
| 57 required = true; |
| 58 } |
| 59 } |
| 20 | 60 |
| 21 NgModelRequiredValidator(NgModel ngModel) { | 61 bool isValid() { |
| 22 ngModel.addValidator(this); | 62 return !required || (value != null && value.length > 0); |
| 23 } | 63 } |
| 24 | 64 |
| 25 bool isValid(value) { | 65 @NgAttr('required') |
| 26 // Any element which isn't required is always valid. | 66 get required => _required; |
| 27 if (!_required) return true; | |
| 28 // Null is not a value, therefore not valid. | |
| 29 if (value == null) return false; | |
| 30 // Empty lists and/or strings are not valid. | |
| 31 // NOTE: This is an excellent use case for structural typing. | |
| 32 // We really want anything object that has a 'isEmpty' property. | |
| 33 return !((value is List || value is String) && value.isEmpty); | |
| 34 } | |
| 35 | |
| 36 set required(value) { | 67 set required(value) { |
| 37 _required = value == null ? false : value; | 68 if(value is String) return; |
| 69 (_required = value) == true ? listen() : unlisten(); |
| 38 } | 70 } |
| 39 } | 71 } |
| 40 | 72 |
| 41 /** | 73 /** |
| 42 * Validates the model to see if its contents match a valid URL pattern. | 74 * Validates the model to see if its contents match a valid URL pattern. |
| 43 */ | 75 */ |
| 44 @NgDirective(selector: 'input[type=url][ng-model]') | 76 @NgDirective(selector: 'input[type=url][ng-model]') |
| 45 class NgModelUrlValidator implements NgValidatable { | 77 class NgModelUrlValidator extends _NgModelValidator { |
| 46 static final URL_REGEXP = new RegExp( | 78 static final URL_REGEXP = new RegExp( |
| 47 r'^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?' + | 79 r'^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?' + |
| 48 r'(\/|\/([\w#!:.?+=&%@!\-\/]))?$'); | 80 r'(\/|\/([\w#!:.?+=&%@!\-\/]))?$'); |
| 49 | 81 |
| 50 String get name => 'url'; | 82 get name => 'url'; |
| 51 | 83 |
| 52 NgModelUrlValidator(NgModel ngModel) { | 84 NgModelUrlValidator(dom.Element inputElement, NgModel ngModel, Scope scope): |
| 53 ngModel.addValidator(this); | 85 super(inputElement, ngModel, scope) { |
| 86 listen(); |
| 87 } |
| 88 |
| 89 bool isValid() { |
| 90 return value == null || value.length == 0 || URL_REGEXP.hasMatch(value); |
| 54 } | 91 } |
| 55 | |
| 56 bool isValid(value) => | |
| 57 value == null || value.isEmpty || URL_REGEXP.hasMatch(value); | |
| 58 } | 92 } |
| 59 | 93 |
| 60 /** | 94 /** |
| 61 * Validates the model to see if its contents match a valid email pattern. | 95 * Validates the model to see if its contents match a valid email pattern. |
| 62 */ | 96 */ |
| 63 @NgDirective(selector: 'input[type=email][ng-model]') | 97 @NgDirective(selector: 'input[type=email][ng-model]') |
| 64 class NgModelEmailValidator implements NgValidatable { | 98 class NgModelEmailValidator extends _NgModelValidator { |
| 65 static final EMAIL_REGEXP = new RegExp( | 99 static final EMAIL_REGEXP = new RegExp( |
| 66 r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$'); | 100 r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$'); |
| 67 | 101 |
| 68 String get name => 'email'; | 102 get name => 'email'; |
| 69 | 103 |
| 70 NgModelEmailValidator(NgModel ngModel) { | 104 NgModelEmailValidator(dom.Element inputElement, NgModel ngModel, Scope scope): |
| 71 ngModel.addValidator(this); | 105 super(inputElement, ngModel, scope) { |
| 106 listen(); |
| 107 } |
| 108 |
| 109 bool isValid() { |
| 110 return value == null || value.length == 0 || EMAIL_REGEXP.hasMatch(value); |
| 72 } | 111 } |
| 73 | |
| 74 bool isValid(value) => | |
| 75 value == null || value.isEmpty || EMAIL_REGEXP.hasMatch(value); | |
| 76 } | 112 } |
| 77 | 113 |
| 78 /** | 114 /** |
| 79 * Validates the model to see if its contents match a valid number. | 115 * Validates the model to see if its contents match a valid number. |
| 80 */ | 116 */ |
| 81 @NgDirective(selector: 'input[type=number][ng-model]') | 117 @NgDirective(selector: 'input[type=number][ng-model]') |
| 82 class NgModelNumberValidator implements NgValidatable { | 118 class NgModelNumberValidator extends _NgModelValidator { |
| 83 String get name => 'number'; | 119 get name => 'number'; |
| 84 | 120 |
| 85 NgModelNumberValidator(NgModel ngModel) { | 121 NgModelNumberValidator(dom.Element inputElement, NgModel ngModel, Scope scope)
: |
| 86 ngModel.addValidator(this); | 122 super(inputElement, ngModel, scope) { |
| 87 } | 123 listen(); |
| 124 } |
| 88 | 125 |
| 89 bool isValid(value) { | 126 bool isValid() { |
| 90 if (value != null) { | 127 if(value != null) { |
| 91 try { | 128 try { |
| 92 num val = double.parse(value.toString()); | 129 num val = double.parse(value.toString()); |
| 93 } catch(exception, stackTrace) { | 130 } catch(exception, stackTrace) { |
| 94 return false; | 131 return false; |
| 95 } | 132 } |
| 96 } | 133 } |
| 97 return true; | 134 return true; |
| 98 } | 135 } |
| 99 } | 136 } |
| 100 | 137 |
| 101 /** | 138 /** |
| 102 * Validates the model to see if its contents match the given pattern present on
either the | 139 * Validates the model to see if its contents match the given pattern present on
either the |
| 103 * HTML pattern or ng-pattern attributes present on the input element. | 140 * HTML pattern or ng-pattern attributes present on the input element. |
| 104 */ | 141 */ |
| 105 @NgDirective(selector: '[ng-model][pattern]') | 142 @NgDirective(selector: '[ng-model][pattern]') |
| 106 @NgDirective( | 143 @NgDirective(selector: '[ng-model][ng-pattern]', map: const {'ng-pattern': '=>pa
ttern'}) |
| 107 selector: '[ng-model][ng-pattern]', | 144 class NgModelPatternValidator extends _NgModelValidator { |
| 108 map: const {'ng-pattern': '=>pattern'}) | |
| 109 class NgModelPatternValidator implements NgValidatable { | |
| 110 RegExp _pattern; | 145 RegExp _pattern; |
| 111 | 146 |
| 112 String get name => 'pattern'; | 147 get name => 'pattern'; |
| 113 | 148 |
| 114 NgModelPatternValidator(NgModel ngModel) { | 149 NgModelPatternValidator(dom.Element inputElement, NgModel ngModel, Scope scope
): |
| 115 ngModel.addValidator(this); | 150 super(inputElement, ngModel, scope) { |
| 116 } | 151 listen(); |
| 152 } |
| 117 | 153 |
| 118 bool isValid(value) { | 154 bool isValid() { |
| 155 if(_pattern != null && value != null && value.length > 0) { |
| 156 return _pattern.hasMatch(ngModel.viewValue); |
| 157 } |
| 158 |
| 119 //remember, only required validates for the input being empty | 159 //remember, only required validates for the input being empty |
| 120 return _pattern == null || value == null || value.length == 0 || | 160 return true; |
| 121 _pattern.hasMatch(value); | |
| 122 } | 161 } |
| 123 | 162 |
| 124 @NgAttr('pattern') | 163 @NgAttr('pattern') |
| 125 set pattern(val) => | 164 get pattern => _pattern; |
| 126 _pattern = val != null && val.length > 0 ? new RegExp(val) : null; | 165 set pattern(val) { |
| 166 if(val != null && val.length > 0) { |
| 167 _pattern = new RegExp(val); |
| 168 listen(); |
| 169 } else { |
| 170 _pattern = null; |
| 171 unlisten(); |
| 172 } |
| 173 } |
| 127 } | 174 } |
| 128 | 175 |
| 129 /** | 176 /** |
| 130 * Validates the model to see if the length of its contents are greater than or | 177 * Validates the model to see if the length of its contents are greater than or
equal to the minimum length |
| 131 * equal to the minimum length set in place by the HTML minlength or | 178 * set in place by the HTML minlength or ng-minlength attributes present on the
input element. |
| 132 * ng-minlength attributes present on the input element. | |
| 133 */ | 179 */ |
| 134 @NgDirective(selector: '[ng-model][minlength]') | 180 @NgDirective(selector: '[ng-model][minlength]') |
| 135 @NgDirective( | 181 @NgDirective(selector: '[ng-model][ng-minlength]', map: const {'ng-minlength': '
=>minlength'}) |
| 136 selector: '[ng-model][ng-minlength]', | 182 class NgModelMinLengthValidator extends _NgModelValidator { |
| 137 map: const {'ng-minlength': '=>minlength'}) | |
| 138 class NgModelMinLengthValidator implements NgValidatable { | |
| 139 int _minlength; | 183 int _minlength; |
| 140 | 184 |
| 141 String get name => 'minlength'; | 185 get name => 'minlength'; |
| 142 | 186 |
| 143 NgModelMinLengthValidator(NgModel ngModel) { | 187 NgModelMinLengthValidator(dom.Element inputElement, NgModel ngModel, Scope sco
pe): |
| 144 ngModel.addValidator(this); | 188 super(inputElement, ngModel, scope) { |
| 145 } | 189 listen(); |
| 190 } |
| 146 | 191 |
| 147 bool isValid(value) { | 192 bool isValid() { |
| 148 //remember, only required validates for the input being empty | 193 //remember, only required validates for the input being empty |
| 149 return _minlength == 0 || value == null || value.length == 0 || | 194 if(_minlength == 0 || value == null || value.length == 0) { |
| 150 value.length >= _minlength; | 195 return true; |
| 196 } |
| 197 return value.length >= _minlength; |
| 151 } | 198 } |
| 152 | 199 |
| 153 @NgAttr('minlength') | 200 @NgAttr('minlength') |
| 154 set minlength(value) => | 201 get minlength => _minlength; |
| 155 _minlength = value == null ? 0 : int.parse(value.toString()); | 202 set minlength(value) { |
| 203 _minlength = value == null ? 0 : int.parse(value.toString()); |
| 204 } |
| 156 } | 205 } |
| 157 | 206 |
| 158 /** | 207 /** |
| 159 * Validates the model to see if the length of its contents are less than or | 208 * Validates the model to see if the length of its contents are less than or equ
al to the maximum length |
| 160 * equal to the maximum length set in place by the HTML maxlength or | 209 * set in place by the HTML maxlength or ng-maxlength attributes present on the
input element. |
| 161 * ng-maxlength attributes present on the input element. | |
| 162 */ | 210 */ |
| 163 @NgDirective(selector: '[ng-model][maxlength]') | 211 @NgDirective(selector: '[ng-model][maxlength]') |
| 164 @NgDirective( | 212 @NgDirective(selector: '[ng-model][ng-maxlength]', map: const {'ng-maxlength': '
=>maxlength'}) |
| 165 selector: '[ng-model][ng-maxlength]', | 213 class NgModelMaxLengthValidator extends _NgModelValidator { |
| 166 map: const {'ng-maxlength': '=>maxlength'}) | |
| 167 class NgModelMaxLengthValidator implements NgValidatable { | |
| 168 int _maxlength = 0; | 214 int _maxlength = 0; |
| 169 | 215 |
| 170 String get name => 'maxlength'; | 216 get name => 'maxlength'; |
| 171 | 217 |
| 172 NgModelMaxLengthValidator(NgModel ngModel) { | 218 NgModelMaxLengthValidator(dom.Element inputElement, NgModel ngModel, Scope sco
pe): |
| 173 ngModel.addValidator(this); | 219 super(inputElement, ngModel, scope) { |
| 220 listen(); |
| 221 } |
| 222 |
| 223 bool isValid() { |
| 224 return _maxlength == 0 || (value == null ? 0 : value.length) <= _maxlength; |
| 174 } | 225 } |
| 175 | 226 |
| 176 bool isValid(value) => | |
| 177 _maxlength == 0 || (value == null ? 0 : value.length) <= _maxlength; | |
| 178 | |
| 179 @NgAttr('maxlength') | 227 @NgAttr('maxlength') |
| 180 set maxlength(value) => | 228 get maxlength => _maxlength; |
| 181 _maxlength = value == null ? 0 : int.parse(value.toString()); | 229 set maxlength(value) { |
| 230 int length = value == null ? 0 : int.parse(value.toString()); |
| 231 if(length != maxlength) { |
| 232 _maxlength = length; |
| 233 } |
| 234 } |
| 182 } | 235 } |
| OLD | NEW |