Ever been in a situation where you've needed to disable an entire group of <input /> elements? Perhaps a scenario where you have one radio button that controls its children (grouped elements) and another radio element that controls the other group? You're in for a treat!
I have constructed an
unobtrusive and idiot proof method for you to implement into your JavaScript library.
First there are two prerequisites.
- You'll need a copy of my getElementsByClass() function
- You'll also need a copy of Scott Andrew's addEvent() function
If you don't feel like reading up on Scott Andrew (or you already know what I'm talking about), then don't worry, I'll have a copy for you soon enough.
The Premise and idea behind 'Unobtrusiveness'
Basically, I wanted a way to be able to drop in an external js file, and let my xHTML take of the rest. The purpose, of course, is to add an
enhancement layer and not let my radio button groups rely on JavaScript. This you should know is a big no-no in usability culture.
My second goal was that it needed to be easy to implement. This, of course, requires more thought process in the beginning. I figure if I could explain this to my wife, then it's a hit. With that said, let's get started! :)
A typical Scenario
Let's take a look at the following xHTML.
<div class="toggleSection">
<div class="toggleGroup">
<label for="topCheck1">The Enabler</label>
<input id="topCheck1" type="radio" name="a" class="toggleEnable" checked="checked" />
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
</div>
<div class="toggleGroup">
<label for="topCheck2">The Enabler</label>
<input id="topCheck2" type="radio" name="a" class="toggleEnable" />
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
</div>
<div class="toggleGroup">
<label for="topCheck3">The Enabler</label>
<input id="topCheck3" type="radio" name="a" class="toggleEnable" />
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
<label><input type="checkbox" class="toggleField" /></label>
</div>
</div>
Pretty straight forward I should hope. Take careful note of the class names on each element. You will see that the entire section is nested with
<div class='toggleSection'> and each group is nested with
<div class='toggleGroup'>.
Upon further inspection, you'll also see that the 'enablers' (in this case, the radio buttons) have a class of 'toggleEnable' and each field inside (which are optional) have a class of 'toggleField'. With all this said, the function should take care of the rest based on this set up.
elementToggler.js and the bunch
Alright, let's break it down. Rather than posting the code on this page, I'll send you to the direct source to take a peak at a each externals js files:
Assuming
elementToggler interests you the most, you'll notice two functions. The first function that is called is
attachEnablers() which (in this case) attaches the
toggleSections() function to be fired upon the click event to the radio buttons. Then on page load, we run the
toggleSections() function to put the document in its correct state.
With all that said, you should already have a pretty good idea what we've set up here. Which leads me to believe you can figure out the rest just by playing with the demo.
See
Section Toggler in action!
Instructions
Just incase of a panic attack and you're ready to lose all patience on how to implement it. Follow these steps carefully (Don't worry - it's too easy to mess up)
- Separate your sections with div.toggleSection
- Separate your groups (within sections) with div.toggleGroup
- Create your element enablers with input.toggleEnable
- Add .toggleField to any element that wants to be part of the action inside your toggle groups
Special Notes
- Take careful notice on the use of the style property in the toggleSections function. I've fiddled and faddled to get this to work with className.replace() - which would obviously be preferable - but there were quite a few browser bugs (in both IE and Firefox) which there seems to be a memory leak. It simply would just stop working after about 5 to 10 clicks.
- There are instructions in the elementToggler.js file just incase my website is down (which makes it pointless of me even noting this)
- Hey McFly, say Hi to you Mom for me