One of the handy features that one might with to put on GridView is the Select All checkbox which is similar to the one on Hotmail and Yahoo. You click the checkbox on the header and all items (checkboxes underneath) get checked. [View Demo]
And as expected, the amount of code used to implement this simple feature is really small. I'm going to explore the JQuery code expecting you already know ASP.NET and how to use GridView along with SqlDataSource.
My GirdView looks exactly like this one:
CheckBoxes are rendered on the last column. I'm mentioning last column because I'm going to use that on JQuery. Also it worth to mention that this GridView will render the header columns like this:
2: <th align="left" scope="col">Category</th>
3: <th align="left" scope="col">Product</th>
4: <th align="right" scope="col">Unit Price</th>
5: <th align="left" scope="col">Supplier</th>
6: <th scope="col">
7: <input id="gvProducts_ctl01_chkSelectAll" type="checkbox" name="gvProducts$ctl01$chkSelectAll" />
Notice the "th" tag; again because I'll use this from JQuery. The rest of rows are rendered as normal "td" tags
As I am using AJAX Enabled Web Application, I have the option ASP.NET AJAX Client Events like onload event. I'm using this event to bind click event to each CheckBox on the GridView:
1: function pageLoad()
3: //Bind onclick event to each checkbox
4: //01 Bind onclick event to header checkbox 'Select All'.
5: $('#<%=gvProducts.ClientID %> >tbody >tr >th:last >input:checkbox').click(selectAll);
7: //02 Bind onclick event to items checkbox 'item select'.
8: $('#<%=gvProducts.ClientID %> >tbody >tr >td >input:checkbox').click(checkSelectAll);
When review the code, you'll notice I'm using JQuery Hierarchy Selector "parent > child" along with Forms Selector ":checkbox" to retrieve checkboxes and bind onclick event to them. To reach the header CheckBox (Select All) I used this expression '#<%=gvProducts.ClientID %> >tbody >tr >th:last >input:checkbox'. I'm focusing on the last th tag as you might notice. The ':last' filter used to match the last selected element which is the last column. and 'input:checkbox' Forms filter matchs all input elements that are checkboxes. In case of header column it is only one. And in case of item rows they are many so it will match all of them and bind same event handler to their onclick event.
Now I'll explore the event handlers 'selectAll' function and 'checkSelectAll' function. 'selectAll' function is attached only to the header CheckBox. On the other hand checkSelectAll funtion is attached to all other CheckBoxes. The code below shows both handlers:
1: function selectAll(e)
3: //Set checked status of all checkboxes to be the same as Select All checkbox checked status.
4: $('#<%=gvProducts.ClientID %> >tbody >tr >td >input:checkbox').attr('checked',this.checked);
6: function checkSelectAll(e)
8: //Idea: total rows with checkboxes vs total checked checkboxes will decide if the Select All checkbox should be checked or not.
9: var expr1 = '#<%=gvProducts.ClientID %> >tbody >tr >td >input:checkbox:checked';
10: var expr2 = '#<%=gvProducts.ClientID %> >tbody >tr >td >input:checkbox';
12: //If total rows with checkboxed is equal to total checked checkboxes then Select All checkbox should be checked.
13: var selectAll = $(expr1).length == $(expr2).length;
14: $('#<%=gvProducts.ClientID %> >tbody >tr >th:last >input:checkbox').attr('checked',selectAll);
selectAll function is very simple, it just gets all checkboxed on the last column -except the header itself- and set its checked state to be as the Select All CheckBox checked state.
checkSelectAll function use a simple trick which comparing total rows with CheckBoxes -except the header row- with total CheckBoxes checked -except the header row CheckBox-. So If total rows with CheckBoxes are equal to total checked CheckBoxes then Select All CheckBox on header row should be checked otherwise it should be unchecked.
You can download the code [47.79 kb] and preview the demo to observe the behavior of the CheckBoxes.
I hope this post would be of use to anyone.