Monday, February 28, 2011

Check / Uncheck all check boxes in ASP.Net using jQuery

jQuery make our scripting(javascript) life simple. One of the powerful things with jQuery is its Selectors. In ASP.Net while displaying list of data using GridView, DataList, ListView or Repeater control, one of the frequently expected thing is the check all option which is expected to happen on the client side.

To achieve those two things need to be done.

Case 1 : Upon the click of the header check box (CheckAll), all the row check boxes' status need to be changed based on the header check box. Case 2 : Upon click of the row check boxes, header check box status need to be set as checked when all of the row check boxes are checked sand vice versa. Following are the sample code to achieve that.

Snippet 1

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CheckAllWithJQuery.aspx.cs" Inherits="CheckAllWithJQuery" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>CheckAll check boxes in DataList</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
    <script type="text/javascript">

        $(document).ready(function () {
            initiateCheckAllBinding();            
        });

        function initiateCheckAllBinding() {
            var headerCheckBox = $("input[id$='HeaderCheckBox']");
            var rowCheckBox = $("#StudentTable input[id*='RowItemCheckBox']");

            headerCheckBox.click(function (e) {                
                rowCheckBox.attr('checked', headerCheckBox.is(':checked'));
            });

            // To select CheckAll when all Item CheckBox is selected and 
            // to deselect CheckAll when an Item CheckBox is deselected.     
            rowCheckBox.click(function (e) {
                var rowCheckBoxSelected = $("#StudentTable input[id*='RowItemCheckBox']:checked");

                if (rowCheckBox.length == rowCheckBoxSelected.length) {
                    headerCheckBox.attr("checked", true);
                }
                else {
                    headerCheckBox.attr("checked", false);
                }
            });
            $("table[id$='StudentDataList'] input[id*='RowItemCheckBox']")
        }       
         
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Repeater ID="StudentRepeater" runat="server">
            <HeaderTemplate>
                <table border="1" cellpadding="5" cellspacing="0" id="StudentTable">
                    <tr>
                        <td>
                            <asp:CheckBox ID="HeaderCheckBox" runat="server" />
                        </td>
                        <td>
                            <b>Id</b>
                        </td>
                        <td>
                            <b>Name</b>
                        </td>
                    </tr>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                        <asp:CheckBox ID="RowItemCheckBox" runat="server" />
                    </td>
                    <td>
                        <asp:Literal ID="IdLiteral" runat="server" Text='<%# Eval("Id") %>'></asp:Literal>
                    </td>
                    <td>
                        <asp:Literal ID="NameLiteral" runat="server" Text='<%# Eval("Name") %>'></asp:Literal>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table>
            </FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

In the above snippet you find that I've used a repeater control which I've specified a template in such a way the final will output will be of a table structure with id "StudentTable". Also I've specified the header check box with id "HeaderCheckBox" and row check box with id "RowItemCheckBox".

In jQuery, in order to get the instance of the header check, I've used "Attribute Ends With Selector".
$("input[id$='HeaderCheckBox']")
Similarly for getting the instances of row check boxes, I've used "Descendant Selector", that is row item check box selector that is descendant of element with id as "StudentTable".
$("#StudentTable input[id*='RowItemCheckBox']")
This works fine for the above provided template. What need to be done if we have a GridView or DataList? Just we need to identify the html rendering of that control and tweek the selector matching that. To be more clear, in general, GridView and DataList will be rendered as html table by default. Think of a case that you have a DataList with id "StudentDataList", then you can modify the selector as
$("table[id$='StudentDataList'] input[id*='RowItemCheckBox']")
SUMMARY
To achieve Case 2, simply I'm evaluating based on the count of number of row check boxes with that of the number selected row check boxes.

REFERENCE
http://api.jquery.com/category/selectors/
http://www.devcurry.com/2009/08/check-uncheck-all-checkboxes-in-aspnet.html
 
Creative Commons License
This work by Tito is licensed under a Creative Commons Attribution 3.0 Unported License.