diff --git a/src/ng/directive/validators.js b/src/ng/directive/validators.js index 5c1649ecf74e..787a80a71ab7 100644 --- a/src/ng/directive/validators.js +++ b/src/ng/directive/validators.js @@ -68,15 +68,21 @@ var requiredDirective = ['$parse', function($parse) { require: '?ngModel', link: function(scope, elm, attr, ctrl) { if (!ctrl) return; - var value = attr.required || $parse(attr.ngRequired)(scope); + // For boolean attributes like required, presence means true + var value = attr.hasOwnProperty('required') || $parse(attr.ngRequired)(scope); - attr.required = true; // force truthy in case we are on non input element + if (!attr.ngRequired) { + // force truthy in case we are on non input element + // (input elements do this automatically for boolean attributes like required) + attr.required = true; + } ctrl.$validators.required = function(modelValue, viewValue) { return !value || !ctrl.$isEmpty(viewValue); }; attr.$observe('required', function(newVal) { + if (value !== newVal) { value = newVal; ctrl.$validate(); diff --git a/test/ng/directive/validatorsSpec.js b/test/ng/directive/validatorsSpec.js index a851b2fec95c..c7259c67c933 100644 --- a/test/ng/directive/validatorsSpec.js +++ b/test/ng/directive/validatorsSpec.js @@ -696,6 +696,13 @@ describe('validators', function() { })); + it('should override "required" when ng-required="false" is set', function() { + var inputElm = helper.compileInput(''); + + expect(inputElm).toBeValid(); + }); + + it('should validate only once after compilation when inside ngRepeat', function() { helper.compileInput( '
' + @@ -731,6 +738,7 @@ describe('validators', function() { expect(helper.validationCounter.required).toBe(1); }); + it('should validate once when inside ngRepeat, and set the "required" error when ngRequired is false by default', function() { $rootScope.isRequired = false; $rootScope.refs = {}; @@ -744,5 +752,15 @@ describe('validators', function() { expect($rootScope.refs.input.$error.required).toBeUndefined(); }); + + it('should validate only once when inside ngIf with required on non-input elements', inject(function($compile) { + $rootScope.value = '12'; + $rootScope.refs = {}; + helper.compileInput('
'); + $rootScope.$digest(); + + expect(helper.validationCounter.required).toBe(1); + expect($rootScope.refs.ctrl.$error.required).not.toBe(true); + })); }); });