jQuery: checkboxes that remember their original state

Last week I had to write a little javascript for a form that involved a long list of check boxes. To save time, the application only processes rows where the checkbox value actually changed away from its original state.

For example, if a checkbox was checked to begin with, then the user unchecks it then re-checks it, we don’t have to do anything because although it did change, it ended up back at the same original state.

This is pretty easy to achieve by remembering the original state of the checkbox using jQuery data — library methods for storing arbitrary javascript objects in DOM elements — then comparing against the original value when toggled.

<script type="text/javascript">        $(document).ready(function() {                // Set aside the original state of each checkbox.                $("input.toggle").each(function() {                        $(this).data("originallyChecked", $(this).is(":checked"));                });                                // Check whether it really changed on click.                $("input.toggle").change(function() {                        var action = $(this).siblings("span");                        if ($(this).data("originallyChecked") == $(this).is(":checked"))                                action.text("(no change)");                        else                                action.text($(this).is(":checked") ? "added" : "removed");                });        });</script><ol>        <li>Apple <input type="checkbox" class="toggle" /> <span/></li>        <li>Banana <input type="checkbox" class="toggle" checked /> <span/></li>        <li>Carrot <input type="checkbox" class="toggle" /> <span/></li>        <li>Zucchini <input type="checkbox" class="toggle" checked /> <span/></li></ol>

The next requirement was adding a select/deselect all button. This proved a little bit more difficult, because of the way jQuery deals with events and the checked attribute. To cut a long story short, I ended up with an event handler that manually sets the checked attribute and then fires the change event on all the checkboxes (I tried the click event first, but it didn’t seem to pick up the new state).

$(document).ready(function() {        $("input#select-all").click(function() {                $("input.toggle").attr('checked', this.checked);                $("input.toggle").change();        });});

Altogether, it works very nicely in only a few lines of javascript.