Table row striping

J

johkar

I would like to ensure this script is optimized (runs correctly or does
not execute) for the major browsers. Will checking getElementById and
getElementsByTagName accomplish this?

In addition, I would like adapt it to ignore table headers or rows with
existing classes hardcoded. I haven't been able to get the syntax
down. Any help appreciated. If there is an existing script that will
do all this, that is fine too. I haven't found it.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript">
function stripeTable(id){
if(document.getElementById && document.getElementsByTagName){
var table = document.getElementById(id);
var rows = table.getElementsByTagName("tr");
for(i = 0; i < rows.length; i++){
if(i % 2 == 1){
rows.className = "defaultclass";
}else{
rows.className = "rowstripe";
}

}
}
}
</script>
<style type="text/css">
..defaultclass { background-color:#fff;}
..rowstripe { background-color:#e7e7e7;}
</style>
</head>

<body onload="stripeTable('table1')">
<table width="50%" border="0" cellspacing="2" cellpadding="2"
id="table1">
<tr>
<th>My Table</th>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>
 
R

RobG

johkar said:
I would like to ensure this script is optimized (runs correctly or does
not execute) for the major browsers. Will checking getElementById and
getElementsByTagName accomplish this?

You should check all the features you are going to use (you don't need
getElementsByTagName, see below). If you are going to use lots of them
and frequently, you may want to have an initialisation phase that sets
everything up once at the very beginning.

You should always ensure that if the script doesn't run, the page is
still functional - that doesn't mean it has to be identical with or
without script, just as long as it's still reasonably useable.
Intranet requirements may be different.

In addition, I would like adapt it to ignore table headers or rows with
existing classes hardcoded. I haven't been able to get the syntax
down. Any help appreciated. If there is an existing script that will
do all this, that is fine too. I haven't found it.

This sort of stuff is much better if done on the server - if your page
takes a while to load, then the table probably won't be 'striped' until
sometime after it is displayed. You might insert the load call in a
script element immediately after the table's closing tag in the source
HTML, but that makes the page a bit messy.

To work on just a component of the table, put the rows you want to play
with in their own tbody element (you can have any number of them in a
table). You can also use thead and tfoot elements to create distinct
table sections that are not included in a tbody element.

As for skipping 'hard coded' classes, the className attribute
represents style rules that are applied either inline (i.e. coded in
the element's HTML source) or applied to the element using script.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript">
function stripeTable(id){

If the id is for a tbody element, they you can work on just those rows
and ignore the others in the table that are in thead, tfoot or other
tbody elemetns.

if(document.getElementById && document.getElementsByTagName){
var table = document.getElementById(id);
var rows = table.getElementsByTagName("tr");

You don't need getElementsByTagName, just use the rows collection:

var rows = document.getElementById(id).rows;

For 'belt and braces' approach, you may want to use:

var o, rows;
if ( document.getElementById
&& (o = document.getElementById(id))
&& (rows = o.rows)){
/* ... */
}

for(i = 0; i < rows.length; i++){

To skip the ones that already have a className:

var row;
for(i = 0, len=rows.length; i<len; i++){
row = rows;
if (!rows.className){
row.className = (i%2)? 'rowstripe' : 'defaultclass';
}
}
if(i % 2 == 1){
rows.className = "defaultclass";
}else{
rows.className = "rowstripe";
}

}
}
}
</script>
<style type="text/css">
.defaultclass { background-color:#fff;}
.rowstripe { background-color:#e7e7e7;}
</style>
</head>

<body onload="stripeTable('table1')">


Use a tbody:

<table width="50%" border="0" cellspacing="2" cellpadding="2"
id="table1">
<tr>
<th>My Table</th>
</tr>

Insert a tbody here. The browser will insert one around the above row,
or replace the above row with a thead. But use a tbody, the table's
rows collection has *all* the rows in it for all tableSection elements
in the table.

<tbody id="tBody1">

[...]

Here's the full thing:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Play</title>
<style type="text/css">
.defaultclass { background-color:#fff;}
.rowstripe { background-color:#e7e7e7;}
.blah {background-color: #bbf;}
</style>
<script type="text/javascript">
function stripeTable(id)
{
if (!document.getElementById) return;
var rows = document.getElementById(id).rows;
var row;
for(i = 0, len=rows.length; i<len; i++){
row = rows;
if (!rows.className){
row.className = (i%2)? 'rowstripe' : 'defaultclass';
}
}
}
</script>
</head>
<body onload="stripeTable('tBody1')">
<table width="50%" border="0" cellspacing="2" cellpadding="2"
id="table1">
<tr><th>My Table</th></tr>
<tbody id="tBody1">
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td class="blah">4</td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
<tr><td>7</td></tr>
</tbody>
</table>
 
R

RobG

RobG wrote:

Sorry, a few snafu's here:
johkar wrote: [...]
As for skipping 'hard coded' classes, the className attribute
represents style rules that are applied either inline (i.e. coded in
the element's HTML source) or applied to the element using script.

The className attribute represents the *class* attribute applied inline
or via script.

[...]
To skip the ones that already have a className:

var row;
for(i = 0, len=rows.length; i<len; i++){
row = rows;
if (!rows.className){


Ooops...

if (!row.className){

[...]
 
D

Dr John Stockton

JRS: In article <[email protected]>
, dated Tue, 20 Jun 2006 11:45:48 remote, seen in
news:comp.lang.javascript said:
I would like to ensure this script is optimized
...
for(i = 0; i < rows.length; i++){
if(i % 2 == 1){
rows.className = "defaultclass";
}else{
rows.className = "rowstripe";
}

}



For that, consider

for (k = 0; k < rows.length; k++)
rows[k].className = k&1 ? "defaultclass" : "rowstripe"

k = rows.length ;
while (k--) rows[k].className = k&1 ? "defaultclass" : "rowstripe"

N.B. i is an annoying variable as it is seen as an error by a "spelling-
checker".
 
J

johkar

RobG said:
RobG wrote:

Sorry, a few snafu's here:
johkar wrote: [...]
As for skipping 'hard coded' classes, the className attribute
represents style rules that are applied either inline (i.e. coded in
the element's HTML source) or applied to the element using script.

The className attribute represents the *class* attribute applied inline
or via script.

[...]
To skip the ones that already have a className:

var row;
for(i = 0, len=rows.length; i<len; i++){
row = rows;
if (!rows.className){


Ooops...

if (!row.className){

[...]


Thanks Rob for the detailed response. It does make a lot more sense to
just apply it to the tbody.
 
M

Matt Kruse

johkar said:
In addition, I would like adapt it to ignore table headers or rows
with existing classes hardcoded.

Why? You probably shouldn't.
Instead, apply the "rowstripe" class (or whatever you call it) and let CSS
specificity rules decide if your hard-coded class rules are more important.
var rows = table.getElementsByTagName("tr");

As rob suggested, looking only at tbodies makes more sense. And also
consider that more than one tbody may exist, and you probably want to reset
strip row counting within each one.
if(i % 2 == 1){
rows.className = "defaultclass";
}else{
rows.className = "rowstripe";
}


You should almost never explicitly set a className. Instead, add to it or
remove a piece of it. Class attributes may contain multiple values, and
setting it explicity might remove things you don't want removed.

I have a table library which has a striping function in it, but I haven't
had the time to document or publish it yet. Its function looks like this:

// Shade alternate rows
// --------------------
table.shadeOddRows = function(t,className) {
if (t==null) { return; }
if (t.nodeName && t.nodeName!="TABLE") {
t = table.getTable(t);
}
var bodies = table.getBodies(t);
if (bodies==null || bodies.length==0) { return; }
for (var i=0; i<bodies.length; i++) {
var tb = bodies;
var rowNum=0;
for (var j=0; j<tb.rows.length; j++) {
if ("none"!=CSS.getStyle(tb.rows[j],"display")) {
if (rowNum++%2==0) {
CSS.removeClass(tb.rows[j],className);
}
else {
CSS.addClass(tb.rows[j],className);
}
}
}
}
}

It obviously has dependencies on other functions. It's used for re-striping
after table sorting, for example. It might give you a few ideas.
 
J

johkar

Dr John Stockton wrote:

For that, consider
for (k = 0; k < rows.length; k++)
rows[k].className = k&1 ? "defaultclass" : "rowstripe"

k = rows.length ;
while (k--) rows[k].className = k&1 ? "defaultclass" : "rowstripe"

N.B. i is an annoying variable as it is seen as an error by a "spelling-
checker".

Can you explain k&1?
 
D

Dag Sunde

johkar said:
Dr John Stockton wrote:

For that, consider
for (k = 0; k < rows.length; k++)
rows[k].className = k&1 ? "defaultclass" : "rowstripe"

k = rows.length ;
while (k--) rows[k].className = k&1 ? "defaultclass" :
"rowstripe"

N.B. i is an annoying variable as it is seen as an error by a
"spelling- checker".

Can you explain k&1?

True or false for odd and even k
 
D

Dr John Stockton

JRS: In article <[email protected]>
, dated Wed, 21 Jun 2006 12:54:59 remote, seen in
news:comp.lang.javascript said:
Dr John Stockton wrote:

For that, consider
for (k = 0; k < rows.length; k++)
rows[k].className = k&1 ? "defaultclass" : "rowstripe"

k = rows.length ;
while (k--) rows[k].className = k&1 ? "defaultclass" : "rowstripe"

N.B. i is an annoying variable as it is seen as an error by a "spelling-
checker".

Can you explain k&1?

Yes. But it is more important for you to have access to documentation,
printed or on the Web, which will answer basic questions about the
language you are using. See sig below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top