Table Sort
See the demo page for the finished version of the code.Altering the Table Display
Initially, every other row in the body of both tables has a style class assigned to its TR tag. This gives the rows an alternating background color for improved readability.
All attributes are retained as the sort function moves those rows around within the table body. So after sorting, chances are that this alternating pattern will be broken.
So after sortTable()
finishes sorting the rows, it calls a
function named makePretty()
to fix the display. It will go through
the rows and restore the alternating backgrounds by changing the row elements
className
properties. It will also do the same for each cell in
those rows in order to highlight the column that was just sorted.
First, a few global variables are defined to make things easier. These include strings designating the style class names to be used and some regular expressions.
// Style class names. var rowClsNm = "alternateRow"; var colClsNm = "sortedColumn"; // Regular expressions for setting class names. var rowTest = new RegExp(rowClsNm, "gi"); var colTest = new RegExp(colClsNm, "gi");
An element may have multiple class names assigned to it. This is done by
listing the class names, separated by spaces, in the tag's CLASS attribute or
by setting the className
property of its corresponding DOM element
with a string in that same format.
Adding and Removing Class Names
In order to preserve any other class names that may be set for a row or column element, we'll use these regular expressions to remove just the one designated class name with code like the following:
rowEl.className = rowEl.className.replace(rowTest, "");
Conversely, to add the class name to an element, we just append the name to
its className
property with a space.
rowEl.className += " " + rowClsNm;
Setting the alternate row styles and highlighting the sorted column is then accomplished by looping through each row and cell.
function makePretty(tblEl, col) { var i, j; var rowEl, cellEl; // Set style classes on each row to alternate their appearance. for (i = 0; i < tblEl.rows.length; i++) { rowEl = tblEl.rows[i]; rowEl.className = rowEl.className.replace(rowTest, ""); if (i % 2 != 0) rowEl.className += " " + rowClsNm; rowEl.className = normalizeString(rowEl.className); // Set style classes on each column (other than the name column) to // highlight the one that was sorted. for (j = 2; j < tblEl.rows[i].cells.length; j++) { cellEl = rowEl.cells[j]; cellEl.className = cellEl.className.replace(colTest, ""); if (j == col) cellEl.className += " " + colClsNm; cellEl.className = normalizeString(cellEl.className); } }
So the function runs through each row first removing the alternate row style class from it. Then, if it an odd numbered row, it adds the class name back.
Note how the normalizeString()
function is used here to clean
up the class name list so it doesn't keep growing with extra spaces. This is
the same function, described earlier, that we used with
getTextValue()
to remove extra white space in the text extracted
from a table cell.
Within each row, we also loop through each cell, doing basically the same thing with the style class for highlighting the sorted column. The only difference is that we skip the first two columns because the first is not sortable and the second is the team name column. There is no compelling reason for not highlighting the team names, it's just an aesthetic choice.
Setting the Column Header Style
The next step in makePretty()
is to highlight the column
header, that is, the table cell containing the sort link that was clicked.
The tblEl
argument that was passed by
sortTable()
refers to the table body. But the sort link resides in
a row within the head section of the table. So first we need to find that row.
Fortunately, this is relatively easy.
We first use the parentNode
property of tblEl
to
get to the TABLE element that both the head and body belong to. Then we use
the tHead
property of that node to get to the last row in the
table head.
var el = tblEl.parentNode.tHead; rowEl = el.rows[el.rows.length - 1];
Given the way the tables are set up, this will be the row containing the sort links (the first row in the head section contains a single, spanned cell for displaying a title).
From there, we do exactly what we did for the cells in each row of the table body.
// Set style classes for each column as above. for (i = 2; i < rowEl.cells.length; i++) { cellEl = rowEl.cells[i]; cellEl.className = cellEl.className.replace(colTest, ""); // Highlight the header of the sorted column. if (i == col) cellEl.className += " " + colClsNm; cellEl.className = normalizeString(cellEl.className); }
Once makePretty()
finishes, sortTable()
will then
call setRanks()
to display the team rankings in the first column of
the table.