An Easier Way to Highlight the Rows of a DataGrid on MouseOver
By Steve Stchur
Introduction
By now, virtually every ASP.NET developer is familiar with the DataGrid control, an extremely powerful and versatile control for displaying data. (If you are not familiar with the DataGrid, I suggest that you start with Scott Mitchell's An Extensive Examination of the DataGrid Control article series.) Personally, I've used the DataGrid control in numerous projects and often find myself trying to make the DataGrid's rendered output more aesthetically appealing. One such aesthetic technique, used by sites like Yahoo! Mail and Hotmail, is automatic highlighting of the row the user's mouse is positioned over. That is, when the end user moves his mouse over the DataGrid's data, the DataGrid row the mouse currently resides over would have a different background color than the other rows.
You may actually know how to accomplish mouse-based row highlighting already, as there have been numerous articles written
about how to extend the DataGrid control to add this functionality. One example of such an article is Scott's
Creating a Row-Selectable DataGrid Control. Scott's article, and many of the other articles,
propose a solution that involves creating a custom ASP.NET server control that extends the DataGrid. This custom server control,
then, emits the necessary client-side script to enable to row highlighting functionality. (Specifically, the <tr>
HTML elements have onmouseover
and onmouseout
attributes added...)
While building a custom server control allows for easy deployment and a rich design-time experience, I was determined to come up with a simpler approach to creating a row-highlightable DataGrid, one that would work without requiring any changes to the standard DataGrid control. An idea for how to accomplish this came to me after reading an article about how to create a purely CSS Drop-Down menu on the AListApart website. The concept for that article was simple: Use the CSS hover style to show/hide various nested lists. I was fascinated by the simplicity and pure genius of this concept, and I realized that with a little tweaking, it could be used to highlight the rows of a DataGrid as well.
In this article we'll examine how to utilize the hover feature of CSS to add row highlighting to a standard DataGrid. Feel free to check out the live demo before you begin reading...
First Things First: Displaying Data in a DataGrid
Throughout the course of this article I'm going to explain how I used client-side CSS to add row highlighting to a standard DataGrid. In my adventure I bumped up against a number of pitfalls, which I'll point out and show how to avoid. Of course, before we can highlight any of the rows in a DataGrid we need a DataGrid to work with. The code below shows a single page that binds synthetically-created data to a DataGrid, and is the basis for which the final live demo is built around.
|
At this point we have a very simple DataGrid that is bound to some hard-coded data. As the
live demo shows, I've set the HeaderStyle
to a nice blue, while the AlternatingItemStyle
property specifies that the background color of every other row should be a light gray.
First Attempts at Row Highlighting
My first instinct to make the rows "highlightable" was to simply add a CSS style to any
TR
(table row) elements
on the page like so:
<style type = "text/css"> |
Since each of the rows in a DataGrid is rendered as a <tr>
element, my initial thinking was that this
CSS would highlight each of the DataGrid's rows pink (#ffccff
) when it was moused over. I started by testing this approach with
the Firefox Web browser and noted that each row of the DataGrid
is highlighted on mouseover. However, every row of the DataGrid was highlighted, including the DataGrid's Header row.
When testing this CSS with Internet Explorer I found that it did not highlight rows at all!
Fixing Row Highlighting for Internet Explorer
A little research turned up the fact that IE only supports
:hover
for hyperlinks (<a>
tags).
Fortunately, as it turned out, fixing this was fairly easy to remedy with some
JavaScript and a slight modification to the CSS stylesheet. Essentially I defined a tr
-level class,
over
and used the same CSS as with the :hover
. The CSS stylesheet, then, becomes:
<style type = "text/css"> |
That change of course, won't solve the problem by itself since we've yet to indicate that the <tr>
elements
of the DataGrid belong to the over
class. A little JavaScript is needed to set the class
attribute of each <tr>
element to over
when it's moused over:
|
The above script tells the browser to start searching through all child elements of the DataGrid. (Note: you need to replace
ID of DataGrid with the client-side ID of the
If you test this code out in IE now, you'll notice something odd. Every OTHER row highlights. Why? Because we
specifically told our DataGrid to that each
So how do we get around this issue? Simple. Just specify that when a
Give that a go in IE, and you'll see that the Header row is no longer "lighting" up when moused over; also, thanks to our
addition of the
So what do we do about Firefox (and other non-IE browsers)? What we need is a way to tell the browser that only certain
The above CSS tells the browser to only apply the hover style to those
I contemplated this approach, however I'm a believer in
CSS, and I feel like it is the superior approach (i.e., the
Right Way to do it). I consider the Javascript a bit of a hack. So my attitude is, let's do it "the right
way" whenever possible, and only resort to Javascript when we have to. You are more than welcome to tweak the JavaScript
so that it works with FireFox if you'd like, but my particular personal philosophy predicates that I persist with this path.
As it stands right now, this won't work, because the
One final thing I'd like to mention is that I cannot take credit for JavaScript in this article. I modified it some, but
the bulk of it came from Patrick Griffiths' and Dan Webb's article Suckerfish
Dropdown on AListApart.Com. I definitely recommend checking out that article as
it will provide you with some extremely valuable CSS insight.
Happy Programming!
<table>
control that is rendered from the DataGrid.
Unless the DataGrid is within a User Control, another DataGrid, or some other naming container, it will simply be the same
as the ID
property of the DataGrid Web control.) When the script finds a DataGrid element whose node name is
TR
it adds an onmouseover
function and an onmouseout
function. The purpose of each
of those functions is to simply set the CSS class of the <tr>
to <tr>
or out of it.
AlternatingItemStyle
should have a background color of #eeeeee
.
Since ASP.NET renders that style inline, it take precedence over the CSS class that we specify in JavaScript. In fact,
had we specified an ItemStyle
as well, we'd see that none of the rows highlight for this very same reason.
TR
is moused over, any TD
elements (that are children of that TR
) get the CSS class "over" attached to them. This works, because any
styles set to the TD
element will override those of its parent (the TR
element). Here is the updated CSS.
<style type = "text/css">
tr:hover, tr.over td { background-color: #ffccff; }
</style>
Not Highlighting the Header Row
Ok, so we've solved the IE-specific problem, but there is still the issue of the highlighting HeaderRow. What to do, what to do.
Well, a keen reader might notice that in IE, the Javascript is looping through every single row in the table (DataGrid).
An easy solution to our problem in IE then, is to simply start at row 1, rather that at row 0, thereby skipping the
first row (the Header row):
[View a Live Demo!]
// In the startHighlight function...
for (i = 1; i < tbody.childNodes.length; i++)
{
// this code stays the same
}
td
in the CSS stylesheet, all of the DataGrid's rows are highlighting in IE, not just
the alternating ones.
TR
elements should have the hover style applied to them. Fortunately, CSS makes this fairly easy. Something
like this should do the trick:
<style type = "text/css">
tr.row:hover, tr.over td { background-color: #ffccff; }
</style>
TR
elements whose CSS class is
row
.
Why Use Two Techniques?
I have employed two different techniques for enabling row highlighting in a DataGrid, the technique used being based on
the visitor's browser: pure CSS for FireFox, a mix of CSS and JavaScript for IE. It's a bit unfortunate that we have to
use two different techniques to support the two most popular browsers. One option would be to tailor the JavaScript code
so that it would also work with FireFox.
TR
elements in our DataGrid don't have
any CSS class associated with them. We can fix that by specifying the CssClass
property in the AlternatingItemStyle
and ItemStyle
sections in our DataGrid:
[View a Live Demo!]
<AlternatingItemStyle BackColor = "#eeeeee" CssClass = "row" />
<ItemStyle BackColor = "#ffffff" CssClass = "row" />
Conclusion
And there you have it! A easy way to highlight the rows in a DataGrid that uses considerably less code that some of the
other methods you may have seen / implemented.
One important thing I should point out, is that I've only tested this in IE 6.0 and Mozilla Firefox 1.0. I'm not sure how
this will react in other browsers (though I suspect Netscape 7 and IE 5.5) should handle it fairly well. In any case, if
you find it doesn't work in some other browser, the Javascript is yours for the taking. Simply modify it to suit your
needs and you're good to go.