| Index: third_party/pkg/angular/lib/directive/ng_model_validators.dart
|
| ===================================================================
|
| --- third_party/pkg/angular/lib/directive/ng_model_validators.dart (revision 33054)
|
| +++ third_party/pkg/angular/lib/directive/ng_model_validators.dart (working copy)
|
| @@ -1,40 +1,72 @@
|
| part of angular.directive;
|
|
|
| -abstract class NgValidatable {
|
| - String get name;
|
| - bool isValid(value);
|
| +/**
|
| + * _NgModelValidator refers to the required super-class which is used when creating
|
| + * validation services that are used with [ngModel]. It is expected that any child-classes
|
| + * that inherit from this perform the necessary logic to return a simple true/false response
|
| + * when validating the contents of the model data.
|
| + */
|
| +abstract class _NgModelValidator {
|
| + final dom.Element inputElement;
|
| + final NgModel ngModel;
|
| + final Scope scope;
|
| + bool _listening = false;
|
| +
|
| + _NgModelValidator(dom.Element this.inputElement, NgModel this.ngModel, Scope this.scope);
|
| +
|
| + /**
|
| + * Registers the validator with to attached model.
|
| + */
|
| + bool listen() {
|
| + if(!_listening) {
|
| + _listening = true;
|
| + this.ngModel.addValidator(this);
|
| + }
|
| + }
|
| +
|
| + get value => ngModel.viewValue;
|
| +
|
| + /**
|
| + * De-registers the validator with to attached model.
|
| + */
|
| + bool unlisten() {
|
| + if(_listening) {
|
| + _listening = false;
|
| + this.ngModel.removeValidator(this);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Returns true/false depending on the status of the validator's validation mechanism
|
| + */
|
| + bool isValid();
|
| }
|
|
|
| /**
|
| * Validates the model depending if required or ng-required is present on the element.
|
| */
|
| -@NgDirective(
|
| - selector: '[ng-model][required]')
|
| -@NgDirective(
|
| - selector: '[ng-model][ng-required]',
|
| - map: const {'ng-required': '=>required'})
|
| -class NgModelRequiredValidator implements NgValidatable {
|
| - bool _required = true;
|
| +@NgDirective(selector: '[ng-model][required]')
|
| +@NgDirective(selector: '[ng-model][ng-required]', map: const {'ng-required': '=>required'})
|
| +class NgModelRequiredValidator extends _NgModelValidator {
|
| + bool _required;
|
| + get name => 'required';
|
|
|
| - String get name => 'required';
|
| + NgModelRequiredValidator(dom.Element inputElement, NgModel ngModel, Scope scope, NodeAttrs attrs):
|
| + super(inputElement, ngModel, scope) {
|
| + if(attrs['required'] != null) {
|
| + required = true;
|
| + }
|
| + }
|
|
|
| - NgModelRequiredValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| + bool isValid() {
|
| + return !required || (value != null && value.length > 0);
|
| }
|
|
|
| - bool isValid(value) {
|
| - // Any element which isn't required is always valid.
|
| - if (!_required) return true;
|
| - // Null is not a value, therefore not valid.
|
| - if (value == null) return false;
|
| - // Empty lists and/or strings are not valid.
|
| - // NOTE: This is an excellent use case for structural typing.
|
| - // We really want anything object that has a 'isEmpty' property.
|
| - return !((value is List || value is String) && value.isEmpty);
|
| - }
|
| -
|
| + @NgAttr('required')
|
| + get required => _required;
|
| set required(value) {
|
| - _required = value == null ? false : value;
|
| + if(value is String) return;
|
| + (_required = value) == true ? listen() : unlisten();
|
| }
|
| }
|
|
|
| @@ -42,52 +74,57 @@
|
| * Validates the model to see if its contents match a valid URL pattern.
|
| */
|
| @NgDirective(selector: 'input[type=url][ng-model]')
|
| -class NgModelUrlValidator implements NgValidatable {
|
| +class NgModelUrlValidator extends _NgModelValidator {
|
| static final URL_REGEXP = new RegExp(
|
| r'^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?' +
|
| r'(\/|\/([\w#!:.?+=&%@!\-\/]))?$');
|
|
|
| - String get name => 'url';
|
| + get name => 'url';
|
|
|
| - NgModelUrlValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| + NgModelUrlValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
| +
|
| + bool isValid() {
|
| + return value == null || value.length == 0 || URL_REGEXP.hasMatch(value);
|
| }
|
| -
|
| - bool isValid(value) =>
|
| - value == null || value.isEmpty || URL_REGEXP.hasMatch(value);
|
| }
|
|
|
| /**
|
| * Validates the model to see if its contents match a valid email pattern.
|
| */
|
| @NgDirective(selector: 'input[type=email][ng-model]')
|
| -class NgModelEmailValidator implements NgValidatable {
|
| +class NgModelEmailValidator extends _NgModelValidator {
|
| static final EMAIL_REGEXP = new RegExp(
|
| r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$');
|
|
|
| - String get name => 'email';
|
| + get name => 'email';
|
|
|
| - NgModelEmailValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| + NgModelEmailValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
| +
|
| + bool isValid() {
|
| + return value == null || value.length == 0 || EMAIL_REGEXP.hasMatch(value);
|
| }
|
| -
|
| - bool isValid(value) =>
|
| - value == null || value.isEmpty || EMAIL_REGEXP.hasMatch(value);
|
| }
|
|
|
| /**
|
| * Validates the model to see if its contents match a valid number.
|
| */
|
| @NgDirective(selector: 'input[type=number][ng-model]')
|
| -class NgModelNumberValidator implements NgValidatable {
|
| - String get name => 'number';
|
| +class NgModelNumberValidator extends _NgModelValidator {
|
| + get name => 'number';
|
|
|
| - NgModelNumberValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| - }
|
| + NgModelNumberValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
|
|
| - bool isValid(value) {
|
| - if (value != null) {
|
| + bool isValid() {
|
| + if(value != null) {
|
| try {
|
| num val = double.parse(value.toString());
|
| } catch(exception, stackTrace) {
|
| @@ -103,80 +140,96 @@
|
| * HTML pattern or ng-pattern attributes present on the input element.
|
| */
|
| @NgDirective(selector: '[ng-model][pattern]')
|
| -@NgDirective(
|
| - selector: '[ng-model][ng-pattern]',
|
| - map: const {'ng-pattern': '=>pattern'})
|
| -class NgModelPatternValidator implements NgValidatable {
|
| +@NgDirective(selector: '[ng-model][ng-pattern]', map: const {'ng-pattern': '=>pattern'})
|
| +class NgModelPatternValidator extends _NgModelValidator {
|
| RegExp _pattern;
|
|
|
| - String get name => 'pattern';
|
| + get name => 'pattern';
|
|
|
| - NgModelPatternValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| - }
|
| + NgModelPatternValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
|
|
| - bool isValid(value) {
|
| + bool isValid() {
|
| + if(_pattern != null && value != null && value.length > 0) {
|
| + return _pattern.hasMatch(ngModel.viewValue);
|
| + }
|
| +
|
| //remember, only required validates for the input being empty
|
| - return _pattern == null || value == null || value.length == 0 ||
|
| - _pattern.hasMatch(value);
|
| + return true;
|
| }
|
|
|
| @NgAttr('pattern')
|
| - set pattern(val) =>
|
| - _pattern = val != null && val.length > 0 ? new RegExp(val) : null;
|
| + get pattern => _pattern;
|
| + set pattern(val) {
|
| + if(val != null && val.length > 0) {
|
| + _pattern = new RegExp(val);
|
| + listen();
|
| + } else {
|
| + _pattern = null;
|
| + unlisten();
|
| + }
|
| + }
|
| }
|
|
|
| /**
|
| - * Validates the model to see if the length of its contents are greater than or
|
| - * equal to the minimum length set in place by the HTML minlength or
|
| - * ng-minlength attributes present on the input element.
|
| + * Validates the model to see if the length of its contents are greater than or equal to the minimum length
|
| + * set in place by the HTML minlength or ng-minlength attributes present on the input element.
|
| */
|
| @NgDirective(selector: '[ng-model][minlength]')
|
| -@NgDirective(
|
| - selector: '[ng-model][ng-minlength]',
|
| - map: const {'ng-minlength': '=>minlength'})
|
| -class NgModelMinLengthValidator implements NgValidatable {
|
| +@NgDirective(selector: '[ng-model][ng-minlength]', map: const {'ng-minlength': '=>minlength'})
|
| +class NgModelMinLengthValidator extends _NgModelValidator {
|
| int _minlength;
|
|
|
| - String get name => 'minlength';
|
| + get name => 'minlength';
|
|
|
| - NgModelMinLengthValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| - }
|
| + NgModelMinLengthValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
|
|
| - bool isValid(value) {
|
| + bool isValid() {
|
| //remember, only required validates for the input being empty
|
| - return _minlength == 0 || value == null || value.length == 0 ||
|
| - value.length >= _minlength;
|
| + if(_minlength == 0 || value == null || value.length == 0) {
|
| + return true;
|
| + }
|
| + return value.length >= _minlength;
|
| }
|
|
|
| @NgAttr('minlength')
|
| - set minlength(value) =>
|
| - _minlength = value == null ? 0 : int.parse(value.toString());
|
| + get minlength => _minlength;
|
| + set minlength(value) {
|
| + _minlength = value == null ? 0 : int.parse(value.toString());
|
| + }
|
| }
|
|
|
| /**
|
| - * Validates the model to see if the length of its contents are less than or
|
| - * equal to the maximum length set in place by the HTML maxlength or
|
| - * ng-maxlength attributes present on the input element.
|
| + * Validates the model to see if the length of its contents are less than or equal to the maximum length
|
| + * set in place by the HTML maxlength or ng-maxlength attributes present on the input element.
|
| */
|
| @NgDirective(selector: '[ng-model][maxlength]')
|
| -@NgDirective(
|
| - selector: '[ng-model][ng-maxlength]',
|
| - map: const {'ng-maxlength': '=>maxlength'})
|
| -class NgModelMaxLengthValidator implements NgValidatable {
|
| +@NgDirective(selector: '[ng-model][ng-maxlength]', map: const {'ng-maxlength': '=>maxlength'})
|
| +class NgModelMaxLengthValidator extends _NgModelValidator {
|
| int _maxlength = 0;
|
|
|
| - String get name => 'maxlength';
|
| + get name => 'maxlength';
|
|
|
| - NgModelMaxLengthValidator(NgModel ngModel) {
|
| - ngModel.addValidator(this);
|
| + NgModelMaxLengthValidator(dom.Element inputElement, NgModel ngModel, Scope scope):
|
| + super(inputElement, ngModel, scope) {
|
| + listen();
|
| + }
|
| +
|
| + bool isValid() {
|
| + return _maxlength == 0 || (value == null ? 0 : value.length) <= _maxlength;
|
| }
|
|
|
| - bool isValid(value) =>
|
| - _maxlength == 0 || (value == null ? 0 : value.length) <= _maxlength;
|
| -
|
| @NgAttr('maxlength')
|
| - set maxlength(value) =>
|
| - _maxlength = value == null ? 0 : int.parse(value.toString());
|
| + get maxlength => _maxlength;
|
| + set maxlength(value) {
|
| + int length = value == null ? 0 : int.parse(value.toString());
|
| + if(length != maxlength) {
|
| + _maxlength = length;
|
| + }
|
| + }
|
| }
|
|
|