When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, May 24, 2006

Checking All CheckBoxes in a GridView

By Scott Mitchell


An Updated Version Is Available!
In December 2010 I updated the code and concepts presented in this article to use unobtrusive JavaScript and the jQuery library. To learn more, read Checking All Checkboxes in a GridView Using jQuery.

Introduction


A common website user interface pattern is a list of items with a checkbox in each row. The archetypical example is the web-based email client, which allows a series of messages to be selected by checking that email's checkbox. Once one or more emails have been selected, the user can apply some group action on those selected messages, such as deleting them, marking them read, or moving them to a different folder. In addition to having the ability to check each record, one at a time, many such user interfaces also provide a "check all" checkbox in the header row. This checkbox, if checked or unchecked, automatically checks or unchecks all items in the list below.

Creating such a user interface with ASP.NET 2.0's GridView control is quite possible, and is the focus of this article. In particular, we'll look at how to enable "Check All"/"Uncheck All" functionality both using server-side code and client-side script. The server-side option is much simpler to implement, but suffers from requiring a postback when opting to check or uncheck all checkboxes. The client-side approach, on the other hand, offers a snappier and sleeker user interface, but does require a bit more effort to implement correctly.

- continued -

Building the Foundation: Creating a GridView with a CheckBox in Each Row


Before we examine how, exactly, to provide functionality to check or uncheck each checkbox in a GridView, let's first concentrate on building a GridView control that possesses a CheckBox for each row. A column of CheckBoxes can be added to the GridView using one of two approaches:
  • Using the CheckBoxField - the CheckBoxField is a built-in GridView field type that renders a column of CheckBoxes with each CheckBox's Checked property assigned to some data field in the grid's underlying data source.
  • Using a TemplateField - we can add a TemplateField and then, in the ItemTemplate, add a CheckBox Web control. If the CheckBox Web control's Checked property should be based on some underlying data field value, the Checked property can be set either declaratively (such as, <asp:CheckBox runat="server" ... Checked='<%# Eval("ColumnName") %>' ... />) or programmatically (such as in the RowDataBound event handler).
The second option - using a TemplateField - has a number of advantages. First, it's more customizable. With minimal effort we can include additional markup in each row and can provide a custom header, even. In fact, the code download at the end of this article includes an example with a CheckBox in this column's header, which the user can check or uncheck all CheckBoxes in the GridView; for more information see Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox. Moreover, if the CheckBox's Checked property is not dependent on some underlying data field, then you'll need to use the TemplateField option. In this article we will use the TemplateField option.

For this article, imagine that we wanted to build some web-based file management tool. In particular, this interface will list the files in the current directory, along with a CheckBox for each file. After the GridView, we'll add a "Delete All Checked Files" Button that, when clicked, will delete those files from the file system whose CheckBox has been checked. (The live demo available at the end of this article doesn't actually delete the files; rather, it just prints a message indicating what files it would have deleted, had that functionality been implemented.)

