Learning jQuery - Column Highlighting
It can be a nice user interface enhancement to visually remind the user of what has been done in the past. By highlighting the column that was most recently used for sorting, we can focus the user's attention on the part of the table that is most likely to be relevant. Fortunately, since we've already determined how to select the table cells in the column, applying a class to those cells is simple:
Sample Code
$table.find('td').removeClass('sorted')
.filter(':nth-child(' + (column + 1) + ')').addClass('sorted')
Copyright exforsys.com
Note that we have to add one to the column index we found earlier, since the :nth-child() selector is one-based rather than zero-based. With this code in place, we get a highlighted column after any sort operation:

Alternating Sort Directions
Our final sorting enhancement is to allow for both ascending and descending sort orders. When the user clicks on a column that is already sorted, we want to reverse the current sort order.
To reverse a sort, all we have to do is to invert the values returned by our comparator. We can do this with a simple variable:
Sample Code
if (a.sortKey < b.sortKey) return -newDirection
if (a.sortKey > b.sortKey) return newDirection
Copyright exforsys.com
If newDirection equals 1, then the sort will be the same as before. If it equals -1, the sort will be reversed. We can use classes to keep track of the current sort order of a column:
Sample Code
$.fn.alternateRowColors = function() {
$('tbody tr:odd', this).removeClass('even').addClass('odd')
$('tbody tr:even', this).removeClass('odd').addClass('even')
return this
}
$(document).ready(function() {
var alternateRowColors = function($table) {
$('tbody tr:odd', $table).removeClass('even').addClass('odd')
$('tbody tr:even', $table).removeClass('odd').addClass('even')
}
$('table.sortable').each(function() {
var $table = $(this)
$table.alternateRowColors($table)
$('th', $table).each(function(column) {
var findSortKey
if ($(this).is('.sort-alpha')) {
findSortKey = function($cell) {
return $cell.find('.sort-key').text().toUpperCase() + ' ' +
$cell.text().toUpperCase()
}
}
else if ($(this).is('.sort-numeric')) {
findSortKey = function($cell) {
var key = parseFloat($cell.text().replace(/^[^\d.]*/, ''))
return isNaN(key) ? 0 : key
}
}
else if ($(this).is('.sort-date')) {
findSortKey = function($cell) {
return Date.parse('1 ' + $cell.text())
}
}
if (findSortKey) {
$(this).addClass('clickable').hover(function() {
$(this).addClass('hover')
}, function() {
$(this).removeClass('hover')
}).click(function() {
+var newDirection = 1
if ($(this).is('.sorted-asc')) {
newDirection = -1
}
var rows = $table.find('tbody > tr').get()
$.each(rows, function(index, row) {
row.sortKey =
findSortKey($(row).children('td').eq(column))
})
rows.sort(function(a, b) {
if (a.sortKey < b.sortKey) return -newDirection
if (a.sortKey > b.sortKey) return newDirection
return 0
})
$.each(rows, function(index, row) {
$table.children('tbody').append(row)
row.sortKey = null
})
$table.find('th').removeClass('sorted-asc')
.removeClass('sorted-desc')
var $sortHead = $table.find('th').filter('
:nth-child(' + (column + 1) + ')')
if (newDirection == 1) {
$sortHead.addClass('sorted-asc')
} else {
$sortHead.addClass('sorted-desc')
}
$table.find('td').removeClass('sorted')
.filter(':nth-child(' + (column + 1) + ')')
.addClass('sorted')
$table.alternateRowColors($table)
})
}
})
})
})
Copyright exforsys.com
As a side benefit, since we use classes to store the sort direction we can style the columns headers to indicate the current order as well:
