Toggle.js: unobtrusivly show and hide elements with effects

Today I would like to announce the release of Toggle.js – a LowPro and Prototype-based solution for unobtrusively toggling elements with effects. Toggle.js makes it easy to create an advanced section on a form that slides out when the “Advanced” link is clicked, or to show more options when a certain check box is checked. And it does all of this with beautiful effects (complements of script.aculo.us).

View the online demo.

The way Toggle.js works is you select an element to be the “Trigger” element that will cause another another element revealed. You can chose a link, a checkbox, a select box, or a group of radio buttons as your trigger. You then add a rel attribute to the element that identifies an ID or group of IDs for the elements that should be revealed.

Using a Link as a Trigger

For example, the following code will create an advanced section that will only be revealed when the “Advanced” link is clicked:

<p><a class="toggle" href="#advanced" rel="toggle[advanced]">Advanced</a></p>
<div id="advanced">
... advanced options here ...
</div>

Note that I’ve set the rel attribute to “toggle[advanced]”. This is a special syntax that identifies the list of IDs that should be toggled when the trigger is clicked. (IDs appear between the brackets. To toggle multiple IDs separate them with commas.) In this case we are telling Toggle.js that the “Advanced” link is a trigger for the “advanced” div. By convention, toggle triggers are also identified with the “toggle” class (this is configurable). Also note that Toggle.js will take care of hiding the “advanced” div when the page loads.

A Checkbox Trigger

To create a checkbox toggle trigger, the syntax is almost identical:

<p>
  <input type="checkbox" class="toggle" name="remind" id="remind" value="1" rel="toggle[remind_on]" />
  <label for="remind">Remind me</label>
  <span id="remind_on">on <input type="text" name="date" /></span>
</p>

In the example above, if the user checks the “Remind me” checkbox a date field will appear where they can enter a date for the reminder. Toggle.js is smart enough to recognize whether the checkbox is checked on page load and will hide or show the related element as needed.

Selects and Options

The code necessary to make this work with a select box is a little different. Instead of setting the rel attribute on the select box, you should set it on each of the options:

<select class="toggle">
  <option>- none -</option>
  <option value="1" rel="toggle[one]">One</option>
  <option value="2" rel="toggle[two]">Two</option>
  <option value="1,2" rel="toggle[one,two]">One and Two</option>
</select>

<div id="one">1</div>
<div id="two">2</div>

In this example, the select box is used to toggle the visibility of divs “one” and “two”, based on selection. Note that the last option, “One and Two”, displays both divs by specifying both IDs in the rel attribute.

Radio Buttons

The fourth and final way that you can use Toggle.js, is with a group of radio buttons. The code is actually strikingly similar to the code used for the select boxes:

<div class="radio_group toggle">
  <p>
    <input type="radio" name="numbers" id="numbers_none"/>
    <label for="numbers_none">None</label>
  </p>
  <p>
    <input type="radio" name="numbers" id="numbers_one" value="1" rel="toggle[one]" />
    <label for="numbers_one">One</label>
  </p>
  <p>
    <input type="radio" name="numbers" id="numbers_two" value="2" rel="toggle[two]" />
    <label for="numbers_two">Two</label>
  </p>
  <p>
    <input type="radio" name="numbers" id="numbers_three" value="1,2" rel="toggle[one,two]" />
    <label for="numbers_three">One and Two</label>
  </p>
</div>

<div id="one">1</div>
<div id="two">2</div>

The Wiring

Apart from the standard script tags for LowPro and Prototype, you will also need to wire in the appropriate LowPro behaviors. If you are building a Rails application, I’d recommend that you put this in “application.js”:

Event.addBehavior({
  'a.toggle': Toggle.LinkBehavior(),
  'input[type=checkbox].toggle': Toggle.CheckboxBehavior(),
  'div.radio_group.toggle': Toggle.RadioGroupBehavior(),
  'select.toggle': Toggle.SelectBehavior()
});

What this code does is associate the LowPro behaviors with the correct elements based on CSS selectors. You can customize the rules above if you want to use different class names or if you would like to tweak the behaviors with custom options.

For example, you can create an inverted toggle checbox by adding the following line to the Event.addBehavior call:

'a.inverted_toggle': Toggle.LinkBehavior({inverted: true}),

An inverted toggle link would hide the associated div the first time it was clicked instead of showing it.

You can also customize the effect used and handle custom before and after toggle events for the Toggle.LinkBehavior. For full details on the different options that you can pass the LowPro behaviors, consult the inline documentation.

There are also two configuration variables that can be used to customize the default settings for all toggle behaviors:

Toggle.DefaultEffect = 'appear';    # a string; the default is 'slide'
Toggle.DefaultEffectDuration = 0.5; # in seconds; the default is 0.25

Conclusion

Toggle.js removes the need to write custom code to toggle the visibility of other elements for many of the common use cases. And it does all of this in a clean unobtrusive way. You can learn more about Toggle.js, over at the GitHub project or view the online demo here.

Before closing, I’d like to thank the kind folks at MemberHub who sponsored the initial development of Toggle.js and have allowed me to release it as open source. MemberHub is a group communications platform for churches and other organizations.

© 2013 John W. Long