In so many occasions I have had a use for a grid-based checkbox selector. I’m sure you’ve all seen them, you select the checkbox at the top of the grid, and all children checkboxes are either checked or unchecked, depending on the parent’s state.
I recently had a project where this functionality was going to be very effective, so I decided to write it up for you.
Let’s say we have the following HTML form.
Some kind of name
Mickey Mouse
Donald Duck
Elmer Fudd
It’s quite a simple form. Just a table of cells wrapped in a form.
We’ll also throw in there a span that we will use to show the user how many items are selected (just in case they can’t count).
Now this is just the client-side code for the page. In a practical example, there would be server-side code that retrieves data from some kind of data source and fills the table. The server-side code could even set the checked state of the checkbox for us. Great, less work for us to do.
Let’s see what the Javascript will look like.
Firstly, we will need to trap the click event on the checkbox. At that time, we will check if the checkbox is currently checked or not, and do some of stuff based on it’s state.
$(“input[name=ItemKey]”).click( function() {
if ( $(this).is(“:checked”) ){
// update all table cells in the current row with a class to indicate selection
// these could probably be chained.. let me know if you can do this better $(this).parent().addClass(“selected”);
$(this).parent().siblings().addClass(“selected”);
} else {
// remove the class to stop showing the row is selected
$(this).parent().removeClass(“selected”).addClass(“plain”);
$(this).parent().siblings().removeClass(“selected”).addClass(“plain”);
}
// update the label indicator of total selected items
ChangeSelectedLabel();
});
// check if all or no checkboxes were set as checked by server-side script
SetToggleCheckBoxFromChildren();
So what’s happening here is that the click event is applying classes to cells to indicate to the user that the row is selected. To do this, we get the parent element of the selected checkbox. Then we get all of that element’s children (which should be the entire row) and set a class to those cells. You can put this class in a stylesheet and format it however you like. Similarly, if the checkbox is unchecked on the click event, we remove that class so all cells in the row go back to the default style. It completely depends on how you style your table. If the cells have no style in the default state, just remove the “selected” class ie don’t worry about applying the “plain” class. There is also a function call in there that will update the indicator label. Let’s look at that now.
function ChangeSelectedLabel() {
var count = $(“input[name=ItemKey]:checked”).length;
$(“#selectedCountLabel”).text(count + ” items selected”);
SetToggleCheckBoxFromChildren();
}
This function sets a variable for the total checked items. Be sure to indicate the checkbox name, just in case you have other checkboxes in your form because you don’t want your total figure calculated incorrectly. Then the “selectedCountLabel” span is updated with the desired text. Then we have a function call to the SetToggleCheckBoxFromChildren function. Let’s look at that one.
function SetToggleCheckBoxFromChildren() {
var TotalDeselectedItems = $(“input[name=ItemKey]:not(:checked)”).length;
if (TotalDeselectedItems == 0) {
$(“#selectallcheckboxes”).prop(“checked”, true);
} else {
$(“#selectallcheckboxes”).prop(“checked”, false);
}
}
Ok, so this function sets the state of the parent checkbox. You know, the one at the top of the table. It’s possible that when the server-side script fills the table that all checkboxes get checked. In this situation, we want the client-side script to set the parent checkbox to the “checked” state. If we don’t, then the selection toggle can get mixed up. You may have noticed that this function was called in the first script block too. This function finds out if there are any checkboxes that are not checked (remember, use our name to filter the scope). If there are not, check the parent checkbox.
I hope you found that useful.