faqts : Computers : Programming : Languages : JavaScript : DHTML

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

26 of 30 people (87%) answered Yes
Recently 8 of 10 people (80%) answered Yes

Entry

How can I sort a TABLE with DOM access in IE5 and NN6 using a custrom attribute/criteria and make the column flip over upon repeated clicking?

Jan 23rd, 2002 01:12
James Massey, Martin Honnen


<script>
/*
This faqt is an extention to the "How can I sort a TABLE with DOM 
access in IE5 and NN6?" faqt by Martin Honnen - thanks Martin!
Please read his faqt and the one about table sorting in Netscape 4 if 
you need support for that browser.
The following contains code has been tested in IE5.00, Netscape6.1 and 
Kmeleon0.6 (the lightweight Gecko based browser for win32).
*/
function findTableParent(node) {
  while(node.tagName.toUpperCase() != 'TABLE')
    node = node.parentNode;
  return node;
}
function createRowsArray(table) {
  var rows = new Array();
  var r = 0;
  if(table.tHead == null && table.tFoot == null)
    for(var r1 = 0; r1 < table.rows.length; r1++, r++)
      rows[r] = table.rows[r1];
  else
    for(var t = 0; t < table.tBodies.length; t++)
      for(var r1 = 0; r1 < table.tBodies[t].rows.length; r1++, r++)
        rows[r] = table.tBodies[t].rows[r1];
  return rows;
}
function insertSortedRows(table, rows) {
  if(document.all) var rowsCopy = new Array(rows.length)
  for(var r = 0; r < rows.length; r++) {
    if(document.all) rowsCopy[r] = rows[r].cloneNode(true);
    table.deleteRow(rows[r].rowIndex);
  }
  var tableSection = table.tBodies[table.tBodies.length - 1];
  for(var r = 0; r < rows.length; r++) {
    var row = document.all ? rowsCopy[r] : rows[r];
    tableSection.appendChild(row);
  }
}
function sortTable(table, sortFun) {
  var rows = createRowsArray(table);
  if(rows.length > 0) {
    rows.sort(sortFun);
    insertSortedRows(table, rows);
  }
}
function compareAlessThanB(A,B){
  return A < B ? - 1 :(A == B ? 0 : 1);
}
function compareBlessThanA(A,B){
  return B < A ? - 1 :(A == B ? 0 : 1);
}
function sortRowsAlpha(row1 , row2) {
  var column = sortRowsAlpha.col;
  var cell1 = row1.cells[column].firstChild.nodeValue;
  var cell2 = row2.cells[column].firstChild.nodeValue;
  return sortRowsAlpha.compare(cell1,cell2);
}
function sortRowsCustom(row1 , row2) {
  var column = sortRowsCustom.col;
  var cell1 = sortRowsCustom.getValue(row1.cells[column].firstChild);
  var cell2 = sortRowsCustom.getValue(row2.cells[column].firstChild);
  return sortRowsCustom.compare(cell1,cell2);
}
function sortRowsNumber(row1 , row2) {
  var column = sortRowsNumber.col;
  var cell1 = parseFloat(row1.cells[column].firstChild.nodeValue);
  var cell2 = parseFloat(row2.cells[column].firstChild.nodeValue);
  return sortRowsNumber.compare(cell1,cell2);
}
/*
  Sort a table column alphabetically.
  @param table The table to be sorted.
  @param col The column to sorted upon.
  @param direction Cause ascending order ('a' first) if null or false.
  @returns <tt>!direction</tt> so that repeated calls of the form 
<tt>direction=doSortTable(a,b,direction);</tt> cause the table column 
to alternate between ascending and descending order.
*/
function doSortTable(table, col, direction) {
  sortRowsAlpha.col = col;
  if( direction == true ){
    sortRowsAlpha.compare = compareBlessThanA;
  }
  else {
    sortRowsAlpha.compare = compareAlessThanB;
  }
  sortTable(table, sortRowsAlpha);
  return direction = (direction!=true)?true:false;
}
/*
  Sort a table column based on a custom numerical 'order' criteria of 
the cell.
  @param table The table to be sorted.
  @param col The column to sorted upon.
  @param customFunction Provides an order value given the contence of 
the cell.
  @param direction Cause ascending order if null or false.
  @returns <tt>!direction</tt> so that repeated calls of the form 
<tt>direction=doSortTable(a,b,direction);</tt> cause the table column 
to alternate between ascending and descending order.
*/
function doSortTableCustom(table, col, customFunction, direction) {
  sortRowsCustom.col = col;
  sortRowsCustom.getValue = customFunction;
  if( direction == true ){
    sortRowsCustom.compare = compareBlessThanA;
  }
  else {
    sortRowsCustom.compare = compareAlessThanB;
  }
  sortTable(table, sortRowsCustom);
  return direction = (direction!=true)?true:false;
}
/*
  Sort a table column numerically.
  @param table The table to be sorted.
  @param col The column to sorted upon.
  @param direction Cause ascending order ('1' first) if null or false.
  @returns <tt>!direction</tt> so that repeated calls of the form 
<tt>direction=doSortTable(a,b,direction);</tt> cause the table column 
to alternate between ascending and descending order.
*/
function doSortTableNumerical(table, col, direction) {
  sortRowsNumber.col = col;
  if( direction == true ){
    sortRowsNumber.compare = compareBlessThanA;
  }
  else {
    sortRowsNumber.compare = compareAlessThanB;
  }
  sortTable(table, sortRowsNumber);
  return direction = (direction!=true)?true:false;
}
/*
  The customized function returns an order value based on some property 
of the what was found in the table cell. In this case it is based on 
the color attribute of the node. We could just as easily be sorting 
based on the name of an image found in the table cell or any other 
custom criteria.
*/
function getOrderBasedOnColor(coloredNode){
  var color = coloredNode.getAttribute('color');
  var order = 0;
  if( color.indexOf('#ffa500') != -1 ){
    order = 3;
  }
  else if( color.indexOf('#ff0000') != -1 ){
    order = 5;
  }
  else if( color.indexOf('#00ff00') != -1 ){
    order = 1;
  }
  else {
    order = 0;
  }
  return order;
}
</script>
<table border="0" cellpadding="1" cellspacing="0">
  <tr valign="top">
    <td bgcolor="black">
      <table border="0" cellpadding="5" cellspacing="1" 
