Martin Martin - 1 month ago 7
jQuery Question

Sort table by background-color of last cell in row

Is it possible to sort a table on page load by a css attribute of the las cell in a row? I want the table rows sorted by the bg-color of it's last cell.

Table:

<table>
<tr>
<td>Foo</td>
<td>Foo</td>
<td style="font-weight:bold; background-color:#dee">Foo</td>
</tr>
<tr>
<td>Foo</td>
<td>Foo</td>
<td style="background-color:#ffa">Foo</td>
</tr>
<tr>
<td>put me on top</td>
<td>Foo</td>
<td style="background-color:#eee">Foo</td>
</tr>
</table>


I have no idea where to start but I can alert the colors as RGB at least:

$("table tr").find("td:last").each(function(index) {
alert($(this).css("background-color"));
});


Test: http://jsfiddle.net/AqTTJ/6/

Answer

The following code sorts rows by a manual key or by background-color integer values. You can try it out here on jsFiddle.

JavaScript

$(document).ready(function() {
  // Variable declarations:
  var tableId = '#table';
  var autoSort = true;
  var rowArr = getRows(tableId);
  var keySort = [];

  // Add a click handler to the sort button
  // that will call autoSortKeys() and pass
  // in either a manual key array or an
  // auto-sorted array.
  $('#sort').click(function() {
    autoSort = $('#autoSort').is(':checked');
    keySort = autoSort
        ? autoSortKeys(rowArr)
        : [0xffee77, 0xaaffaa, 0xff6666];
    sortTable(tableId, rowArr, keySort);
  });
});

// Sorts a table based on the array of
// keys that are passed into the function.
function sortTable(tableId, rows, keys) {
  $(tableId).empty();
  $.each(keys, function(indexK, valueK) {
    $.each(rows, function(indexR, valueR) {
      if (valueR[0] === valueK) {
        $(tableId).append(valueR[1]);
      }
    });
  });
}

// Converts an rgb() value returned from Jquery
// into an integer value for comparison.
function rgbToInt(color) {
  var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
  var red = parseInt(digits[2]);
  var green = parseInt(digits[3]);
  var blue = parseInt(digits[4]);
  return parseInt((blue | (green << 8) | (red << 16)), 10);
};

// Stores every row in a table designated table
// as a sub-array comprised of the background color
// integer value and the row DOM element.
function getRows(tableId) {
  var arr = new Array();
  $(tableId+' tr').each(function() {
    var bg = $(this).find('td:last-child').css('backgroundColor');
    var key = rgbToInt(bg);
    arr.push([key, $(this)]); // [bg-color, <tr />]
  });
  return arr;
}

// Automatically sorts rows based on their background
// color integer value from highest to lowest.
function autoSortKeys(arr) {
  var keys = new Array();
  $.each(arr, function(index, value) {
    keys.push(value[0]);
  });
  var uniqueKeys = new Array();
  $.each(keys, function(index, value){
    if($.inArray(value, uniqueKeys ) === -1)
      uniqueKeys.push(value);
  });
  delete keys; // garbage collect
  return uniqueKeys .sort().reverse();
}

HTML

<table id="table">
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="font-weight:bold; background-color:#fe7">One</td>
  </tr>
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="font-weight:bold; background-color:#fe7">One</td>
  </tr>
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="background-color:#f66">Three</td>
  </tr>
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="font-weight:bold; background-color:#fe7">One</td>
  </tr>
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="background-color:#afa">Two</td>
  </tr>
  <tr>
    <td>Foo</td>
    <td>Foo</td>
    <td style="background-color:#f66">Three</td>
  </tr>
</table>
<br />
<label for="autoSort"> Auto Sort </label>
<input type="checkbox" id="autoSort" checked="CHECKED" />
<input type="button" id="sort" value="Sort" />
Comments