-->
Bookmark and Share

Table Sort

See the demo page for the finished version of the code.

Customizing a Table Sort

To make sortTable() a little more useful, we can pass the table or table section id as an argument instead of hard coding it in the function. Then it can be used for multiple tables on a page.

function sortTable(id, col) {

  // Get the table section to sort.
  var tblEl = document.getElementById(id);

  ...

}

...

    <tr style="vertical-align:bottom">
      <th style="text-align:left">
        <a href="" onclick="return sortTable('planetData', 0)">Name</a>
      </th>

Other parameters can be defined as well, such as a second column index to be used for when the values of the primary sort column in two rows are equal. To handle a secondary sort column, we might do something like this.

function sortTable(id, col, col2) {

  ...

      cmp = compareValues(minVal, testVal);
      // Need to sort on secondary column?
      if (cmp == 0)
        compareValues(getTextValue(tblEl.rows[minIdx].cells[col2]),
                      getTextValue(tblEl.rows[j].cells[col2]));
      // Reverse order?
      if (tblEl.reverseSort[col])
        cmp = -cmp;

  ...
}

Now's a good time to look at the demo which incorporates some features tailored to a pair of tables containing statistics for NFL teams.

You'll notice that the tables have some styling applied to give them a more appealing look. Also, when you sort a table on a specific column, that column is highlighted and a ranking appears in the first column. We'll cover these features in a bit.

A more subtle feature is the sort order of each column. As before, you can reverse the order by clicking the same column header twice in succession, but some columns are initially sorted in ascending order while others start in descending order.

This reflects the particular statistic. The first table has offensive statistics, so the team that, say, scores the most points should appear at the top of the list when sorted. That means the initial sort order for that column should be descending. But on defense, the team that allows the least points should go to the top. So on that table, the column initially sorts in ascending order.

This is accomplished by adding a parameter to the sortTable() function.

function sortTable(id, col, rev) {

  // Get the table or table section to sort.
  var tblEl = document.getElementById(id);

  // The first time this function is called for a given table, set up
  // an array of reverse sort flags.
  if (tblEl.reverseSort == null) {
    tblEl.reverseSort = new Array();
    // Also, assume the team name column is initially sorted.
    tblEl.lastColumn = 1;
  }

  // If this column has not been sorted before, set the initial sort
  // direction.
  if (tblEl.reverseSort[col] == null)
    tblEl.reverseSort[col] = rev;

  // If this column was the last one sorted, reverse its sort direction.
  if (col == tblEl.lastColumn)
    tblEl.reverseSort[col] = !tblEl.reverseSort[col];

  // Remember this column as the last one sorted.
  tblEl.lastColumn = col;

As before, id is the id of the table section to be sorted and col is the index of the column to sort on. The rev argument is a boolean value. If true, the column will initially be sorted in reverse order.

These values are set in the onclick event for each link in the column headers. For example, the link on the "Yards" column in the offensive statistics table looks like this:

  onclick="this.blur(); return sortTable('offTblBdy',  3, true);"

While the same column in the defensive statistics table looks like this:

onclick="this.blur(); return sortTable('defTblBdy',  3, false);"

The addition of this.blur() removes the dotted outline that many browsers display around a link when it is clicked.

The "Team" Column

In the function code shown above, note that the very first time sortTable() is called for either table, we set its lastColumn property to the index of the team names column. That's because in both tables, the teams are initially sorted by name. Doing this means that if you click on the "Team" link first (before any other column in that table), it will reverse its sort order.

The team name column is treated specially in a couple of other ways too. For one, it is used as the secondary sort column whenever two rows have equal values in the primary sort column.

      cmp = compareValues(minVal, testVal);
      // Negate the comparison result if the reverse sort flag is set.
      if (tblEl.reverseSort[col])
        cmp = -cmp;
      // Sort by the second column (team name) if those values are equal.
      if (cmp == 0 && col != 1)
        cmp = compareValues(getTextValue(tblEl.rows[minIdx].cells[1]),
                            getTextValue(tblEl.rows[j].cells[1]));

In this case, the names are always sorted in ascending order.

The other case of special handling for the "Team" column deal with the way the table's appearance is altered after a sort, which we'll look at next.