Working with the HTML 5 Validation API
The HTML 5 validation API is designed to work without Javascript interception, only based on the markup that the browser sees. However, there are some entry points, where you can influence the course of the validation.
A typical flow without Javascript looks like this:
All the methods and properties described below are fully supported by Hyperform.
When you apply Hyperform to window
, their polyfills will be installed
globally for all input elements:
hyperform(window);
var element = document.createElement('input');
assert('willValidate' in element);
Checking, if an element will be validated at all
To check, if an element will be validated at all (or whether it will be skipped
for one reason or another), evaluate element.willValidate
.
if (element.willValidate) {
// this element is not disabled. On submit it
// will be checked for its validity state.
}
Marking an element as invalid
At any time you can mark an element as invalid by setting its validation message to a non-empty value:
element.setCustomValidity(message);
An element marked this way will respond to the :invalid
CSS pseudo-class and
will report message
to the user, when she tries to submit the containing
form. To mark the element as valid, again, set the message to the empty string:
element.setCustomValidity('');
You can query the currently set validation message (your own or the default
one of the browser) with element.validationMessage
.
Manually checking the validity and reporting to the user
Use checkValidity()
, if you are just interested in whether an element is
valid or not. Use reportValidity()
to also inform the user about the
validation result. Both will trigger an event named invalid
, if the element
in question is, well, invalid.
To query specific errors (like, if the user entered a value into a required
field), the validity
object provides corresponding properties:
// malformed input, e.g. an e-mail address w/o "@"
var element_has_malformed_data = element.validity.badInput;
// missing a pattern requirement:
var element_doesnt_match = element.validity.patternMismatch;
// missing required value:
var element_is_empty = element.validity.valueMissing;
//.. and so on.
// overall test, if all constraints are met:
var element_is_valid = element.validity.valid;
// or equivalent (but triggers the "invalid" event):
var element_is_valid = element.checkValidity();
// show a warning to the user, if the element is invalid (or remove said
// warning again if valid):
element.reportValidity();
Checking the whole form’s validity
The form
element, too, has the checkValidity()
and reportValidity()
methods. When called, they will loop through all form elements of the form
and check and report, respectively, the validity of each item.
// check all elements of the first form and report their state
document.forms[0].reportValidity();
Switching off the validation
When a form has an attribute novalidate
, the browser will skip validation
altogether for this form. You can control this feature in your code by
toggling form.noValidate
(with upper-case “V”).
form.noValidate = true;
// validation is switched off for this form
This is an all-or-nothing property, and you cannot control single input fields
apart from setting them in the disabled
state. (Read on to learn about
Hyperform’s solution to this.)
Things, that do not work well with the HTML 5 API
When you try to hook into the HTML 5 validation API, you will quite soon run into a wall that prevents you from implementing some of the most common validation patterns. This is where the high level API of Hyperform comes to rescue. Some common problems, that are not solvable with the methods above alone, include:
-
You cannot switch off the validation for single elements apart from setting the
disabled
attribute (or a handful of other comparably intrusive methods). If you want to allow a user to enter invalid data, you have to disable the validation for the whole form and reimplement everything yourself.(Why would you want to do this? Think of entering credit card numbers. The field should have a maximum input length of 19 digits. But good usability dictates, that we should allow users to paste numbers with spaces, dashes or trailing punctuation and sanitize the value as long a possible. This is not possible with a strict validation, that comes with
<input type="text" name="cc" pattern="[0-9]{8,19}" maxlength="19">
.)Hyperform respects a non-standard attribute
novalidate
on a per element base, so you can remove single input fields from the validation step. -
When a user tries to submit a form, the browser will run the validation before the
submit
event is fired. This is unfortunate, since there is no option to hook custom behavior into this step like calling custom and possibly costly validation routines on submit.Hyperform allows to register custom validator functions that are called during validation. It also triggers a cancellable
validate
event on the form, before the validation starts. -
Providing custom validation messages for the standard validations is non-trivial. You have to hook into the
invalid
event for each element, determine again, why exactly it is invalid, and then re-build the message before setting it withsetCustomValidity()
or rendering it yourself.Hyperform gives you full localization control as well as methods to adapt every element’s message per validation incident.
-
Detecting when a field becomes valid again is not part of the API.
Hyperform will trigger a
valid
event on each field, that complements theinvalid
event from the specification.
How all of these work in detail is described on the next page.
Next: Extra Hyperform Features – functionality added beyond standard HTML 5 validation.