How to create the id of <td> and <tr> generated by DataGrid in ASP.NET and use it by client-side JavaScript.





3.00/5 (23 votes)
Feb 7, 2006
3 min read

60697

427
How to create client-side id of table row and cell generated by a datagrid and the way to use it using javascript along with an example in C#.
Introduction
One of the main problems I faced while working with datagrid is that programmer has no hand in generating the id in the html of different controls of in the datagrid. Though there is a well formed logic behind the generated ClientID, but most of the times it is difficult to use from client-side Javascript.
For example if the id of datagrid is ItemsGrid and a checkbox with id chkSelect is in the first column of the data grid, then in the client side html the id of the checkboxes generated are like ‘ItemsGrid__ctl2_chkSelect’, ‘ItemsGrid__ctl3_chkSelect’ etc.
Moreover by default the datagrid generates a table without any id of the <td> and <tr> tags. So one cannot directly use client-side script to change the attributes of these <td> and <tr>, like changing the background color of a row on mouse hover.
This proved to be a real gotcha for me to integrate javascript with datagrid. I found that the ‘ClientID’ of the controls in datagrid to be very helpful and by adding the ‘attribute’ to the controls the problem can be solved. MSDN has given me a good hint to solve it.
Here is an example which shows how to change background color of the rows of the table generated by a datagrid in the javascript events ‘onmousemove’ and ‘onclick’ event of checkbox.
The HTML code for the datagrid is as follows:
<asp:datagrid id="ItemsGrid" runat="server"
AlternatingItemStyle-BackColor="#f5f5f5"
BorderColor="Black" BorderWidth="1px" CellPadding="3"
AutoGenerateColumns="False">
<AlternatingItemStyle BackColor="WhiteSmoke"></AlternatingItemStyle>
<HeaderStyle BackColor="LightGray"></HeaderStyle>
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<asp:CheckBox id="chkSelectAll" Runat="server"
AutoPostBack="False"></asp:CheckBox>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox id="chkSelect"
runat="server"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="FirstName"
HeaderText="First Name"></asp:BoundColumn>
<asp:BoundColumn DataField="LastName"
HeaderText="Last Name"></asp:BoundColumn>
<asp:BoundColumn DataField="Age" HeaderText="Age">
<ItemStyle HorizontalAlign="Right"></ItemStyle>
</asp:BoundColumn>
</Columns>
</asp:datagrid>
The datagrid contains four columns, first one is ‘TemplateColumn’ with checkbox in it and the others are ‘BoundColumn’. The header of the ‘TemplateColumn’ also contains a checkbox ‘chkSelectAll’ which is used to select or deselect the other checkboxes.
The C# code snippet is give below:
private DataTable CreateDataSource()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("FirstName",
typeof(string)));
dt.Columns.Add(new DataColumn("LastName",
typeof(string)));
dt.Columns.Add(new DataColumn("Age", typeof(int)));
DataRow[] dr = new DataRow[5];
dr[0] = dt.NewRow();
dr[0][0] = "Pradipta";
dr[0][1] = "Basu";
dr[0][2] = "30";
dt.Rows.Add(dr[0]);
dr[1] = dt.NewRow();
dr[1][0] = "Sanjoy";
dr[1][1] = "Chatterjee";
dr[1][2] = "31";
dt.Rows.Add(dr[1]);
dr[2] = dt.NewRow();
dr[2][0] = "Arabinda";
dr[2][1] = "Sen";
dr[2][2] = "31";
dt.Rows.Add(dr[2]);
dr[3] = dt.NewRow();
dr[3][0] = "Kuntal";
dr[3][1] = "Ghoshal";
dr[3][2] = "24";
dt.Rows.Add(dr[3]);
dr[4] = dt.NewRow();
dr[4][0] = "Arijit";
dr[4][1] = "Chowdhury";
dr[4][2] = "25";
dt.Rows.Add(dr[4]);
return dt;
}
void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
// Load this data only once.
ItemsGrid.DataSource = CreateDataSource();
ItemsGrid.DataBind();
}
}
private void ItemsGrid_ItemDataBound(object sender,
DataGridItemEventArgs e)
{
ListItemType itemType = (ListItemType)e.Item.ItemType;
if ((itemType != ListItemType.Footer) &&
(itemType != ListItemType.Separator))
{
if(itemType == ListItemType.Header)
{
//Add attributes to the <th>
object checkBox = e.Item.FindControl("chkSelectAll");
if(checkBox != null)
((CheckBox)checkBox).Attributes.Add("onClick",
"Javascript:chkSelectAll_OnClick(" +
((CheckBox)checkBox).ClientID + ")");
}
else
{
// Add attributes to the <td>.
string tableRowId = ItemsGrid.ClientID + "_row" +
e.Item.ItemIndex.ToString();
e.Item.Attributes.Add("id", tableRowId);
object checkBox = e.Item.FindControl("chkSelect");
if(checkBox != null)
{
string clientId = ((CheckBox)checkBox).ClientID;
e.Item.Attributes.Add("onMouseMove",
"Javascript:chkSelect_OnMouseMove(" +
tableRowId + "," + clientId + ")");
e.Item.Attributes.Add("onMouseOut",
"Javascript:chkSelect_OnMouseOut(" +
tableRowId + "," + clientId + "," +
e.Item.ItemIndex + ")");
((CheckBox)checkBox).Attributes.Add("onClick",
"Javascript:chkSelect_OnClick(" +
tableRowId + "," + clientId + "," +
e.Item.ItemIndex + ")");
}
}
}
}
In Page_Load() the datasource of the Datagrid is set and data binding is done. The function ‘CreateDataSource()’ creates a DataTable for the Datagrid to use.
In ItemDataBound event handler, I have done the following :
- the id of each row is set. The id is generated by concatenating the ClientId of the datagrid with a string ‘row’ and the ItemIndex. The ClientID of the datagrid is used since the client side id of the datagrid gets changed if the datagrid is used inside a usercontrol.
- OnMouseMove and OnMouseOut javascript events are set
- OnClick event of all the checkboxes including the checkbox in the header is set.
The javascript used in the code are as follows:
function chkSelect_OnMouseMove(tableRowId, checkBox)
{
if(checkBox.checked == false)
tableRowId.style.backgroundColor = "#ffffcc";
}
function chkSelect_OnMouseOut(tableRowId,
checkBox, rowIndex)
{
if(checkBox.checked == false)
{
var bgColor;
if(rowIndex%2 == 0)
bgColor = "#ffffff";
else
bgColor = "#f5f5f5";
tableRowId.style.backgroundColor = bgColor;
}
}
function chkSelect_OnClick(tableRowId,
checkBox, rowIndex)
{
var bgColor;
if(rowIndex%2 == 0)
bgColor = "#ffffff";
else
bgColor = "#f5f5f5";
if(checkBox.checked == true)
tableRowId.style.backgroundColor = "#b0c4de";
else
tableRowId.style.backgroundColor = bgColor;
}
function chkSelectAll_OnClick(checkBox)
{
re = new RegExp('_chkSelect$')
for(i = 0; i <
document.forms[0].elements.length; i++)
{
elm = document.forms[0].elements[i]
if (elm.type == 'checkbox')
{
if (re.test(elm.id))
{
elm.checked = checkBox.checked;
var tableId = elm.parentNode.parentNode.id;
var rowIndex =
tableId.substring(tableId.length - 1,
tableId.length);
chkSelect_OnClick(
document.getElementById(tableId),
elm, rowIndex);
}
}
}
}
The function chkSelect_OnMouseMove() changes the background color of the row over which the mouse is moved. It checks whether the checkbox in the row is checked or not. If the checkbox is not checked, then it changes the background color.
The function chkSelect_OnMouseOut() restores the background color of the row to its original when the mouse moves out of a row.
The function chkSelect_OnClick() also changes the background color of the corresponding row when the checkbox in the row is selected and restores the original color when the checkbox is deselected.
Note: While setting the color to original color, it is checked that the row number is even or odd, since AlternatingItemStyle-BackColor property of the datagrid is used, to make things a bit complicated.
The function chkSelectAll_OnClick() is fired when the checkbox ‘chkSelectAll’ in the header of the datagrid is checked or unchecked. When this checkbox is checked or unchecked, then all the checkboxes in each row is also checked or unchecked accordingly with corresponding changes in background color of rows in the table.
The code is tested for IE 6.0, Mozilla Firefox 1.0.7 and Opera 8.5
The included solution and project contains the full source code for the example.
Thank you for reading my code.