Accessible forms using jQuery's Validation plug-in

There has been a lot of talk on our blog recently regarding forms. We have looked at rules for displaying error messages, creating accessible forms and would you have guessed, I’m now going to talk about implementing accessible form errors! Well, it makes a change from all of those HTML5 and CSS3 posts that are flooding my daily feeds of late. A screenshot of the demo form page with error messages. Anyway, this short post looks at how we can begin to deliver a better experience for our users when it comes to displaying form errors. As jQuery is my preferred library of choice and the Validation plug-in provides an excellent starting point, we will use them both to form the basis of this article. Out of the box the jQuery Validation plug-in provides some reasonable defaults, however because of the vast options available in the plug-in, a developer can use it for great good or great evil. Following these tips, we are able to improve the accessibility of the plugins out-of-the-box defaults, which ultimately provides a better experience for our users. I will start by making a few assumptions at this point:

  1. You have read Three rules for creating accessible forms and understand how to create accessible forms;
  2. You have a server-side validation method. It ensures there is a fallback for that minority who do not have JavaScript available, and stops hackers who can turn off JavaScript to avoid validation;
  3. You have downloaded the relevant jQuery and jQuery Validation plug-in files.

A simple form

First we need our form mark-up to be clean and tidy. Something like this perhaps:

<form action="#" id="formDemo">
    <fieldset>
      <legend>Your Details></legend>
        <div>
            <label for="f0">First Name</label> <input class="required" id="f0" name="f0" type="text" />
        </div>
        <div>
            <label for="f1">Last Name</label> <input class="required" id="f1" name="f1" type="text" />
        </div>
        <div>
            <label for="f2">Telephone Number</label> <input class="required" id="f2" name="f2" type="text" />
        </div>
        <div>
            <label for="f3">Email Address</label> <input class="required" id="f3" name="f3" type="text" />
        </div>
    </fieldset>
    <div>
        <input type="submit" value="Submit" />
    </div>
</form>

Setup the jQuery validation function

Our next step is to call the jQuery Validation function. There are several ways you can do this, but for the sake of this article I want to keep it clean and simple. Thus I will call the jQuery Validation plug-in from within my own function (accValidate):

$(document).ready(function() {
    /*Initialise the validation function */
    $('#formDemo').accValidate();
});
jQuery.fn.accValidate = function(){

    var form = this;

    //The jQuery validation plug-in in action
    $(form).validate({

    //Optional, but for demo purpose we only want to validate on submitting the form
    onfocusout: false,
    onkeyup: false,
    onclick: false,

    //We are going to focus on the first link in the error list so i have disabled
    //the input error focus option in jQuery Validation
focusInvalid: false,
    …

The excellent jQuery Validation plug-in allows us to configure how and when the validation script is run. For the purpose of our demo, we will disable the onfocus, onkeyup and onclick validation options. We only want it to validate on submission of the form. Next the plug-in allows us to define the element to use for the error messages and their location:

    …
    //Set the element which will wraps the inline error messages
errorElement: "strong",

    //Location for the inline error messages
    //In this case we will place them in the associated label element
    errorPlacement: function(error, element) {
    error.appendTo($('label[for="' + $(element).attr('id') + '"]', form));
    },
    …

We will display a simple inline error message for each input as part of the associated label. Why here you ask? Well it will depend on the situation and the input type in question (there are always some exceptions), but in this case it works well for screen readers that typically read out the associated label text (and therefore the error message) when the input field receives focus.

Creating the error summary

So far our jQuery Validation plug-in has done an excellent job! But now we are going to head off the beaten track slightly and create the error summary with the help of some of the functionality available within the plug-in:

    …
    //Create our error summary that will appear before the form
    showErrors: function(errorMap, errorList) {
    if (submitted && errorList) {

        var $errorFormId = 'errors-' + form.attr('id')

        //Reset and remove error messages if the form
        //has been validated once already
        summary = "";
        $('label .error', form).remove();

        //Create our container if one doesnt already exits
        //better than an empty div being in the HTML source
        if($('#' + $errorFormId).length == 0) {
            $('<div id="' + $errorFormId + '"/>').insertBefore(form);
        }

        //Generate our error summary list
        for (error in errorList) {
            //get associated label text to be used for the error summary
            var $errorLabel = $('label[for="' + $(errorList[error].element).attr('id') + '"]').text();
            summary += '<li><a href="#' + errorList[error].element.id + '">' + $errorLabel + ': ' + errorList[error].message + '</a></li>';
            }

            //Output our error summary and place it in the error container
            $('#' + $errorFormId).html('<h2>Errors found in the form</h2><p><em>Whoops!</em> - There is a problem with the form, please check and correct the following:</p><ul>' + summary + '</ul>');

            //Focus on first error link in the error container
            //Alternatively, you might want to use the Validation default option (focusInvalid)
            $('#' + $errorFormId + ' a:eq(0)').focus();

            //Move the focus to the associated input when error message link is triggered
            //a simple href anchor link doesnt seem to place focus inside the input
            $('#' + $errorFormId + ' a').click(function() {
            $($(this).attr('href')).focus();
            return false;
        });
    }
    this.defaultShowErrors();
    submitted = false;
    },
    invalidHandler: function(form, validator){
        submitted = true;
    }
    …

This creates our error summary, based on the errors found in the form, and inserts it before the form being validated. It clearly lists all errors and, as an added bit of functionality, provides anchor links allowing the user to easily skip to input fields that have an error. You might also notice that we place the focus on the first link in the error summary when the form is submitted. This approach has undergone a fair amount of discussion and testing, the result of which lead us to believe that this approach worked well for users addressing errors in the form. There we have it. You can checkout the demo here to see the form validation in action. The jQuery Validation plug-in offers many useful features, for example we haven’t even looked at custom error messages or checkbox validation. But this should give you an idea of how we can start to deliver accessible error messages using a plug-in like jQuery Validation. Have a different plug-in or library of choice for validating forms? Why not share it here...

Add a comment

Fields marked with an asterisk (*) are mandatory.