You are here: Home > Articles > Article Display

Creating clickable table rows in ASP.NET that change colors

In services like Hotmail, you have a list of contents in a table. If you allow the user to select rows and do something with them, you might want to make it more pleasing to the eye, by changing the color of the row when selected. You might also have a main control checkbox, that when clicked selects all the rows and also colors all the rows. In this article, we'll see how to accomplish that in 2 parts: first how to create programatically the table and controls populating the checkboxes, and second we'll create the Javascript functions that handle the client effect of changing colors.

Published: Nov 4, 2002
Tested with: ASP.NET 1.1
Category: ASP.NET
63,912 views

Introduction

In services like Hotmail, you have a list of contents in a table. If you allow the user to select rows and do something with them, you might want to make it more pleasing to the eye, by changing the color of the row when selected. You might also have a main control checkbox, that when clicked selects all the rows and also colors all the rows. In this article, we'll see how to accomplish that in 2 parts: first how to create programatically the table and controls populating the checkboxes, and second we'll create the Javascript functions that handle the client effect of changing colors.

Hotmail - select by row

This is a snapshot taken from my hotmail account. Each row contains a checkbox, and when clicked the whole row changes colors. You can also see next to the From heading the main checkbox, which when clicked selects and highlights all rows.

Creating the table programatically

First create a table in a web form nested inside a form - tables.aspx

1 <%@ Page language="VB" Debug="true" Strict="true" codebehind="tables.aspx.vb" src="tables.aspx.vb" inherits="Table" %>
2 <html>
3 <head>
4     <title>Highlighting rows in a table</title> </head>
5 <body>
6 <form id="myForm" method="post" runat="server">
7     <asp:Table runat="server" id="myTable" cellpadding="3" cellspacing="1" border="0">
8         <asp:TableRow BackColor="#c9c9c9">
9             <asp:TableCell>
10                 <input name="cbxSelectAll" type="checkbox" onclick="javascript:checkAll(this.form);">
11             </asp:TableCell>
12             <asp:TableCell Text="Output" />
13         </asp:TableRow>
14     </asp:Table>
15 </form>
16 </body>
17 </html>

The web form is a simple page with one form and one table that run at the server side. I included the headers row already, in order to show how to create rows using both html controls and web controls.

Then create some code in the codebehind page that will populate the table with rows - tables.aspx.vb

1 Option Explicit On
2 Option Strict On
3
4 Imports System
5 Imports System.Web.UI.WebControls
6 Imports System.Drawing
7
8 Public Class Table
9
10     Inherits System.Web.UI.Page
11     
12     Protected myTable As System.Web.UI.WebControls.Table
13     
14     Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
15         PopulateTable()
16     End Sub
17     
18     Protected Sub PopulateTable()
19         'dimension new web controls
20         Dim rowItem As TableRow
21         Dim cellCheckbox As TableCell
22         Dim checkItem As CheckBox
23         Dim cellWhatever As TableCell
24         Dim lblItem As Label
25         Dim i As Integer
26         'write as many rows as you need (15 in this case)
27         For i = 1 To 15
28             'define new web controls
29             rowItem = New TableRow
30             cellCheckbox = New TableCell
31             checkItem = New Checkbox
32             'check cell
33             checkItem.Attributes("onClick") = "javascript:colorRow(this);"
34             cellCheckbox.Controls.Add(checkItem)
35             'add the cells to the new row
36             rowItem.Cells.Add(cellCheckbox)
37             'add more cells as needed
38             'for the From, Subject, Date and Size cells
39             'define new web controls
40             cellWhatever = New TableCell
41             lblItem = New Label
42             'label cell
43             lblItem.Text = "This is the output from line " + i.ToString()
44             cellWhatever.Controls.Add(lblItem)
45             'add the cells to the new row
46             rowItem.Cells.Add(cellWhatever)
47             rowItem.BackColor = Color.FromName("#eeeeee")
48             myTable.Rows.Add(rowItem)
49         Next
50     End Sub
51
52 End Class

The codebehind page has one class, Table, which inherits from the System.Web.UI.Page class. It contains 2 methods: the Page_Load() and a custom one called PopulateTable(), which is called when the page is loaded. We can use a simple loop in the sub to create 15 rows. The first cell of each row is the Checkbox, and we add the Javascript call as an attribute. The second cell contains a Label web control just so we can show the highlight effect later on.

Creating the Javascript functions

The resulting HTML output from the above code looks something like this:

1 ...
2 <form name="myForm" method="post" action="tables.aspx" id="myForm">
3     <table id="myTable" cellspacing="1" cellpadding="3" border="0" border="0">
4         <tr style="background-color:#C9C9C9;">
5             <td>
6                 <input name="cbxSelectAll" type="checkbox" onclick="javascript:checkAll(this.form);">
7             </td>
8             <td>Output</td>
9         </tr>
10         <tr style="background-color:#eeeeee;">
11             <td>
12                 <span onClick="javascript:colorRow(this);">
13                     <input id="_ctl0" type="checkbox" name="_ctl0" />
14                 </span>
15             </td>
16             <td>
17                 <span>This is the output from line 1</span>
18             </td>
19         </tr>
20 ...

