Update (July 28, 2010):
I have fixed a minor bug in this script to ensure compatibility with webforms2, part of a suite of scripts that implement cross-browser compatibility with the HTML5 forms specification.
I have been following the progression of the HTML5 Forms standard with great interest. It promises a whole slew of new visual and usability goodness to existing HTML forms (e.g. slider and calendar widgets), a client-side validation framework, and so much more. One of the things I was disappointed with, though, was that HTML5 cannot hide and show form elements depending on what the user has input into the form so far. To give a very simple example of what I am talking about, select a country of origin in the form below:
In HTML5, there is no way for a developer to tell the browser “only show me this block of HTML if
<form> <table class="formTable"> <tr> <th>Country of Origin</th> <td><select name="country"> <option value=""> Select One... </option> <option value="Canada"> Canada </option> <option value="United States"> United States </option> </select> </td> </tr> <tr class="visibleIf" data-visibleif-rule="country == 'Canada'"> <th>Postal Code</th> <td><input type="text" name="postalCode" value="" /> </td> </tr> <tr class="visibleIf" data-visibleif-rule="country == 'United States'"> <th>Zip Code</th> <td><input type="text" name="zipCode" value="" /> </td> </tr> </table> </form>
This example is rather simple: the Postal Code form field is shown when
country == 'Canada' and Zip Code is shown when
country == 'United States'. Note that in order to hide and show a block of HTML, you must set two attributes inside the containing tag:
class="visibleIf": which lets the visibleIf.js script know that this block of HTML is to be hidden or shown according to the
data-visibleif-rule='rule expression': which contains the visibility rule. The rule variables are form element names, like
countryis in the above example. You can do simple equality rules like this, or complex ones like:
<div class="visibleIf" data-visibleif-rule="country == 'Canada' && (city == 'Toronto' || city == 'Vancouver')"> ... </div>
<div class="visibleIf" data-visibleif-rule="parseInt(total) > 100"> ... </div>
Note that the above examples have visibleIf rules inside a
tr tag, they can be used in any tag inside an HTML form.
Although the above example is quite simple, you can use visibleIf to make really complex forms — you can even put visibleIf blocks inside of visibleIf blocks. To illustrate this I have created a more interesting form that shows what can be done using visibleIf.
Hidden Fields – To Clear Or Not To Clear
If the user does something that hides some form fields (e.g. clicks on a checkbox) and then reverses that action (in this case clicking on the same checkbox), the fields will reappear with any previously filled-in data erased. Developers can override this default behavior by setting the class of the fields that shouldn’t be erased to
visibleIf-doNotReset. To illustrate this, I have created a page with two identical forms on it — one that erases the values inside hidden fields, and one that doesn’t. Play with the example and you’ll see what I mean.
Hidden Fields – Submit To The Server, Or Not?
Also note that by default, only the visible form elements are submitted to the server (this is because when a form element is hidden by
disabled attribute is set to
true when the form is submitted). If developers wants to override this behavior, they can simply set the form’s
The Quick “How-To” Guide”
Setting up your existing forms to use visibleIf is a quick, three-step process:
- Download the source from the visibleIf Project Page
- Use the visibleIf rules as seen in the example above. Note that
A Note On The Use Of Custom Data Attributes
Why did I bother with custom data attributes when making
visibleIf? Why did I just use the attribute
data-visibleif-rule instead of just
visibleif-rule or just
rule to place the visibility rule? Wouldn’t that be simpler?
data-attributes are HTML compliant: . Their use ensure that
visibleIfwill be compatible with future versions of HTML since
data-rulecould be used by another library. Using the name of the library in the attribute significantly reduces that possibility.