Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 validation: JavaScript weirdness with willValidate

OK this is a weird one. I'm sure I'm missing something obvious.

http://jsfiddle.net/wVp8j/

HTML:

<form>
    <input type='text' required />
    <button>check field validity</button>
</form>

JS:

var field = document.querySelector('input[type=text]');
document.querySelector('button').addEventListener('click', function() {
    alert('Validates: '+field.willValidate);
    alert('Value missing: '+field.validity.valueMissing);
}, false);

If the form is submitted with the field left blank, submission is suppressed, as you'd expect, but the first alert, checking the field's validity state, gives true. Why?

To contradict this further, the second alert confirms there's a problem with the field and also gives true, as expected.

What am I missing?

[Sidenote: MDN seems to think willValidate is a method, not a property.]

[EDIT]

As the commenter below points out, willValidate says whether the field is a candidate for validation, not, despite its misleading name, whether the field will validate.

Which presumably means the only means of telling whether a field will validate, should the form be submitted, via JS, is to iterate over its validity object and see if any flag is set to true.

[EDIT 2]

Turns out you can just check validity.valid on a field, even though the valid flag doesn't show up if you console.log the entire validity object. This would appear to be the way, therefore, to find out whether a field will hypothetically validate.

like image 978
Mitya Avatar asked Jul 14 '14 21:07

Mitya


2 Answers

willValidate is a property that says whether or not an input can be validated, not if it is valid or not. The only time that willValidate is false is if the input element is disabled or the like.

See http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-willValidate

Use field.validity.valid instead to check for validity.

http://jsfiddle.net/3xFua/

(function() {
    var field = document.querySelector('input[type=text]');
    document.querySelector('button').addEventListener('click', function() {
        console.log('Validates: ', field.validity.valid);
        console.log('Value missing: ', field.validity.valueMissing);
    }, false);
})();
like image 110
soktinpk Avatar answered Nov 19 '22 10:11

soktinpk


The documentation suggests using .checkValidity() which

Method Description

checkValidity() Returns true if the element's value has no validity problems; false otherwise. If the element is invalid, this method also causes an invalid event at the element.

while (as @soktinpk's answer correctly states) .willValidate simply flags it as available for validation, not passing validation.

Thus I recommend using this:

function() {
    alert('Validates: '+field.checkValidation());
    alert('Value missing: '+field.validity.valueMissing);
}

off-topic, alert is a terrible debugging tool. Consider using console.log or debugger;

like image 23
blgt Avatar answered Nov 19 '22 12:11

blgt