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.
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'sChecked
property should be based on some underlying data field value, theChecked
property can be set either declaratively (such as,<asp:CheckBox runat="server" ... Checked='<%# Eval("ColumnName") %>' ... />
) or programmatically (such as in theRowDataBound
event handler).
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.)
|
The files in the current directory are accessed and bound to the GridView in the Page_Load
event handler, using
the following code:
|
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
|
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:
|
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
|
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:
|
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
ID
s 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
|
This code will add JavaScript to the page that looks similar to the following:
<script type="text/javascript">
|
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 (usingdocument.getElementById(id)
) and sets itschecked
property to the value of checkedStateChangeAllCheckBoxStates(checkState)
- iterates through theCheckBoxIDs
array and, for each element, callsChangeCheckBoxState
, passing in the client-side ID value for the currentCheckBoxIDs
element along with the checkState value
<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">
|
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!
Attachments
Further Reading