Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit c2d447e

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 #4293 Closes #2144 Closes #4857 Closes #5120 Closes #4945 Closes #5500 Closes #5944
1 parent 7551585 commit c2d447e

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

src/ng/directive/input.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,27 @@ function validate(ctrl, validatorName, validity, value){
435435
return validity ? value : undefined;
436436
}
437437

438+
439+
function addNativeHtml5Validators(ctrl, validatorName, element) {
440+
var validity = element.prop('validity');
441+
if (isObject(validity)) {
442+
var validator = function(value) {
443+
// Don't overwrite previous validation, don't consider valueMissing to apply (ng-required can
444+
// perform the required validation)
445+
if (!ctrl.$error[validatorName] && (validity.badInput || validity.customError ||
446+
validity.typeMismatch) && !validity.valueMissing) {
447+
ctrl.$setValidity(validatorName, false);
448+
return;
449+
}
450+
return value;
451+
};
452+
ctrl.$parsers.push(validator);
453+
ctrl.$formatters.push(validator);
454+
}
455+
}
456+
438457
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
458+
var validity = element.prop('validity');
439459
// In composition mode, users are still inputing intermediate text buffer,
440460
// hold the listener until composition is done.
441461
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
@@ -463,7 +483,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
463483
value = trim(value);
464484
}
465485

466-
if (ctrl.$viewValue !== value) {
486+
if (ctrl.$viewValue !== value ||
487+
// If the value is still empty/falsy, and there is no `required` error, run validators
488+
// again. This enables HTML5 constraint validation errors to affect Angular validation
489+
// even when the first character entered causes an error.
490+
(validity && value === '' && !validity.valueMissing)) {
467491
if (scope.$$phase) {
468492
ctrl.$setViewValue(value);
469493
} else {
@@ -583,6 +607,8 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
583607
}
584608
});
585609

610+
addNativeHtml5Validators(ctrl, 'number', element);
611+
586612
ctrl.$formatters.push(function(value) {
587613
return ctrl.$isEmpty(value) ? '' : '' + value;
588614
});

0 commit comments

Comments
 (0)