Learning jQuery - Sorting Other Types of Data
Our sort routine should be able to handle not just the Title and Author columns, but the Publish Dates and Price as well. Since we streamlined our comparator function, it can handle all kinds of data, but the computed keys will need to be adjusted for other data types. For example, in the case of prices we need to strip off the leading $ character and parse the rest, then compare them:
var key = parseFloat ($cell.text ().replace (/^ [^\d. ]*/, '')); row.sortKey = isNaN (key) ? 0 : key;
var%20key%20%3D%20parseFloat%28%24cell.text%28%29.replace%28%2F%5E%5B%5E%5Cd.%5D%2A%2F%2C%20%27%27%29%29%3B%0A%0D%0Arow.sortKey%20%3D%20isNaN%28key%29%20%3F%200%20%3A%20key%3B
The result of parseFloat() needs to be checked, because if no number can be extracted from the text, NaN is returned, which can wreak havoc on .sort(). For the date cells, we can use the JavaScript Date object:
row.sortKey = Date.parse ('1 ' + $cell.text ());
row.sortKey%20%3D%20Date.parse%28%271%20%27%20%2B%20%24cell.text%28%29%29%3B
The dates in this table contain a month and year only; Date.parse() requires a fully‑specified date, so we prepend the string with 1. This provides a day to complement the month and year, and the combination is then converted into a timestamp, which can be sorted using our normal comparator.
We can apportion these expressions across separate functions, and call the appropriate one based on the class applied to the table header:
$.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. ]*/, '')); }; } 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 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 -1; if (a.sortKey > b.sortKey) return 1; return 0; }); $. each(rows, function(index, row ) { $table.children('tbody').append(row); row.sortKey = null; }); $table.alternateRowColors($table); }); } }); }); });
%24.fn.alternateRowColors%20%3D%20function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28%27tbody%20tr%3Aodd%27%2C%20this%29.removeClass%28%27even%27%29.addClass%28%27odd%27%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28%27tbody%20tr%3Aeven%27%2C%20this%29.removeClass%28%27odd%27%29.addClass%28%27even%27%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20return%20this%3B%0A%0D%0A%20%20%20%20%7D%3B%0A%0D%0A%20%20%20%20%24%28document%29.ready%28function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20var%20alternateRowColors%20%3D%20function%28%24table%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28%27tbody%20tr%3Aodd%27%2C%20%24table%29.removeClass%28%27even%27%29.addClass%28%27odd%27%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28%27tbody%20tr%3Aeven%27%2C%20%24table%29.removeClass%28%27odd%27%29.addClass%28%27even%27%29%3B%0A%0D%0A%20%20%20%20%7D%3B%0A%0D%0A%20%20%20%20%24%28%27table.sortable%27%29.each%28function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20var%20%24table%20%3D%20%24%28this%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%24table.alternateRowColors%28%24table%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28%27th%27%2C%20%24table%29.each%28function%28column%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20var%20findSortKey%3B%0A%0D%0A%20%20%20%20%20%20%20%20if%20%28%24%28this%29.is%28%27.sort-alpha%27%29%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20findSortKey%20%3D%20function%28%24cell%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24cell.find%28%27.sort-key%27%29.text%28%29.toUpperCase%28%29%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%27%20%27%20%2B%20%24cell.text%28%29.toUpperCase%28%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%0D%0A%20%20%20%20%20%20%20%20%7D%0A%0D%0A%20%20%20%20%20%20%20%20else%20if%20%28%24%28this%29.is%28%27.sort-numeric%27%29%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20findSortKey%20%3D%20function%28%24cell%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20key%20%3D%20parseFloat%28%24cell.text%28%29.replace%28%2F%5E%5B%5E%5Cd.%5D%2A%2F%2C%20%27%27%29%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN%28key%29%20%3F%200%20%3A%20key%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%0D%0A%20%20%20%20%20%20%20%20%7D%0A%0D%0A%20%20%20%20%20%20%20%20else%20if%20%28%24%28this%29.is%28%27.sort-date%27%29%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20findSortKey%20%3D%20function%28%24cell%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20Date.parse%28%271%20%27%20%2B%20%24cell.text%28%29%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%0D%0A%20%20%20%20%7D%0A%0D%0A%20%20%20%20if%20%28findSortKey%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28this%29.addClass%28%27clickable%27%29.hover%28function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%24%28this%29.addClass%28%27hover%27%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%7D%2C%20function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24%28this%29.removeClass%28%27hover%27%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%29.click%28function%28%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20rows%20%3D%20%24table.find%28%27tbody%20%3E%20tr%27%29.get%28%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24.each%28rows%2C%20function%28index%2C%20row%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20row.sortKey%20%3D%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20findSortKey%28%24%28row%29.children%28%27td%27%29.eq%28column%29%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20rows.sort%28function%28a%2C%20b%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28a.sortKey%20%3C%20b.sortKey%29%20return%20-1%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28a.sortKey%20%3E%20b.sortKey%29%20return%201%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%200%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24.each%28rows%2C%20function%28index%2C%20row%29%20%7B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24table.children%28%27tbody%27%29.append%28row%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20row.sortKey%20%3D%20null%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24table.alternateRowColors%28%24table%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%0D%0A%20%20%20%20%20%20%20%20%7D%0A%0D%0A%20%20%20%20%7D%29%3B%0A%0D%0A%7D%29%3B%0A%0D%0A%7D%29%3B
The findSortKey variable doubles as the function to calculate the key and a flag to indicate whether the column header is marked with a class making it sortable. We can now sort on date or price:

Trackback(0)
|