From 77ce5b89f97aa83c3eb1fe2e19375ef00a822015 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 24 Jun 2014 09:13:59 -0400 Subject: [PATCH] fix(input): validate minlength/maxlength for non-string values Use the viewValue rather than modelValue when validating. The viewValue should always be a string, and should reflect what the user has entered, or the formatted model value. BREAKING CHANGE: Always uses the viewValue when validating minlength and maxlength. Closes #7967 Closes #8811 --- src/ng/directive/input.js | 8 +-- test/ng/directive/inputSpec.js | 91 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index a306c11e282a..3b208ca21abe 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -2473,8 +2473,8 @@ var maxlengthDirective = function() { maxlength = int(value) || 0; ctrl.$validate(); }); - ctrl.$validators.maxlength = function(value) { - return ctrl.$isEmpty(value) || value.length <= maxlength; + ctrl.$validators.maxlength = function(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || viewValue.length <= maxlength; }; } }; @@ -2492,8 +2492,8 @@ var minlengthDirective = function() { minlength = int(value) || 0; ctrl.$validate(); }); - ctrl.$validators.minlength = function(value) { - return ctrl.$isEmpty(value) || value.length >= minlength; + ctrl.$validators.minlength = function(modelValue, viewValue) { + return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength; }; } }; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index eb5ed857ed0e..55ab01dc2c51 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2901,6 +2901,97 @@ describe('input', function() { expect(scope.form.alias.$error.required).toBeTruthy(); }); }); + + describe('minlength', function() { + + it('should invalidate values that are shorter than the given minlength', function() { + compileInput(''); + + changeInputValueTo('12'); + expect(inputElm).toBeInvalid(); + + changeInputValueTo('123'); + expect(inputElm).toBeValid(); + }); + + it('should listen on ng-minlength when minlength is observed', function() { + var value = 0; + compileInput(''); + attrs.$observe('minlength', function(v) { + value = int(attrs.minlength); + }); + + scope.$apply(function() { + scope.min = 5; + }); + + 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); + }); + }); + + + describe('maxlength', function() { + + it('should invalidate values that are longer than the given maxlength', function() { + compileInput(''); + + changeInputValueTo('12345678'); + expect(inputElm).toBeInvalid(); + + changeInputValueTo('123'); + expect(inputElm).toBeValid(); + }); + + it('should listen on ng-maxlength when maxlength is observed', function() { + var value = 0; + compileInput(''); + attrs.$observe('maxlength', function(v) { + value = int(attrs.maxlength); + }); + + scope.$apply(function() { + scope.max = 10; + }); + + 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); + }); + }); }); describe('email', function() {