Mercurial > repos > rlegendre > ribo_tools
view lightbox/js/stupidtable.js @ 8:adc01e560eae
Uploaded
author | rlegendre |
---|---|
date | Mon, 20 Oct 2014 11:34:11 -0400 |
parents | |
children |
line wrap: on
line source
// Stupid jQuery table plugin. // Call on a table // sortFns: Sort functions for your datatypes. (function($) { $.fn.stupidtable = function(sortFns) { return this.each(function() { var $table = $(this); sortFns = sortFns || {}; // ==================================================== // // Utility functions // // ==================================================== // // Merge sort functions with some default sort functions. sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns); // Return the resulting indexes of a sort so we can apply // this result elsewhere. This returns an array of index numbers. // return[0] = x means "arr's 0th element is now at x" var sort_map = function(arr, sort_function) { var map = []; var index = 0; var sorted = arr.slice(0).sort(sort_function); for (var i=0; i<arr.length; i++) { index = $.inArray(arr[i], sorted); // If this index is already in the map, look for the next index. // This handles the case of duplicate entries. while ($.inArray(index, map) != -1) { index++; } map.push(index); } return map; }; // Apply a sort map to the array. var apply_sort_map = function(arr, map) { var clone = arr.slice(0), newIndex = 0; for (var i=0; i<map.length; i++) { newIndex = map[i]; clone[newIndex] = arr[i]; } return clone; }; // ==================================================== // // Begin execution! // // ==================================================== // // Do sorting when THs are clicked $table.on("click", "th", function() { var trs = $table.children("tbody").children("tr"); var $this = $(this); var th_index = 0; var dir = $.fn.stupidtable.dir; $table.find("th").slice(0, $this.index()).each(function() { var cols = $(this).attr("colspan") || 1; th_index += parseInt(cols,10); }); // Determine (and/or reverse) sorting direction, default `asc` var sort_dir = $this.data("sort-default") || dir.ASC; if ($this.data("sort-dir")) sort_dir = $this.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC; // Choose appropriate sorting function. var type = $this.data("sort") || null; // Prevent sorting if no type defined if (type === null) { return; } // Trigger `beforetablesort` event that calling scripts can hook into; // pass parameters for sorted column index and sorting direction $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 sortMethod = sortFns[type]; // Push either the value of the `data-order-by` attribute if specified // or just the text() value in this column to column[] for comparison. trs.each(function(index,tr) { var $e = $(tr).children().eq(th_index); var sort_val = $e.data("sort-value"); var order_by = typeof(sort_val) !== "undefined" ? sort_val : $e.text(); column.push(order_by); }); // Create the sort map. This column having a sort-dir implies it was // the last column sorted. As long as no data-sort-desc is specified, // we're free to just reverse the column. var theMap; if (sort_dir == dir.ASC) theMap = sort_map(column, sortMethod); else theMap = sort_map(column, function(a, b) { return -sortMethod(a, b); }); // Reset siblings $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc"); $this.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir); var sortedTRs = $(apply_sort_map(trs, theMap)); $table.children("tbody").remove(); $table.append("<tbody />").append(sortedTRs); // Trigger `aftertablesort` event. Similar to `beforetablesort` $table.trigger("aftertablesort", {column: th_index, direction: sort_dir}); // More reliable method of forcing a redraw $table.css("display"); }, 10); }); }); }; // Enum containing sorting directions $.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) { if (a < b) return -1; if (a > b) return +1; return 0; }, "string-ins": function(a, b) { a = a.toLowerCase(); b = b.toLowerCase(); if (a < b) return -1; if (a > b) return +1; return 0; } }; })(jQuery);