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