Unobtrusive and accessible form input labeling with jQuery

It's common practice to skip the use of elements in simple forms. The most common example of this are site search forms. The following example uses a JavaScript event handler attribute to clear the input's value which also serves as the input's label.

This method is great for displaying simple forms in tight spaces, but accessibility suffers if you're not using label elements. The input's default label value is usually not restored if the input loses focus without being submitted.

jQuery makes it easy to maintain accessibility and graceful degradation with these types of forms. Let's start with an accessible form.

Search this site

Here's the CSS

fieldset {
  border: none;
  width: 300px;
}
#search_form input {
  display: inline;
}
#search_form input[type="text"] {
  width: 10em;
}
#search_form legend,
#search_form label {
  display: none;
}

And here's the jQuery script.

// Declare short form elements in this page
// Add as many form id's as you need to the array
var shortForms = new Array("#search_form");
// When the document's loaded, initialize short forms
$("document").ready(function() {
  handleShortFormEvent(shortForms);
});
  
/**
 * Handle initialization of all short forms
 *
 *  array shortForms Array of short form IDs
 */
function handleShortFormEvent(shortForms) {
  for (var i in shortForms) {
    shortFormInit(shortForms[i]);
  }
}
/**
 * Initialize a short form. Short forms may contain only one text input.
 *
 *  string formID The form's ID, including #
 */
function shortFormInit(formID) {
  // Get the input ID and it's label text
  var labelValue = $(formID + " input[type='text']:first").siblings("label").html();
  var inputID = "#" + $(formID + " input[type='text']:first").attr("id");
  // Set the input value equal to label text
  $(inputID).val(labelValue);
  // Attach event listeners to the input
  $(inputID).bind("focus blur", function(e){
    var eLabelVal = $(this).siblings("label").html();
    var eInputVal = $(this).val();
    // Empty input value if it equals it's label
    if (eLabelVal == eInputVal) {
      $(this).val("");
    // Reset the input value if it's empty
    } else if ($(this).val() == "") {
      $(this).val(eLabelVal);
    }
  });
}

Here's what's happening above.

  1. An array of the page's short form IDs is set.
  2. In jQuery style, when the document's ready, initialize the short forms with handleShortFormEvent().
  3. handleShortFormEvent() loops through the forms and passes each off to shortFormInit().
  4. shortFormInit() sets text input values equal to its label. Then it attaches an event listener to each input which:
    • clears the default input value when someone focuses on it
    • restores the default input value if nothing was entered
    • retains any user values entered

I kept the handleShortFormEvent() and shortFormInit() functions separate to allow for initilization for form's loaded into the DOM after page load. I'd handle these instances with the help of jQuery.listen or the jQuery Live Query plugin.

It shouldn't be too difficult to expand this to handle multi-input forms but I believe there are jQuery plugins out there that do this.

Check out a working example.

Share