HTML5 Form Validation
- by Stephen.Walther
The latest versions of Google Chrome (16+), Mozilla Firefox (8+), and Internet Explorer (10+) all support HTML5 client-side validation. It is time to take HTML5 validation seriously.
The purpose of the blog post is to describe how you can take advantage of HTML5 client-side validation regardless of the type of application that you are building. You learn how to use the HTML5 validation attributes, how to perform custom validation using the JavaScript validation constraint API, and how to simulate HTML5 validation on older browsers by taking advantage of a jQuery plugin. Finally, we discuss the security issues related to using client-side validation.
Using Client-Side Validation Attributes
The HTML5 specification discusses several attributes which you can use with INPUT elements to perform client-side validation including the required, pattern, min, max, step, and maxlength attributes.
For example, you use the required attribute to require a user to enter a value for an INPUT element. The following form demonstrates how you can make the firstName and lastName form fields required:
<!DOCTYPE html>
<html >
<head>
<title>Required Demo</title>
</head>
<body>
<form>
<label>
First Name:
<input required title="First Name is Required!" />
</label>
<label>
Last Name:
<input required title="Last Name is Required!" />
</label>
<button>Register</button>
</form>
</body>
</html>
If you attempt to submit this form without entering a value for firstName or lastName then you get the validation error message:
Notice that the value of the title attribute is used to display the validation error message “First Name is Required!”. The title attribute does not work this way with the current version of Firefox. If you want to display a custom validation error message with Firefox then you need to include an x-moz-errormessage attribute like this:
<input required title="First Name is Required!"
x-moz-errormessage="First Name is Required!" />
The pattern attribute enables you to validate the value of an INPUT element against a regular expression. For example, the following form includes a social security number field which includes a pattern attribute:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pattern</title>
</head>
<body>
<form>
<label>
Social Security Number:
<input required pattern="^d{3}-d{2}-d{4}$"
title="###-##-####" />
</label>
<button>Register</button>
</form>
</body>
</html>
The regular expression in the form above requires the social security number to match the pattern ###-##-####:
Notice that the input field includes both a pattern and a required validation attribute. If you don’t enter a value then the regular expression is never triggered. You need to include the required attribute to force a user to enter a value and cause the value to be validated against the regular expression.
Custom Validation
You can take advantage of the HTML5 constraint validation API to perform custom validation. You can perform any custom validation that you need. The only requirement is that you write a JavaScript function.
For example, when booking a hotel room, you might want to validate that the Arrival Date is in the future instead of the past:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Constraint Validation API</title>
</head>
<body>
<form>
<label>
Arrival Date:
<input id="arrivalDate" type="date" required />
</label>
<button>Submit Reservation</button>
</form>
<script type="text/javascript">
var arrivalDate = document.getElementById("arrivalDate");
arrivalDate.addEventListener("input", function() {
var value = new Date(arrivalDate.value);
if (value < new Date()) {
arrivalDate.setCustomValidity("Arrival date must be after now!");
} else {
arrivalDate.setCustomValidity("");
}
});
</script>
</body>
</html>
The form above contains an input field named arrivalDate. Entering a value into the arrivalDate field triggers the input event.
The JavaScript code adds an event listener for the input event and checks whether the date entered is greater than the current date. If validation fails then the validation error message “Arrival date must be after now!” is assigned to the arrivalDate input field by calling the setCustomValidity() method of the validation constraint API. Otherwise, the validation error message is cleared by calling setCustomValidity() with an empty string.
HTML5 Validation and Older Browsers
But what about older browsers? For example, what about Apple Safari and versions of Microsoft Internet Explorer older than Internet Explorer 10?
What the world really needs is a jQuery plugin which provides backwards compatibility for the HTML5 validation attributes. If a browser supports the HTML5 validation attributes then the plugin would do nothing. Otherwise, the plugin would add support for the attributes.
Unfortunately, as far as I know, this plugin does not exist. I have not been able to find any plugin which supports both the required and pattern attributes for older browsers, but does not get in the way of these attributes in the case of newer browsers.
There are several jQuery plugins which provide partial support for the HTML5 validation attributes including:
· jQuery Validation — http://docs.jquery.com/Plugins/Validation
· html5Form — http://www.matiasmancini.com.ar/jquery-plugin-ajax-form-validation-html5.html
· h5Validate — http://ericleads.com/h5validate/
The jQuery Validation plugin – the most popular JavaScript validation library – supports the HTML5 required attribute, but it does not support the HTML5 pattern attribute. Likewise, the html5Form plugin does not support the pattern attribute.
The h5Validate plugin provides the best support for the HTML5 validation attributes. The following page illustrates how this plugin supports both the required and pattern attributes:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>h5Validate</title>
<style type="text/css">
.validationError {
border: solid 2px red;
}
.validationValid {
border: solid 2px green;
}
</style>
</head>
<body>
<form id="customerForm">
<label>
First Name:
<input id="firstName" required />
</label>
<label>
Social Security Number:
<input id="ssn" required pattern="^d{3}-d{2}-d{4}$"
title="Expected pattern is ###-##-####" />
</label>
<input type="submit" />
</form>
<script type="text/javascript" src="Scripts/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.h5validate.js"></script>
<script type="text/javascript">
// Enable h5Validate plugin
$("#customerForm").h5Validate({
errorClass: "validationError",
validClass: "validationValid"
});
// Prevent form submission when errors
$("#customerForm").submit(function (evt) {
if ($("#customerForm").h5Validate("allValid") === false) {
evt.preventDefault();
}
});
</script>
</body>
</html>
When an input field fails validation, the validationError CSS class is applied to the field and the field appears with a red border. When an input field passes validation, the validationValid CSS class is applied to the field and the field appears with a green border.
From the perspective of HTML5 validation, the h5Validate plugin is the best of the plugins. It adds support for the required and pattern attributes to browsers which do not natively support these attributes such as IE9. However, this plugin does not include everything in my wish list for a perfect HTML5 validation plugin.
Here’s my wish list for the perfect back compat HTML5 validation plugin:
1. The plugin would disable itself when used with a browser which natively supports HTML5 validation attributes. The plugin should not be too greedy – it should not handle validation when a browser could do the work itself.
2. The plugin should simulate the same user interface for displaying validation error messages as the user interface displayed by browsers which natively support HTML5 validation. Chrome, Firefox, and Internet Explorer all display validation errors in a popup. The perfect plugin would also display a popup.
3. Finally, the plugin would add support for the setCustomValidity() method and the other methods of the HTML5 validation constraint API. That way, you could implement custom validation in a standards compatible way and you would know that it worked across all browsers both old and new.
Security
It would be irresponsible of me to end this blog post without mentioning the issue of security. It is important to remember that any client-side validation — including HTML5 validation — can be bypassed.
You should use client-side validation with the intention to create a better user experience. Client validation is great for providing a user with immediate feedback when the user is in the process of completing a form. However, client-side validation cannot prevent an evil hacker from submitting unexpected form data to your web server.
You should always enforce your validation rules on the server. The only way to ensure that a required field has a value is to verify that the required field has a value on the server. The HTML5 required attribute does not guarantee anything.
Summary
The goal of this blog post was to describe the support for validation contained in the HTML5 standard. You learned how to use both the required and the pattern attributes in an HTML5 form. We also discussed how you can implement custom validation by taking advantage of the setCustomValidity() method.
Finally, I discussed the available jQuery plugins for adding support for the HTM5 validation attributes to older browsers. Unfortunately, I am unaware of any jQuery plugin which provides a perfect solution to the problem of backwards compatibility.