I found myself needing to implement a tri-state checkbox in javascript. A checkbox has initially 2 states: on or off. From the html perspective if the checkbox is checked then the value is submitted, if it is not then the value is not submitted. From the javascript perspective you can use:
if (checkbox.checked) { alert("This checkbox is checked"); }
Some times a true or false is not enough. Other development platforms have tri-state checkboxes that can have either a true, false or null value. The following snippet adds a “greyable” functionality to checkboxes:
Element.addMethods("INPUT", (function() { var changeHandler = function(e) { if (this.greyed || this.checked) { this.setGreyed(!this.greyed); if (!this.greyed) { this.checked = true; } } }; function setGreyed(checkbox, greyed) { checkbox.greyed = typeof greyed == "undefined" ? true : !!greyed; checkbox.setOpacity(checkbox.greyed ? 0.33 : 1); if (checkbox.greyed) { checkbox.checked = checkbox.greyedState; } } function setGreyable(element, enable) { if (!(element = $(element))) return; if (!(/checkbox|radiobutton/i.test(element.type))) { return; } if (typeof element.greyedState == "undefined" || enable) { element.observe("change", changeHandler); element.setGreyState(false); element.setGreyed(false); } else { element.stopObserving("change", changeHandler); element.setGreyed(false); element.checked = element.greyedState; element.greyedState = undefined; element.greyed = undefined; } } function setGreyState(element, greyedState) { if (!(element = $(element))) return; if (!(/checkbox|radiobutton/i.test(element.type))) { return; } element.greyedState = typeof greyedState == "undefined" ? true : !!greyedState; } return { setGreyed: setGreyed, setGreyable: setGreyable, setGreyState: setGreyState } })());
This currently requires prototypejs but could be easily modified to not depend on it. To enable it on some element do something like this:
checkbox.setGreyable();
To check if it is greyed or not:
if (checkbox.greyed) { alert("This checkbox is greyed"); }
You can also change the state of the checkbox when it is greyed. To set this use the following:
checkbox.setGreyState(true);
The parameter indicates whether the checkbox is checked when grey. Clicking on the checkbox (or changing the state by keyboard) loops through 3 states: checked, not checked and greyed.
Update: the HTML5 spec has something to say about this, it seems that is should be implemented (in a differente manner) on all html5 browsers: http://www.w3.org/TR/html5/forms.html#checkbox-state-(type=checkbox)