bgcolor="#aaaaaaaa">
        <thead>
          <tr bgcolor="#00000000">
            <th onclick="this.direction=doSortTableCustom
(findTableParent(this), this.cellIndex, getOrderBasedOnColor, 
this.direction);" color="white"><font color="white">Color (clickme)
</font></th>
            <th onclick="this.direction=doSortTableNumerical
(findTableParent(this), this.cellIndex, this.direction);" 
color="white"><font color="white">Number (clickme)</font></th>
            <th onclick="this.direction=doSortTable(findTableParent
(this), this.cellIndex, this.direction);" color="white"><font 
color="white">Text (clickme)</font></th>
          </tr>
        </thead>
        <tr>
           <td bgcolor="white"><font color="#ff0000">coloured 
text</font></td>
           <td bgcolor="white">15.0</td>
           <td bgcolor="white">some string one</td>
        </tr>
        <tr>
           <td bgcolor="white"><font color="#00ff00">coloured 
text</font></td>
           <td bgcolor="white">1.1111</td>
           <td bgcolor="white">some string two</td>
        </tr>
        <tr>
           <td bgcolor="white"><font color="#0000ff">coloured 
text</font></td>
           <td bgcolor="white">12354.6</td>
           <td bgcolor="white">another string</td>
        </tr>
        <tr>
           <td bgcolor="white"><font color="#ffa500">coloured 
text</font></td>
           <td bgcolor="white">89.8</td>
           <td bgcolor="white">yet another string</td>
        </tr>
      </table>
    </td>
  </tr>
</table>