GridView with Select All CheckBox using JQuery

by mosessaur| 25 March 2008| 16 Comments

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]

I've seen several implementation for this feature long time ago. Myself wrote one. And all solutions were using some good amount of JavaScript. Today I was thinking, why not revisit the idea again, but this time using all mighty JQuery.

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:
GridView With CheckBoxes

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:

   1: <tr>
   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" />
   8:     </th>
   9: </tr>

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()
   2: {
   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);
   6:     
   7:     //02 Bind onclick event to items checkbox 'item select'.
   8:     $('#<%=gvProducts.ClientID %> >tbody >tr >td >input:checkbox').click(checkSelectAll);
   9: }

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)
   2: {
   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);
   5: }
   6: function checkSelectAll(e)
   7: {
   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';
  11:     
  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);
  15: }

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.

 

kick it on DotNetKicks.com

Comments (16) -

Josh Stodola
Josh Stodola United States on 3/16/2008 3:57 AM Very nicely done - good job!
mosessaur
mosessaur Egypt on 3/16/2008 4:06 AM thank you Josh for cheering comment
Dave
Dave United States on 3/19/2008 6:40 AM Gotta love jQuery.
mosessaur
mosessaur Egypt on 3/20/2008 6:49 PM Yeah, isn't it amazing framework ;)?
Richard
Richard United Kingdom on 4/10/2008 11:57 PM Nicely done. Small suggestion: using the demo, there is no indication that a request is waiting for a response. If there was a small animated loading gif to tell me that something was happening, I wouldn't have been confused about why it wasn't working for me ;)
mosessaur
mosessaur Egypt on 4/11/2008 12:08 AM Thank you Richard, yes you are right, maybe because I'm lazy and didn't add that to the demos, I'll do that in the upcoming posts and will try to update old ones.
Mauro
Mauro Brazil on 5/5/2008 3:06 PM Good job! - Very nicely done
Marc
Marc United States on 5/24/2008 11:27 AM Is there anyway to handle the Select All and the GridView Paging? Right now the Select All functionality only handles the current page being viewed.
mosessaur
mosessaur Egypt on 5/25/2008 1:50 PM Well, That was was how it supposed to be. Even in hotmail or yahoo, when you go to next page, you reset all items to be unselected. However I'm sure there is a way to implement your requirements, but I never tried it.
Bolsa de Trabajo
Bolsa de Trabajo Mexico on 6/7/2008 2:48 PM Interesting.
cc
cc People's Republic of China on 7/18/2008 6:41 PM I like it
kamal
kamal Indonesia on 10/27/2008 7:37 PM nice article...
jai
jai United States on 11/22/2008 9:19 PM very nice
justin
justin United States on 4/20/2009 2:42 PM why not just do this:

$(document).ready(function(){  

$("#chkPagesSelectAll").click(function()
        {
            $("#<%=gridName.ClientID%> input:checkbox").attr("checked",$('#chkPagesSelectAll').is(':checked'));
        });
}

where chkPagesSelectAll is the checkbox in your header
mosessaur
mosessaur Egypt on 4/21/2009 11:56 PM @justin The reason is what if there are another column in the gird that contains inputs of type checkbox?! my target here is to show that using jQuery selectors you can archive your target even in complex scenarios.
But of course I think you way should work too.
Patrick
Patrick Australia on 5/6/2009 7:50 AM Hi Muhammad,
         Nice article but how to get the selected values in JQUERY?
I want these values as i want to delete/update items in the list.
Tha...in advance

Pingbacks and trackbacks (2)+

Comments are closed