Stripey tables revisited

15 Mar 2004

Background

This is an update of an earlier article, which was inspired by David F Miller’s Zebra tables article for A List Apart.

In order to make data tables easier to read it’s useful to ‘stripe’ every other line with a subtle background colour so the eye can track easily across each column for a given row.

The JavaScript function described below is the one I use to stripe the Waxheads’ results table.

My solution* is a short function that sets the class of either the odd or even rows of a table. Thus, you can have full control over the guide stripes’ appearance via the page’s stylesheet.

As in David’s example, if the row already has a class defined then the function won’t replace it with the guide stripe class. Unlike David’s example, the row is updated whether, or not, it has a background colour set as I feel the background colour of the row should be being set via either the row’s or the table’s style.

Implementation

Striping a table is straightforward. Firstly, include the javascript in a <script> block. Alternatively, and better if you’re going to stripe tables on more than one page, load the JavaScript from an external file using:

<script language="JavaScript" type="text/javascript" src="myJavaScript.js">

Next, identify your table with an id attribute. For instance:

<table id="myTable" summary="Stripey table">

Now, either directly from a <script> block within the page, or from the onload attribute in the <body> tag, call, for example:

tableStripe('myTable' 'myStripeClass', true)

(So, from the onload attribute it would be:

<body onload="javascript:tableStripe('myTable' 'myStripeClass', true)">

The parameters passed to tableStripe() are, in order, the id of the table, the class name to apply to the row and, finally, a Boolean to determine whether to apply the class to the odd (true) or even (false) rows.

The JavaScript source is fairly succinct:

function tableStripe(p_strId, p_strClass, p_bOdd) {    var l_Table = document.getElementById(p_strId);    if(l_Table.rows) {     for(var l_iIndex = (p_bOdd ?  0 : 1);<span class="exDesc">&rArr;</span> l_iIndex &lt. l_Table.rows.length;<span class="exDesc">&rArr;</span> l_iIndex += 2) { var l_Row = l_Table.rows.item(l_iIndex);  if(!hasClass(l_Row)) {   l_Row.className = p_strClass; }     }   } }

(The signifies that the line would, but for display considerations, continue on the same line.)

Handily, the DOM provides a rows attribute in the table class, which is a list of all the table’s row elements in the order in which they appear. We simply traverse the list and, depending on whether we want to apply our class to odd or even rows and, if the row hasn’t already got a class attribute, we set the row’s className attribute to our supplied class name.

The rows are indexed from zero. We set our starting index to zero for an odd start and one for an even start and then traverse the list in steps of two. If the current row doesn᾿already have a class we apply our own.

For a working example, view the Waxheads ’ results page’s source code.

This article is a work in progress. I’ve noted that both this technique, and David’s don’t work for IE5.01/Win, I will look to see if there’s a work-around that can be applied in that case – let me know if you find other issues with other browsers.

*Acknowledgments

I’m grateful to my friend Nigel Caughey for entering into a game of ‘optimisation tennis’ with me that transformed my initial algorithm into the one shown here.

In addition, I’ve borrowed David’s hasClass() function, for the IE compatibility reasons he describes in his comment:

// this function is needed to work around // a bug in IE related to element attributes function hasClass(p_Element) {    var l_bRet = false;    if (p_Element.getAttributeNode("class") != null) {  l_bRet = <span class="exDesc">&rArr;</span>    p_Element.getAttributeNode("class").value;    }    return l_bRet; } 

For more information about the DOM see Document Object Model (DOM) Level 2 HTML Specification