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);
+ });
});