views:

592

answers:

2

I have a query building form built in php. The results of the query are returned and placed in two different tables one above the other. (table id's are results, and results2) Each record returned builds two tables to display its data. (Soon to be three)

I'm using the following code to change the class tags of my 's to provide alternate row coloring:

    <script type="text/javascript">
function alternate(id){
  if(document.getElementsByTagName){
    var table = document.getElementById(id);
    var rows = table.getElementsByTagName("tr");
    for(i = 0; i < rows.length; i++){
      if(i % 2 == 0){
       rows[i].className = "row-one";
       }else{
       rows[i].className = "row-two";
            }
          }
         }
        }
</script>

Then I'm using a body onload like so:

<body onload="alternate('results'); alternate('results2');">

The problem is it only colors the first two instances of these tables, when depending on the amount of records returned there could be hundreds of them.

How can I get this function to apply to every table in the document with a id = results and results2 and soon to be a results3?

Thank you for any assist Stack Overflow.

+2  A: 

If you really want to do this with JavaScript, I would suggest the following code:

First, make your tables have a class of "results" instead of ID "results1", "results2", etc (because as my comment on the question says, IDs must be unique, and getElementById will only return one result and apply to only one real element):

<table class="results">...</table>

Next, use this JavaScript:

<script type="text/javascript">
function alternate(classNameMatch) {
    var tables = document.getElementsByTagName("TABLE");
    for (var i=0; i < tables.length; i++) {
        var table = tables[i];
        if (table.className.indexOf(classNameMatch) == -1)) continue;

        for (var j=0; j < table.rows.length; j++) { // "TABLE" elements have a "rows" collection built-in
            table.rows[j].className = j % 2 == 0 ? "row-one" : "row-two";
        }
    }
}
</script>

Then call alternate("results"); on page load.

But, I really suggest doing this in PHP. JavaScript will be very inefficient with large result sets. It will also not show up right away, making the style of the page visibily change after page load.

I would also just add a class to every other row, and then style all rows by default one way and the other class the other way:

<style type="text/css">
table.results tr { background-color:#f0f0f0; }
table.results tr.row2 { background-color:#f0f0ff; }
</style>
Renesis
Thank you Renesis, greatly appreciated.
Aaron
+1  A: 

Of course each call to the method is only applying to one table - you are not looping over a number of tables, but set the table var at the top of the document and then colour the rows in that table. As others have pointed out, IDs are meant to be unique within a document anyway, which is why getElementByID only returns a single value.

Doing this on the server-side would be much better as well, because that's the canonical document sent to everyone so doesn't rely on them having JS enabled, and doesn't take a possibly non-negligible amount of processing time while the page gets striped.

If you must do this client-side, a better implementation would be to give your tables a particular class (instead of ID); refactor your solution slightly so that you split the core of your functionality into a method that stripes a single table that's passed in; then find all tables with the class "stripeme" (or whatever), and loop over that result, passing each table into your striping method.

Andrzej Doyle