Friday, December 30, 2005

"SelectAll" CheckBox for DataGrid Web Control in ASP.NET

Goal: Assuming you have already added a checkbox column to
the DataGrid web control using TemplateColumn. Now you want to add a
checkbox in the header of this column to select/clear all the
checkboxes in the column.

Solution: besides adding the select all check box to the
DataGrid, you will only need 3 JavaScript functions and 2 lines of
code to accomplish this.

1. Add a CheckBox to the HeaderTemplate of the checkbox column.
Set the name to:

the name of ItemTemplate + "SelectAll";

2. In the code-behind, "Page_Load" function add this:

string scriptString = "<script language='javascript'>\n" +
"<!-- Hide script from old browsers.\n" +
"bindSelectAllCheckBox(" +
"'CheckBoxCol'" + //unfortunately, this is a hard-coded name of checkbox
",'" +
[YourDataGrid].ClientID + //replace with the name of your datagrid
"')" + "\n"+
"// End of hiding here. -->\n" +
"</script>";
RegisterStartupScript("CBSelectAll", scriptString);

3. The Javascript:

var gSelectAllTable; //global class to save information
function SelectAllCB_Click()
{
var bChecked = gSelectAllTable.SelectAllCB.checked;
var numCBs = gSelectAllTable.CheckBoxes.length
for(var i = 0; i < numCBs; i++)
{
gSelectAllTable.CheckBoxes[i].checked = bChecked;
}
gSelectAllTable.NumChecked = (bChecked) ? numCBs : 0;
}

function CheckBox_Click()
{
gSelectAllTable.NumChecked += this.checked ? 1 : -1;
gSelectAllTable.SelectAllCB.checked =
(gSelectAllTable.NumChecked == gSelectAllTable.CheckBoxes.length) ? true : false;
}

function bindSelectAllCheckBox(cbASPID, tableID)
//Assumptions:
// 1. only one such select check box is implemented on a page
// 2. the SelectAll check box's ID is composed "SelectAll"
//Parameters:
// cbASPID: ID (not ClientID) of the checkboxes
// tableID: ClientID of the table whose checkboxes will be selected
{
//regular expression for checkbox
var re = new RegExp(':' + cbASPID + '$');
//regex for select all
var reall = new RegExp(':' + cbASPID + 'SelectAll$');
gSelectAllTable = document.getElementById(tableID);
gSelectAllTable.CheckBoxes = new Array();
gSelectAllTable.NumChecked = 0;
var cbCount = 0;

if(gSelectAllTable)
{
var fm = document.forms[0];
for(var i = 0; i < fm.elements.length; i++)
{
elm = fm.elements[i];
if(elm.type == 'checkbox')
{
if(reall.test(elm.name))
{ //select all check box
gSelectAllTable.SelectAllCB = elm;
elm.onclick = SelectAllCB_Click;
}
else if(re.test(elm.name))
{ //other check boxes
gSelectAllTable.CheckBoxes[cbCount] = elm;
cbCount++;
if(elm.checked)
{
gSelectAllTable.NumChecked++;
}
elm.onclick = CheckBox_Click;
}
}
}

}
}


What can be improved:

  1. The ID of CheckBox is hardcoded.We cannot catch any typo in compile time.

  2. This implementation cannot handle 2 or more such DataGrid on one page;

  3. This implementation cannot handle CheckBox in "EditItemTemplate";

This implementation is inspired by:

  1. DHTML Utopia: Modern Web Design Using JavaScript & DOM:
    http://www.sitepoint.com/books/dhtml1/?SID=878198150071901bb10971055cb72d00

  2. Yahoo Email: http://mail.yahoo.com


No comments: