Usable forms

Usable Forms is one of the eight example scripts in the book.

There's a bug that prevents the script from working with multiple selects. (Single selects work fine, though).

If you reload this page you'll notice that Mozilla checks the radio button above the one that was checked before the reload. This is in fact a browser bug, and not a bug in my script.

Clicking on the labels doesn't work in Safari.

I have heard, but did not test, that if you hide the submit button and reinsert it into the form later on, it does not work in Firefox.

On this page I present my the Usable Forms script. This script is meant to show and hide form fields based on user actions, and thus to significantly increase the usability of large and complicated forms.
I explain the whys and wherefores of this script in great detail in my May 2003 Digital Web Magazine article Forms, usability, and the W3C DOM.

The article discusses version 1.0, but I advise you to download a newer version.

Example

The script adds and removes form fields based on user actions. Try the form below.

Other than The Netherlands
Marital status


Yes

Downloads

There are three versions available; I explain the exact differences below on this page:

  1. Version 2.0. If you don't know the script, use this version.
  2. Version 1.5. The same as 2.0, except that it's backwards compatible with version 1.0
  3. Version 1.0. The original version discussed in my article. I advise you to use one of the newer versions; this one is only maintained for historical reasons.

This is the only script on my site that contains a copyright notice, because it's more special and ground-breaking than any of my other scripts. You may do whatever you like with it, as long as this copyright notice remains intact. If you extend the script, please also extend the notice to explain what you've done.

Instructions for version 2.0

To use Usable Forms, do the following:

Step 1: Download the script

Download the script. Include it in any page you want to use it in:

<script type="text/javascript" src="/correct/path/usableforms.js"></script>

Step 2: Create the form

Create the form while following these guidelines:
Any form field/label combo that should be hidden, should reside in a container tag, most likely a tr or a div. It's this container tag that will be shown or hidden when the user takes action. Of course all container tags should be the same HTML element: the script searches through these container tags for the rel attributes I explain below.

Example with trs as container tag:

<tr>
	<td class="question"><label for="country_other">Country</label></td>
	<td>
		<input type="checkbox" name="country_other" id="country_other" rel="other_country" />
			Other than The Netherlands
	</td>
</tr>
<tr rel="other_country">
	<td class="question"><label for="other_country">
		<span class="accessibility">If not the Netherlands:</span> Which other country?</label></td>
	<td><input name="other_country" id="other_country" /></td>
</tr>
<tr>
	<td class="question">Marital status</td>
	<td>
		<input type="radio" name="marital" value="single" rel="none" id="marital_single" />
			<label for="marital_single">Single</label><br />
		<input type="radio" name="marital" value="married" rel="marriageContract" id="marital_married" />
			<label for="marital_married">Married</label><br />
		<input type="radio" name="marital" value="divorced" rel="divorceDetails" id="marital_divorced" />
			<label for="marital_divorced">Divorced</label><br />
	</td>
</tr>
<tr rel="marriageContract">
	<td class="question"><label for="marriage_contract">
		<span class="accessibility">If Married:</span> Marriage contract?</label></td>
	<td><input type="checkbox" name="marriage_contract" id="marriage_contract" /> Yes</td>
</tr>

Step 3: Define the container tag

In the first line of the script, enter the UPPER CASE tag name of the container tag. Only these tags will be shown and hidden by the script.

var containerTag = 'TR';

Step 4: Create the interaction

Decide which user actions should reveal which form fields. Now add rel attributes with the same values to the form fields and to the container tags that should be revealed when the user selects/checks this form field.

Example:

<input type="checkbox" rel="other_country" name="country_other" id="country_other" />
	Other than The Netherlands

<tr rel="other_country">
	<td class="question"><label for="other_country">
		<span class="accessibility">If not the Netherlands:</span> Which other country?</label></td>
	<td><input name="other_country" id="other_country" /></td>
</tr>

Step 5: Related radios and options

When you add rel attributes to radio buttons or options, give all other radios or options in the same group a rel="none". Although they shouldn't show any new form fields, any form fields related to another radio or option should be hidden when the user clicks on them, and the script needs a rel attribute to trigger that behaviour.

Example:

<input type="radio" name="marital" value="single" rel="none" id="marital_single" />
	<label for="marital_single">Single</label><br />
<input type="radio" name="marital" value="married" rel="marriageContract" id="marital_married" />
	<label for="marital_married">Married</label><br />
<input type="radio" name="marital" value="divorced" rel="divorceDetails" id="marital_divorced" />
	<label for="marital_divorced">Divorced</label><br />

Step 6: Accessibility

Users without (sufficient) JavaScript will see the entire form, including any fields that you'd prefer to hide. These users will probably need an extra bit of guidance in the form of help texts. You can add elements with class="accessibility" to your form. If the script works, these elements are automatically hidden. Thus you can create extra texts that are only visible to noscript users.

Example:

<label for="other_country"><span class="accessibility">If not the Netherlands:</span>
	Which other country?</label>

Version notes

Version 1.0 was the original script I wrote in May 2003. In November 2005 I updated the script, and I created two new versions, 1.5 and 2.0 . The only difference is that 1.5 is completely backward compatible, and 2.0 isn't. Below the differences are summarized.

Versions 1.0 and 1.5 vs. version 2.0

Version 1.0 and 1.5 Version 2.0
Searches for show attributes on form fields. Searches for rel attributes on form fields.
Searches for relation attributes on container tags. Searches for rel attributes on container tags.

Version 1.0 vs. versions 1.5 and 2.0

Version 1.0 Version 1.5 and 2.0

Needs an HTML "waiting room" structure.

Waiting room no longer needed. The hidden form fields are stored in a JavaScript array.

Does not work when the user clicks on a label.

Works when the user clicks on a label.

Hidden elements revealed with one form action always appear at the place the first element was included in the HTML.

Hidden elements revealed with one form action appear at the place they themselves were included in the HTML.

Explorer bug: relation names may not be the same as names of a form field.

Bug solved.

change events defined on selects by the form creator were overwritten.

change events are no longer touched.

Stores hidden form fields in an HTML waiting room. The hidden fields are still in the document.

Stores hidden form fields in a div element that's not attached to the main document. The hidden fields "float in hyperspace".

Repeatedly loops through all container tags.

Loops through the container tags only once.