From 6fd9cff6189854cc0b14c72998462f945228cf01 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Wed, 22 Jan 2014 22:30:20 -0500 Subject: [PATCH] fix(input): use ValidityState to determine validity In browsers where HTML5 constraint validation is (partially) implemented, an invalid number entered into an input[type=number] (for example) input element would be visible to the script context as the empty string. When the required or ngRequired attributes are not used, this results in the invalid state of the input being ignored and considered valid. To address this, a validator which considers the state of the HTML5 ValidityState object is used when available. Closes #4293 Closes #2144 Closes #4857 Closes #5120 Closes #4945 Closes #5500 --- src/ng/directive/input.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 53a8ddd4d70a..b63d6b0290aa 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -404,7 +404,28 @@ function validate(ctrl, validatorName, validity, value){ return validity ? value : undefined; } + +function validateHtml5(ctrl, validatorName, element) { + var v = element.prop('validity'); + if (v && typeof v === 'object') { + var validator = function(value) { + // Don't overwrite previous validation, don't consider valueMissing to apply (ng-required can + // perform the required validation) + if (!ctrl.$error[validatorName] && (v.badInput || v.customError || v.typeMismatch) && + !v.valueMissing) { + ctrl.$setValidity(validatorName, false); + return undefined; + } + return value; + }; + ctrl.$parsers.push(validator); + ctrl.$formatters.push(validator); + } +} + function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + var validity = element.prop('validity'); + validity = typeof validity === 'object' && validity; // In composition mode, users are still inputing intermediate text buffer, // hold the listener until composition is done. // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent @@ -431,7 +452,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { value = trim(value); } - if (ctrl.$viewValue !== value) { + if (ctrl.$viewValue !== value || (validity && !value && !validity.valueMissing)) { if (scope.$$phase) { ctrl.$setViewValue(value); } else { @@ -551,6 +572,8 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }); + validateHtml5(ctrl, 'number', element); + ctrl.$formatters.push(function(value) { return ctrl.$isEmpty(value) ? '' : '' + value; });