diff --git a/src/AngularPublic.js b/src/AngularPublic.js index e97723ef946d..76bbf4a83ed8 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -45,6 +45,10 @@ ngChangeDirective, requiredDirective, requiredDirective, + minlengthDirective, + minlengthDirective, + maxlengthDirective, + maxlengthDirective, ngValueDirective, ngModelOptionsDirective, ngAttributeAliasDirectives, @@ -184,6 +188,10 @@ function publishExternalAPI(angular){ ngChange: ngChangeDirective, required: requiredDirective, ngRequired: requiredDirective, + ngMinlength: minlengthDirective, + minlength: minlengthDirective, + ngMaxlength: maxlengthDirective, + maxlength: maxlengthDirective, ngValue: ngValueDirective, ngModelOptions: ngModelOptionsDirective }). diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 086618640d00..17a9dd5a04a3 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1000,22 +1000,6 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { return ctrl.$isEmpty(value) || isUndefined(regexp) || regexp.test(value); }; } - - // min length validator - if (attr.ngMinlength) { - var minlength = int(attr.ngMinlength); - ctrl.$validators.minlength = function(value) { - return ctrl.$isEmpty(value) || value.length >= minlength; - }; - } - - // max length validator - if (attr.ngMaxlength) { - var maxlength = int(attr.ngMaxlength); - ctrl.$validators.maxlength = function(value) { - return ctrl.$isEmpty(value) || value.length <= maxlength; - }; - } } function weekParser(isoWeek) { @@ -2183,6 +2167,43 @@ var requiredDirective = function() { }; +var maxlengthDirective = function() { + return { + require: '?ngModel', + link: function(scope, elm, attr, ctrl) { + if (!ctrl) return; + + var maxlength = 0; + attr.$observe('maxlength', function(value) { + maxlength = int(value) || 0; + ctrl.$validate(); + }); + ctrl.$validators.maxlength = function(value) { + return ctrl.$isEmpty(value) || value.length <= maxlength; + }; + } + }; +}; + +var minlengthDirective = function() { + return { + require: '?ngModel', + link: function(scope, elm, attr, ctrl) { + if (!ctrl) return; + + var minlength = 0; + attr.$observe('minlength', function(value) { + minlength = int(value) || 0; + ctrl.$validate(); + }); + ctrl.$validators.minlength = function(value) { + return ctrl.$isEmpty(value) || value.length >= minlength; + }; + } + }; +}; + + /** * @ngdoc directive * @name ngList diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index c1978c6dfbec..0f08ee2c627f 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -1368,6 +1368,24 @@ describe('input', function() { expect(value).toBe(5); }); + + it('should observe the standard minlength attribute and register it as a validator on the model', function() { + compileInput(''); + scope.$apply(function() { + scope.min = 10; + }); + + changeInputValueTo('12345'); + expect(inputElm).toBeInvalid(); + expect(scope.form.input.$error.minlength).toBe(true); + + scope.$apply(function() { + scope.min = 5; + }); + + expect(inputElm).toBeValid(); + expect(scope.form.input.$error.minlength).not.toBe(true); + }); }); @@ -1396,6 +1414,24 @@ describe('input', function() { expect(value).toBe(10); }); + + it('should observe the standard maxlength attribute and register it as a validator on the model', function() { + compileInput(''); + scope.$apply(function() { + scope.max = 1; + }); + + changeInputValueTo('12345'); + expect(inputElm).toBeInvalid(); + expect(scope.form.input.$error.maxlength).toBe(true); + + scope.$apply(function() { + scope.max = 6; + }); + + expect(inputElm).toBeValid(); + expect(scope.form.input.$error.maxlength).not.toBe(true); + }); });