The following GridView accomplished the needed functionality. Note that it uses a TemplateField to house a CheckBox control for each GridView row. (Some of the GridView's formatting-related settings have been removed for brevity.)

<asp:GridView ID="FileList" runat="server"
    AutoGenerateColumns="False" DataKeyNames="FullName">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox runat="server" ID="RowLevelCheckBox" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Name" HeaderText="Name" />
        <asp:BoundField DataField="CreationTime" HeaderText="Created On">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:BoundField DataField="Length" DataFormatString="{0:N0}"
                     HeaderText="File Size"
            HtmlEncode="False">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
    </Columns>
</asp:GridView>

The files in the current directory are accessed and bound to the GridView in the Page_Load event handler, using the following code:

Protected Sub Page_Load(ByVal sender As Object, _
                        ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        Dim dirInfo As New DirectoryInfo(Request.PhysicalApplicationPath)

        FileList.DataSource = dirInfo.GetFiles()
        FileList.DataBind()
    End If
End Sub

For more information on accessing and displaying the files in a directory, see Displaying the Files in a Directory Using a DataGrid...

Next, we need a "Delete All Checked Files" Button that, when clicked, determines what CheckBoxes have been checked and deletes those files. The following Click event handler for that Button iterates through the GridView's Rows collection and, for each GridViewRow instance, determines whether or not the CheckBox RowLevelCheckBox has been checked. If it has, the event handler concatenates the file path to a Label Web control (Summary). (In practice, it would use the File.Delete(path) method in the System.IO namespace to actually delete the file.)

Protected Sub DeleteButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DeleteButton.Click
   Summary.Text = "The following file would have been deleted:<ul>"

   Dim currentRowsFilePath As String

   'Enumerate the GridViewRows
   For index As Integer = 0 To FileList.Rows.Count - 1
      'Programmatically access the CheckBox from the TemplateField
      Dim cb As CheckBox = CType(FileList.Rows(index).FindControl("RowLevelCheckBox"), CheckBox)

      'If it's checked, delete it...
      If cb.Checked Then
         currentRowsFilePath = FileList.DataKeys(index).Value
         Summary.Text &= String.Concat("<li>", currentRowsFilePath, "</li>")
      End If
   Next


   Summary.Text &= "</ul>"
End Sub

Note how the CheckBox is programmatically referenced from the TemplateField - FileList.Rows(index).FindControl("controlID"). Had we used a CheckBoxField, the syntax would have instead been FileList.Rows(index).Cells(0).Controls(0). The Cells(0) would have accessed the first column in the specified row (this assumes that the CheckBoxField was the first field in the GridView) and Control(0) references that column's first control in its Controls collection, which, for the CheckBoxField, is its CheckBox control.

Now that we have the groundwork laid out, we're ready to examine how to implement functionality to check and uncheck all CheckBoxes in the GridView. Let's first look at how to provide this functionality using server-side code.

Providing "Check All" and "Uncheck All" Functionality Using Server-Side Code


To provide "Check All" and "Uncheck All" functionality I added to Button Web controls above the GridView:

<p>
   <asp:Button ID="CheckAll" runat="server" Text="Check All" />
   &nbsp;
   <asp:Button ID="UncheckAll" runat="server" Text="Uncheck All" />
</p>

Next, I created Click event handlers for both of these Buttons, in which I enumerate the GridView's Rows collection and, for each GridViewRow instance, access the CheckBox and set its Checked property accordingly:

Protected Sub CheckAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckAll.Click
   'Enumerate each GridViewRow
   For Each gvr As GridViewRow In FileList.Rows
      'Programmatically access the CheckBox from the TemplateField
      Dim cb As CheckBox = CType(gvr.FindControl("RowLevelCheckBox"), CheckBox)

      'Check it!
      cb.Checked = True
   Next

End Sub

Protected Sub UncheckAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles UncheckAll.Click
   'Enumerate each GridViewRow
   For Each gvr As GridViewRow In FileList.Rows
      'Programmatically access the CheckBox from the TemplateField
      Dim cb As CheckBox = CType(gvr.FindControl("RowLevelCheckBox"), CheckBox)

      'Uncheck it!
      cb.Checked = False
   Next

End Sub

That's all there is to it! The only issue with the server-side approach is that clicking the "Check All" or "Uncheck All" checkboxes results in a postback, which adds overhead, a screen flash, and so on. While such behavior may be unnoticeable in an intranet scenario, Internet sites typically strive to provide a better user experience through the use of client-side script. Such functionality can be achieved, but requires a bit more effort. Before we turn our attention to the client-side scripting functionality, take a moment to check out the screen shot of the server-side approach in action. Note that clicking the "Check All" or "Uncheck All" Buttons will appropriately check or uncheck all of the CheckBoxes in the GridView; the following screen shot shows the grid right after the "Check All" Button has been clicked.

Providing "Check All" and "Uncheck All" Functionality with Client-Side Script


In order to provide a snappier user experience, ideally the "Check All" and "Uncheck All" would check or uncheck all of the CheckBoxes on the client-side without causing a postback. The CheckBoxes in the GridView can be accessed through client-side JavaScript using the following pattern:

// Get a reference to the CheckBox
var cb = document.getElementById('checkBoxID');

// Adjust the checked state
cb.Checked = false;  // or whatever...

Here, checkBoxID is the client-side ID of the rendered CheckBox control. This is not necessarily the same as the value of the ID property of the CheckBox Web control. Instead, the client-side ID is prepended with the IDs of the CheckBox Web control's parent controls. In order to work with the CheckBoxes in client-side script we need to create a client-side Array of the client-side IDs of the GridView CheckBoxes.

ASP.NET 2.0 provides a number of methods in the ClientScriptManager class, which can be accessed directly from an ASP.NET page using the ClientScript property. This class has the same client-script-related methods found in the Page class in ASP.NET 1.x, along with some additional methods. One such method (available both in 1.x and 2.0) is RegisterArrayDeclaration(arrayName, arrayValue), which creates a client-side Array with elements specified by the arrayValue input parameter. (To add multiple elements to a single array, call RegisterArrayDeclaration(arrayName, arrayValue) multiple times, passing in the same arrayName value.)

The following code enumerates the GridView's Rows collection and, for each GridViewRow instance, programmatically accesses the CheckBox and stores its client-side ID (accessible via the ClientID property) in a client-side Array (ClientSideIDs).

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   If Not Page.IsPostBack Then
      Dim dirInfo As New DirectoryInfo(Request.PhysicalApplicationPath)

      FileList.DataSource = dirInfo.GetFiles()
      FileList.DataBind()
   End If

   'On every page visit we need to build up the CheckBoxIDs array
   For Each gvr As GridViewRow In FileList.Rows
      'Get a programmatic reference to the CheckBox control
      Dim cb As CheckBox = CType(gvr.FindControl("RowLevelCheckBox"), CheckBox)

      ClientScript.RegisterArrayDeclaration("CheckBoxIDs", String.Concat("'", cb.ClientID, "'"))
   Next

End Sub

This code will add JavaScript to the page that looks similar to the following:

<script type="text/javascript">
<!--

var CheckBoxIDs = new Array('<i>CheckBoxID1</i>','<i>CheckBoxID2</i>', ...,'<i>CheckBoxIDN</i>');


// -->
</script>

This code needs to be placed in the Page_Load event handler and executed on every page visit because these types of client-side injected arrays are not persisted across postbacks. If we only create this client-side Array on the first page visit (or whenever the GridView is data bound), upon postback - such as when clicking the "Delete All Checked Files" Button Web control - the subsequent page load will not include the CheckBoxIDs client-side Array, thereby rendering the "Check All" and "Uncheck All" functionality impotent.

For more information on working with client-side script from server-side code, be sure to read Working With Client-Side Script...

Armed with this array of client-side IDs, we can write a client-side JavaScript function that enumerates this array's elements and, for each element, references the checkbox and sets its checked property accordingly. I've created two functions to accomplish this:

  • ChangeCheckBoxState(id, checkState) - references the specified checkbox (using document.getElementById(id)) and sets its checked property to the value of checkedState
  • ChangeAllCheckBoxStates(checkState) - iterates through the CheckBoxIDs array and, for each element, calls ChangeCheckBoxState, passing in the client-side ID value for the current CheckBoxIDs element along with the checkState value
I then created two <input type="button" ... /> buttons - "Check All" and "Uncheck All" - and configured their client-side onclick event such that it invoked ChangeAllCheckBoxStates, passing in the appropriate value for checkState.

<script type="text/javascript">
   function ChangeCheckBoxState(id, checkState)
   {
      var cb = document.getElementById(id);
      if (cb != null)
         cb.checked = checkState;
   }

   function ChangeAllCheckBoxStates(checkState)
   {
      // Toggles through all of the checkboxes defined in the CheckBoxIDs array
      // and updates their value to the checkState input parameter
      if (CheckBoxIDs != null)
      {
         for (var i = 0; i < CheckBoxIDs.length; i++)
            ChangeCheckBoxState(CheckBoxIDs[i], checkState);
      }
   }
</script>

...

<p>
   <input type="button" value="Check All" onclick="ChangeAllCheckBoxStates(true);" />
   &nbsp;
   <input type="button" value="Uncheck All" onclick="ChangeAllCheckBoxStates(false);" />
</p>

With these changes added, the "Check All" and "Uncheck All" buttons perform their task completely on the client-side, thereby providing a snappier user experience. The download available at the end of this article includes an additional example that illustrates how to augment the client-side example to include a checkbox in the header of the column of checkboxes that, if checked or unchecked, checks or unchecks all of the checkboxes in the grid. A more thorough examination of this extra example can be found at Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox!

Conclusion


In this article we examined two ways to check (or uncheck) all CheckBoxes within a GridView control. This can be accomplished most easily using server-side code, but at the expense of a postback. A client-side approach offers a snappier user experience, but requires a bit more code and some JavaScript functions as well.

Happy Programming!

  • By Scott Mitchell


    Attachments


  • Download the code used in this article

    Further Reading


  • Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox
  • Checking All Checkboxes in a GridView Using jQuery



  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article