Skip to content

Commit 5b804a6

Browse files
committed
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 angular#4293 Closes angular#2144 Closes angular#4857 Closes angular#5120 Closes angular#4945 Closes angular#5500
1 parent e020916 commit 5b804a6

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/ng/directive/input.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,28 @@ function validate(ctrl, validatorName, validity, value){
404404
return validity ? value : undefined;
405405
}
406406

407+
408+
function validateHtml5(ctrl, validatorName, element) {
409+
var v = element.prop('validity');
410+
if (v && isObject(v)) {
411+
var validator = function(value) {
412+
// Don't overwrite previous validation, don't consider valueMissing to apply (ng-required can
413+
// perform the required validation)
414+
if (!ctrl.$error[validatorName] && (v.badInput || v.customError || v.typeMismatch) &&
415+
!v.valueMissing) {
416+
ctrl.$setValidity(validatorName, false);
417+
return undefined;
418+
}
419+
return value;
420+
};
421+
ctrl.$parsers.push(validator);
422+
ctrl.$formatters.push(validator);
423+
}
424+
}
425+
407426
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
427+
var validity = element.prop('validity');
428+
validity = isObject(validity) && validity;
408429
// In composition mode, users are still inputing intermediate text buffer,
409430
// hold the listener until composition is done.
410431
// 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) {
431452
value = trim(value);
432453
}
433454

434-
if (ctrl.$viewValue !== value) {
455+
if (ctrl.$viewValue !== value || (validity && !value && !validity.valueMissing)) {
435456
if (scope.$$phase) {
436457
ctrl.$setViewValue(value);
437458
} else {
@@ -551,6 +572,8 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
551572
}
552573
});
553574

575+
validateHtml5(ctrl, 'number', element);
576+
554577
ctrl.$formatters.push(function(value) {
555578
return ctrl.$isEmpty(value) ? '' : '' + value;
556579
});

0 commit comments

Comments
 (0)