|
// Stupid jQuery table plugin. |
|
|
|
(function($) { |
|
$.fn.stupidtable = function(sortFns) { |
|
return this.each(function() { |
|
var $table = $(this); |
|
sortFns = sortFns || {}; |
|
sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns); |
|
$table.data('sortFns', sortFns); |
|
|
|
$table.on("click.stupidtable", "thead th", function() { |
|
$(this).stupidsort(); |
|
}); |
|
}); |
|
}; |
|
|
|
|
|
// Expects $("#mytable").stupidtable() to have already been called. |
|
// Call on a table header. |
|
$.fn.stupidsort = function(force_direction){ |
|
var $this_th = $(this); |
|
var th_index = 0; // we'll increment this soon |
|
var dir = $.fn.stupidtable.dir; |
|
var $table = $this_th.closest("table"); |
|
var datatype = $this_th.data("sort") || null; |
|
|
|
// No datatype? Nothing to do. |
|
if (datatype === null) { |
|
return; |
|
} |
|
|
|
// Account for colspans |
|
$this_th.parents("tr").find("th").slice(0, $(this).index()).each(function() { |
|
var cols = $(this).attr("colspan") || 1; |
|
th_index += parseInt(cols,10); |
|
}); |
|
|
|
var sort_dir; |
|
if(arguments.length == 1){ |
|
sort_dir = force_direction; |
|
} |
|
else{ |
|
sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC; |
|
if ($this_th.data("sort-dir")) |
|
sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC; |
|
} |
|
|
|
|
|
$table.trigger("beforetablesort", {column: th_index, direction: sort_dir}); |
|
|
|
// More reliable method of forcing a redraw |
|
$table.css("display"); |
|
|
|
// Run sorting asynchronously on a timout to force browser redraw after |
|
// `beforetablesort` callback. Also avoids locking up the browser too much. |
|
setTimeout(function() { |
|
// Gather the elements for this column |
|
var column = []; |
|
var sortFns = $table.data('sortFns'); |
|
var sortMethod = sortFns[datatype]; |
|
var trs = $table.children("tbody").children("tr"); |
|
|
|
// Extract the data for the column that needs to be sorted and pair it up |
|
// with the TR itself into a tuple. This way sorting the values will |
|
// incidentally sort the trs. |
|
trs.each(function(index,tr) { |
|
var $e = $(tr).children().eq(th_index); |
|
var sort_val = $e.data("sort-value"); |
|
|
|
// Store and read from the .data cache for display text only sorts |
|
// instead of looking through the DOM every time |
|
if(typeof(sort_val) === "undefined"){ |
|
var txt = $e.text(); |
|
$e.data('sort-value', txt); |
|
sort_val = txt; |
|
} |
|
column.push([sort_val, tr]); |
|
}); |
|
|
|
// Sort by the data-order-by value |
|
column.sort(function(a, b) { return sortMethod(a[0], b[0]); }); |
|
if (sort_dir != dir.ASC) |
|
column.reverse(); |
|
|
|
// Replace the content of tbody with the sorted rows. Strangely |
|
// enough, .append accomplishes this for us. |
|
trs = $.map(column, function(kv) { return kv[1]; }); |
|
$table.children("tbody").append(trs); |
|
|
|
// Reset siblings |
|
$table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc"); |
|
$this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir); |
|
|
|
$table.trigger("aftertablesort", {column: th_index, direction: sort_dir}); |
|
$table.css("display"); |
|
}, 10); |
|
|
|
return $this_th; |
|
}; |
|
|
|
// Call on a sortable td to update its value in the sort. This should be the |
|
// only mechanism used to update a cell's sort value. If your display value is |
|
// different from your sort value, use jQuery's .text() or .html() to update |
|
// the td contents, Assumes stupidtable has already been called for the table. |
|
$.fn.updateSortVal = function(new_sort_val){ |
|
var $this_td = $(this); |
|
if($this_td.is('[data-sort-value]')){ |
|
// For visual consistency with the .data cache |
|
$this_td.attr('data-sort-value', new_sort_val); |
|
} |
|
$this_td.data("sort-value", new_sort_val); |
|
return $this_td; |
|
}; |
|
|
|
// ------------------------------------------------------------------ |
|
// Default settings |
|
// ------------------------------------------------------------------ |
|
$.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"}; |
|
$.fn.stupidtable.default_sort_fns = { |
|
"int": function(a, b) { |
|
return parseInt(a, 10) - parseInt(b, 10); |
|
}, |
|
"float": function(a, b) { |
|
return parseFloat(a) - parseFloat(b); |
|
}, |
|
"string": function(a, b) { |
|
return a.localeCompare(b); |
|
}, |
|
"string-ins": function(a, b) { |
|
a = a.toLocaleLowerCase(); |
|
b = b.toLocaleLowerCase(); |
|
return a.localeCompare(b); |
|
} |
|
}; |
|
})(jQuery); |