A closer look at the HTML code produced above, reveals that the Javascript function colorRow(this) is wrapped around each checkbox in a tag, and not in the checkbox tag itself. This is the result of adding an attribute programatically to a checkbox web control. The .NET parser gives each generated checkbox a generic ID and Name, starting with _ctl and followed by a number. This is a little trickier to handle than simply having the function in the checkbox tag itself, but nothing that can't be solved. Let's take a look at this Javascript function.

1 <script type="text/javascript">
2 //declare global variables
3 var rowsSelected = 0;
4 //change the background color of a row when selected and
5 //also count how many rows are selected
6 function colorRow(srcElement) {
7     var cb = event.srcElement;
8     var curElement = cb;
9     while (curElement && !(curElement.tagName == "TR")) {
10         curElement = curElement.parentElement;
11     }
12     if (!(curElement == cb) && (cb.name != "cbxSelectAll")) {
13         if (cb.checked) {
14             curElement.style.backgroundColor = "gold";
15             rowsSelected = rowsSelected + 1;
16         }
17         else {
18             curElement.style.backgroundColor = "#eeeeee";
19             rowsSelected = rowsSelected - 1;
20         }
21     }
22 }
23
24 ...

We capture the event that fired the Javascript, namely the span, and use Javascript's parentElement to travel upwards in the DOM hierarchy until it finds a <tr> tag. The first one we find must be the row in question, so we capture it and then change its color. The color we change it to, depends on whether we are checking the row or un-checking it. We must also make sure to exclude the main checkbox (cbxSelectAll) from the ones that can change colors: otherwise, even the title headers would change colors once we click on the checkbox to automatically select all the checkboxes. A global variable rowsSelected counts how many rows have been clicked. This is useful if for example you have a Delete function, which deletes the rows you have selected - you can fire the server event only if the rowsSelected is greater than 0, otherwise you can pop up an alert message to the user. Let's now take a look at the function which selects all the checkboxes.

1 ...
2
3 //color all rows when the main checkbox is clicked
4 function checkAll(form) {
5     var thisNumRowsSelected = 0;
6     var isChecked = document.all.cbxSelectAll.checked;
7     for (var i=0; i < form.elements.length; i++) {
8         if (form.elements[i].name.indexOf('_ctl') > -1) {
9             var curElement = form.elements[i];
10             if (isChecked) {
11                 curElement.checked = true;
12                 thisNumRowsSelected = thisNumRowsSelected + 1;
13                 while (!(curElement.tagName == "TR")) {
14                     curElement = curElement.parentElement;
15                 }
16                 if (form.elements[i].name != "cbxSelectAll") {
17                     curElement.style.backgroundColor = "gold";
18                 }
19             }
20             else {
21                 curElement.checked = false;
22                 while (!(curElement.tagName == "TR")) {
23                     curElement = curElement.parentElement;
24                 }
25                 if (form.elements[i].name != "cbxSelectAll") {
26                     curElement.style.backgroundColor = "#eeeeee";
27                 }
28             }
29         }
30     }
31     rowsSelected = thisNumRowsSelected;
32 }
33 </script>

This function does basically the same one as the colorRow(), except that it excludes the cbxSelectAll checkbox row from being highlighted. The internal variable thisNumRowsSelected counts the total number of rows selected, and sets it equal to the global rowsSelected variable at the end of the function. Our 2 Javascript functions are now complete, and we can add them to our web form - tables.aspx.

Conclusion

In this article we have learned how to populate a table with rows and cells containing checkboxes programatically, and how to change the color of the rows on clicking each checkbox. The Javascript code has been tested with IE6.0 and it should work with DOM-compliant browsers. One possible improvement I can think of, is to allow for many different colors of rows, and return back to the original color on un-checking each checkbox.

 



Other articles in this category
  1. Smart headers and footers using ASP.NET User Controls
    December 23, 2002
    Good site usability often means removing links from one page back to itself. In this article we will look at how to create an ASP.NET User Control which will act as a common header to a site. It will automatically know which page we are looking at, and it will remove links to the same page from itself. For example, on this site, if we click on the About us section of the header, it will take you to the page, and it will make that link inactive. That way, we know that we are under that section, and we can't click on it anymore.
  2. Maintaining Sorting while Paging in an ASP.NET Datagrid
    December 18, 2002
    The Datagrid server control offers much control and flexibility in presenting data. Two of the actions that are hard-wired into it are Paging and Sorting. On their own they work great, but not so well together. When you sort a column and then move to a previous or next page, the sorting preference is not maintained. In this article we will see how to maintain both by using the Viewstate object.
  3. How postback works in ASP.NET
    December 10, 2002
    In this article, we will take a closer look at how ASP.NET pages post back to themselves, and how to customize this feature in our web applications.
  4. Viewing and editing file and directory attributes in ASP.NET
    December 2, 2002
    The System.IO.FileAttributes class gives us access to file/directory attributes. In this article, we'll see how to use this class to first read the current attributes and then change them.
  5. Copying a directory in ASP.NET
    November 25, 2002
    The System.IO.DirectoryInfo class does not come with a method to copy a directory. In this article, we'll see how to create a method to do that, and then use it in an ASP.NET page.