diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
index db59a1c2e3e1..06b13dc57b8b 100644
--- a/src/ng/directive/input.js
+++ b/src/ng/directive/input.js
@@ -939,13 +939,12 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
// If a control is suffering from bad input, browsers discard its value, so it may be
// necessary to revalidate even if the control's value is the same empty value twice in
// a row.
- var revalidate = validity && ctrl.$$hasNativeValidators;
- if (ctrl.$viewValue !== value || (value === '' && revalidate)) {
+ if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
if (scope.$$phase) {
- ctrl.$setViewValue(value, event, revalidate);
+ ctrl.$setViewValue(value, event);
} else {
scope.$apply(function() {
- ctrl.$setViewValue(value, event, revalidate);
+ ctrl.$setViewValue(value, event);
});
}
}
@@ -1812,23 +1811,24 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
* event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
* usually handles calling this in response to input events.
*/
- this.$commitViewValue = function(revalidate) {
+ this.$commitViewValue = function() {
var viewValue = ctrl.$viewValue;
$timeout.cancel(pendingDebounce);
- if (!revalidate && ctrl.$$lastCommittedViewValue === viewValue) {
+ if (ctrl.$$lastCommittedViewValue !== viewValue) {
+ // change to dirty
+ if (ctrl.$pristine) {
+ ctrl.$dirty = true;
+ ctrl.$pristine = false;
+ $animate.removeClass($element, PRISTINE_CLASS);
+ $animate.addClass($element, DIRTY_CLASS);
+ parentForm.$setDirty();
+ }
+ } else if (viewValue !== '' || !ctrl.$$hasNativeValidators) {
return;
}
ctrl.$$lastCommittedViewValue = viewValue;
- // change to dirty
- if (ctrl.$pristine) {
- ctrl.$dirty = true;
- ctrl.$pristine = false;
- $animate.removeClass($element, PRISTINE_CLASS);
- $animate.addClass($element, DIRTY_CLASS);
- parentForm.$setDirty();
- }
var modelValue = viewValue;
forEach(ctrl.$parsers, function(fn) {
@@ -1881,14 +1881,14 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
* @param {string} value Value from the view.
* @param {string} trigger Event that triggered the update.
*/
- this.$setViewValue = function(value, trigger, revalidate) {
+ this.$setViewValue = function(value, trigger) {
ctrl.$viewValue = value;
if (!ctrl.$options || ctrl.$options.updateOnDefault) {
- ctrl.$$debounceViewValueCommit(trigger, revalidate);
+ ctrl.$$debounceViewValueCommit(trigger);
}
};
- this.$$debounceViewValueCommit = function(trigger, revalidate) {
+ this.$$debounceViewValueCommit = function(trigger) {
var debounceDelay = 0,
options = ctrl.$options,
debounce;
@@ -1907,10 +1907,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
$timeout.cancel(pendingDebounce);
if (debounceDelay) {
pendingDebounce = $timeout(function() {
- ctrl.$commitViewValue(revalidate);
+ ctrl.$commitViewValue();
}, debounceDelay);
} else {
- ctrl.$commitViewValue(revalidate);
+ ctrl.$commitViewValue();
}
};
diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js
index 9c9eca38c709..7b71f4b1d6c2 100644
--- a/test/ng/directive/inputSpec.js
+++ b/test/ng/directive/inputSpec.js
@@ -2228,6 +2228,18 @@ describe('input', function() {
expect(inputElm).toBeInvalid();
});
+ it('should invalidate number with ngModelOptions if suffering from bad input', function() {
+ compileInput('', {
+ valid: false,
+ badInput: true
+ });
+
+ changeInputValueTo('10a');
+ browserTrigger(inputElm, 'blur');
+ expect(scope.age).toBeUndefined();
+ expect(inputElm).toBeInvalid();
+ });
it('should validate number if transition from bad input to empty string', function() {
var validity = {
@@ -2243,6 +2255,22 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should validate when bad input number with ngModelOptions changes to empty', function() {
+ var validity = {
+ valid: false,
+ badInput: true
+ };
+ compileInput('', validity);
+ changeInputValueTo('10a');
+ browserTrigger(inputElm, 'blur');
+ validity.badInput = false;
+ validity.valid = true;
+ changeInputValueTo('');
+ browserTrigger(inputElm, 'blur');
+ expect(scope.age).toBeNull();
+ expect(inputElm).toBeValid();
+ });
describe('min', function() {