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. You can see the whole thing in action here.

3 thoughts on “jQuery: checkboxes that remember their original state

  1. You could have added an extra class ‘checked’ in the html, or else on page load add the class dynamically?

    I’ve have found jQuery data real useful when you have two scripts that have different scopes and need access to the same object, but that object is not globally defined.

  2. Yep definitely another class is an alternative — actually that would probably be better because then you could get rid of the on load event handler that populates the originallyChecked data.

Comments are closed.