mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
new natural sort algorithm
This commit is contained in:
parent
ebf50c950a
commit
1ac4778369
BIN
README.markdown
BIN
README.markdown
Binary file not shown.
@ -148,7 +148,7 @@
|
|||||||
|
|
||||||
<div class="next-up">
|
<div class="next-up">
|
||||||
<hr />
|
<hr />
|
||||||
Next up: <a href="example-option-digits.html">Dealing with digits! ››</a>
|
Next up: <a href="example-multiple-tbodies.html">Sorting with Multiple Tbodies ››</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
100
docs/example-multiple-tbodies.html
Normal file
100
docs/example-multiple-tbodies.html
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>jQuery plugin: Tablesorter 2.0 - Sorting with Multiple Tbodies</title>
|
||||||
|
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Demo stuff -->
|
||||||
|
<link rel="stylesheet" href="css/jq.css">
|
||||||
|
<script src="js/chili/jquery.chili-2.2.js"></script>
|
||||||
|
<script src="js/chili/recipes.js"></script>
|
||||||
|
<script src="js/docs.js"></script>
|
||||||
|
|
||||||
|
<!-- Tablesorter: required -->
|
||||||
|
<link rel="stylesheet" href="../css/blue/style.css">
|
||||||
|
<script src="../js/jquery.tablesorter.js"></script>
|
||||||
|
|
||||||
|
<script id="js">$(function() {
|
||||||
|
|
||||||
|
$("table").tablesorter({
|
||||||
|
cssInfoBlock : "tablesorter-no-sort"
|
||||||
|
});
|
||||||
|
|
||||||
|
});</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="banner">
|
||||||
|
<h1>table<em>sorter</em></h1>
|
||||||
|
<h2>Sorting with Multiple Tbodies</h2>
|
||||||
|
<h3>Flexible client-side table sorting</h3>
|
||||||
|
<a href="index.html">Back to documentation</a>
|
||||||
|
</div>
|
||||||
|
<div id="main">
|
||||||
|
<h1>Demo</h1>
|
||||||
|
<div id="demo"><table class="sortable">
|
||||||
|
<thead>
|
||||||
|
<tr><th>Name</th><th>A-head</th><th>B-head</th><th>C-head</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tfoot>
|
||||||
|
<tr><th>Name</th><th>A-foot</th><th>B-foot</th><th>C-foot</th></tr>
|
||||||
|
</tfoot>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr><td>DDD</td><td>r1c1</td><td>r1c2</td><td>r1c3</td></tr>
|
||||||
|
<tr><td>AAA</td><td>r2c1</td><td>r2c2</td><td>r2c3</td></tr>
|
||||||
|
<tr><td>CCC</td><td>r3c1</td><td>r3c2</td><td>r3c3</td></tr>
|
||||||
|
<tr><td>BBB</td><td>r4c1</td><td>r4c2</td><td>r4c3</td></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- add "tablesorter-no-sort" class to skip sorting of this tbody -->
|
||||||
|
<tbody class="tablesorter-no-sort">
|
||||||
|
<tr><th colspan="4">summary info for the first group</th></tr>
|
||||||
|
<tr><th colspan="4">Another row referring to the first group</th></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr><td>Zorro</td><td>r5c1</td><td>r5c2</td><td>r5c3</td></tr>
|
||||||
|
<tr><td>Caleb</td><td>r6c1</td><td>r6c2</td><td>r6c3</td></tr>
|
||||||
|
<tr><td>Momo</td><td>r7c1</td><td>r7c2</td><td>r7c3</td></tr>
|
||||||
|
<tr><td>Wolfie</td><td>r8c1</td><td>r8c2</td><td>r8c3</td></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="tablesorter-no-sort">
|
||||||
|
<tr><th colspan="4">summary info for the second group</th></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr><td>Ulysses</td><td>r9c1</td><td>r9c2</td><td>r9c3</td></tr>
|
||||||
|
<tr><td>Penelope</td><td>r10c1</td><td>r10c2</td><td>r10c3</td></tr>
|
||||||
|
<tr><td>Edvald</td><td>r11c1</td><td>r11c2</td><td>r11c3</td></tr>
|
||||||
|
<tr><td>Jan</td><td>r12c1</td><td>r12c2</td><td>r12c3</td></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="tablesorter-no-sort">
|
||||||
|
<tr><th colspan="4">summary info for the last group</th></tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
</table></div>
|
||||||
|
|
||||||
|
<h1>Javascript</h1>
|
||||||
|
<div id="javascript">
|
||||||
|
<pre class="js"></pre>
|
||||||
|
</div>
|
||||||
|
<h1>HTML</h1>
|
||||||
|
<div id="html">
|
||||||
|
<pre class="html"></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="next-up">
|
||||||
|
<hr />
|
||||||
|
Next up: <a href="example-option-digits.html">Dealing with digits! ››</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -294,6 +294,7 @@
|
|||||||
<li><a href="example-option-sort-key.html">Change the default multi-sorting key</a></li>
|
<li><a href="example-option-sort-key.html">Change the default multi-sorting key</a></li>
|
||||||
<li><a href="example-option-custom-sort.html">Custom sort script</a> <span class="tip"><em>New!</em></span> v2.2</li>
|
<li><a href="example-option-custom-sort.html">Custom sort script</a> <span class="tip"><em>New!</em></span> v2.2</li>
|
||||||
<li><a href="example-locale-sort.html">Sorting Accented Characters</a> <span class="tip"><em>New!</em></span> v2.2</li>
|
<li><a href="example-locale-sort.html">Sorting Accented Characters</a> <span class="tip"><em>New!</em></span> v2.2</li>
|
||||||
|
<li><a href="example-multiple-tbodies.html">Sorting with Multiple Tbodies</a> <span class="tip"><em>New!</em></span> v2.2</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4>Parsers / Extracting Content</h4>
|
<h4>Parsers / Extracting Content</h4>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* TableSorter 2.2.1 - Client-side table sorting with ease!
|
* TableSorter 2.2.2 - Client-side table sorting with ease!
|
||||||
* @requires jQuery v1.2.6+
|
* @requires jQuery v1.2.6+
|
||||||
*
|
*
|
||||||
* Copyright (c) 2007 Christian Bach
|
* Copyright (c) 2007 Christian Bach
|
||||||
@ -18,7 +18,7 @@
|
|||||||
$.extend({
|
$.extend({
|
||||||
tablesorter: new function() {
|
tablesorter: new function() {
|
||||||
|
|
||||||
this.version = "2.2.1";
|
this.version = "2.2.2";
|
||||||
|
|
||||||
var parsers = [], widgets = [], tbl;
|
var parsers = [], widgets = [], tbl;
|
||||||
this.defaults = {
|
this.defaults = {
|
||||||
@ -26,7 +26,7 @@
|
|||||||
cssAsc: "tablesorter-headerSortUp",
|
cssAsc: "tablesorter-headerSortUp",
|
||||||
cssDesc: "tablesorter-headerSortDown",
|
cssDesc: "tablesorter-headerSortDown",
|
||||||
cssChildRow: "expand-child",
|
cssChildRow: "expand-child",
|
||||||
cssInfoBlock: "tablesorter-infoOnly",
|
cssInfoBlock: "tablesorter-infoOnly", // don't sort tbody with this class name
|
||||||
sortInitialOrder: "asc",
|
sortInitialOrder: "asc",
|
||||||
sortMultiSortKey: "shiftKey",
|
sortMultiSortKey: "shiftKey",
|
||||||
sortForce: null,
|
sortForce: null,
|
||||||
@ -224,9 +224,10 @@
|
|||||||
}
|
}
|
||||||
for (k = 0; k < b.length; k++) {
|
for (k = 0; k < b.length; k++) {
|
||||||
tc.cache[k] = { row: [], normalized: [] };
|
tc.cache[k] = { row: [], normalized: [] };
|
||||||
|
// ignore tbodies with class name from css.cssInfoBlock
|
||||||
|
if (!$(b[k]).hasClass(tc.cssInfoBlock)) {
|
||||||
totalRows = (b[k] && b[k].rows.length) || 0;
|
totalRows = (b[k] && b[k].rows.length) || 0;
|
||||||
totalCells = (b[k].rows[0] && b[k].rows[0].cells.length) || 0;
|
totalCells = (b[k].rows[0] && b[k].rows[0].cells.length) || 0;
|
||||||
|
|
||||||
for (i = 0; i < totalRows; ++i) {
|
for (i = 0; i < totalRows; ++i) {
|
||||||
/** Add the table data to main data array */
|
/** Add the table data to main data array */
|
||||||
c = $(b[k].rows[i]);
|
c = $(b[k].rows[i]);
|
||||||
@ -247,6 +248,7 @@
|
|||||||
tc.cache[k].normalized.push(cols);
|
tc.cache[k].normalized.push(cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (tc.debug) {
|
if (tc.debug) {
|
||||||
benchmark("Building cache for " + totalRows + " rows", cacheTime);
|
benchmark("Building cache for " + totalRows + " rows", cacheTime);
|
||||||
}
|
}
|
||||||
@ -287,6 +289,7 @@
|
|||||||
appendTime = new Date();
|
appendTime = new Date();
|
||||||
}
|
}
|
||||||
for (k = 0; k < b.length; k++) {
|
for (k = 0; k < b.length; k++) {
|
||||||
|
if (!$(b[k]).hasClass(c.cssInfoBlock)){
|
||||||
f = document.createDocumentFragment();
|
f = document.createDocumentFragment();
|
||||||
r = c.cache[k].row;
|
r = c.cache[k].row;
|
||||||
n = c.cache[k].normalized;
|
n = c.cache[k].normalized;
|
||||||
@ -305,6 +308,7 @@
|
|||||||
}
|
}
|
||||||
table.tBodies[k].appendChild(f);
|
table.tBodies[k].appendChild(f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (c.appender) {
|
if (c.appender) {
|
||||||
c.appender(table, rows);
|
c.appender(table, rows);
|
||||||
}
|
}
|
||||||
@ -417,24 +421,6 @@
|
|||||||
return $tableHeaders;
|
return $tableHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part of original tablesorter - not even called.
|
|
||||||
function checkCellColSpan(table, rows, row) {
|
|
||||||
var i, cell, arr = [],
|
|
||||||
r = table.tHead.rows,
|
|
||||||
c = r[row].cells;
|
|
||||||
for (i = 0; i < c.length; i++) {
|
|
||||||
cell = c[i];
|
|
||||||
if (cell.colSpan > 1) {
|
|
||||||
arr = arr.concat(checkCellColSpan(table, rows, row++)); // what is headerArr?
|
|
||||||
} else {
|
|
||||||
if (table.tHead.length === 1 || (cell.rowSpan > 1 || !r[row + 1])) {
|
|
||||||
arr.push(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValueInArray(v, a) {
|
function isValueInArray(v, a) {
|
||||||
var i, l = a.length;
|
var i, l = a.length;
|
||||||
for (i = 0; i < l; i++) {
|
for (i = 0; i < l; i++) {
|
||||||
@ -535,35 +521,41 @@
|
|||||||
// Natural sort modified from: http://www.webdeveloper.com/forum/showthread.php?t=107909
|
// Natural sort modified from: http://www.webdeveloper.com/forum/showthread.php?t=107909
|
||||||
function sortText(a, b, col) {
|
function sortText(a, b, col) {
|
||||||
if (a === b) { return 0; }
|
if (a === b) { return 0; }
|
||||||
var c = tbl[0].config, cnt = 0, L, t, x, e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
var c = tbl[0].config, e = c.string[ (c.empties[col] || c.emptyTo ) ],
|
||||||
|
r = $.tablesorter.regex, xN, xD, yN, yD, xF, yF, i, mx;
|
||||||
if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : -e || -1; }
|
if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : -e || -1; }
|
||||||
if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : e || 1; }
|
if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : e || 1; }
|
||||||
if (typeof c.textSorter === 'function') { return c.textSorter(a, b); }
|
if (typeof c.textSorter === 'function') { return c.textSorter(a, b); }
|
||||||
// if (c.sortLocaleCompare) { return a.localeCompare(b); }
|
// natural sort - https://github.com/overset/javascript-natural-sort
|
||||||
try {
|
// chunk/tokenize
|
||||||
x = /^(\.)?\d/;
|
xN = a.replace(r[0], '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
|
||||||
L = Math.min(a.length, b.length) + 1;
|
yN = b.replace(r[0], '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
|
||||||
while (cnt < L && a.charAt(cnt) === b.charAt(cnt) && x.test(b.substring(cnt)) === false && x.test(a.substring(cnt)) === false) { cnt++; }
|
// numeric, hex or date detection
|
||||||
a = a.substring(cnt);
|
xD = parseInt(a.match(r[2])) || (xN.length !== 1 && a.match(r[1]) && Date.parse(a));
|
||||||
b = b.substring(cnt);
|
yD = parseInt(b.match(r[2])) || (xD && b.match(r[1]) && Date.parse(b)) || null;
|
||||||
if (x.test(a) || x.test(b)) {
|
// first try and sort Hex codes or Dates
|
||||||
if (x.test(a) === false) {
|
if (yD) {
|
||||||
return (a) ? 1 : -1;
|
if ( xD < yD ) { return -1; }
|
||||||
} else if (x.test(b) === false) {
|
if ( xD > yD ) { return 1; }
|
||||||
return (b) ? -1 : 1;
|
|
||||||
} else {
|
|
||||||
t = parseFloat(a) - parseFloat(b);
|
|
||||||
if (t !== 0) { return t; } else { t = a.search(/[^\.\d]/); }
|
|
||||||
if (t === -1) { t = b.search(/[^\.\d]/); }
|
|
||||||
a = a.substring(t);
|
|
||||||
b = b.substring(t);
|
|
||||||
}
|
}
|
||||||
|
mx = Math.max(xN.length, yN.length);
|
||||||
|
// natural sorting through split numeric strings and default strings
|
||||||
|
for (i = 0; i < mx; i++) {
|
||||||
|
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
|
||||||
|
xF = (!(xN[i] || '').match(r[3]) && parseFloat(xN[i])) || xN[i] || 0;
|
||||||
|
yF = (!(yN[i] || '').match(r[3]) && parseFloat(yN[i])) || yN[i] || 0;
|
||||||
|
// handle numeric vs string comparison - number < string - (Kyle Adams)
|
||||||
|
if (isNaN(xF) !== isNaN(yF)) { return (isNaN(xF)) ? 1 : -1; }
|
||||||
|
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
|
||||||
|
if (typeof xF !== typeof yF) {
|
||||||
|
xF += '';
|
||||||
|
yF += '';
|
||||||
|
}
|
||||||
|
if (xF < yF) { return -1; }
|
||||||
|
if (xF > yF) { return 1; }
|
||||||
}
|
}
|
||||||
return (a > b) ? 1 : -1;
|
|
||||||
} catch (er) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function sortTextDesc(a, b, col) {
|
function sortTextDesc(a, b, col) {
|
||||||
if (a === b) { return 0; }
|
if (a === b) { return 0; }
|
||||||
@ -571,7 +563,6 @@
|
|||||||
if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : e || 1; }
|
if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : e || 1; }
|
||||||
if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : -e || -1; }
|
if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : -e || -1; }
|
||||||
if (typeof c.textSorter === 'function') { return c.textSorter(b, a); }
|
if (typeof c.textSorter === 'function') { return c.textSorter(b, a); }
|
||||||
// if (c.sortLocaleCompare) { return b.localeCompare(a); }
|
|
||||||
return sortText(b, a);
|
return sortText(b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,6 +827,13 @@
|
|||||||
// replace all unwanted chars and match.
|
// replace all unwanted chars and match.
|
||||||
return (/^[\-+(]?\d*[)]?$/).test($.trim(s.replace(/[,.'\s]/g, '')));
|
return (/^[\-+(]?\d*[)]?$/).test($.trim(s.replace(/[,.'\s]/g, '')));
|
||||||
};
|
};
|
||||||
|
// regex used in natural sort
|
||||||
|
this.regex = [
|
||||||
|
/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, // chunk/tokenize numbers & letters
|
||||||
|
/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, //date
|
||||||
|
/^0x[0-9a-f]+$/i, // hex
|
||||||
|
/^0/ // leading zeros
|
||||||
|
];
|
||||||
// used when replacing accented characters during sorting
|
// used when replacing accented characters during sorting
|
||||||
this.characterEquivalents = {
|
this.characterEquivalents = {
|
||||||
"a" : "\u00e1\u00e0\u00e2\u00e3\u00e4", // áàâãä
|
"a" : "\u00e1\u00e0\u00e2\u00e3\u00e4", // áàâãä
|
||||||
@ -1030,7 +1028,7 @@
|
|||||||
ts.addWidget({
|
ts.addWidget({
|
||||||
id: "zebra",
|
id: "zebra",
|
||||||
format: function(table) {
|
format: function(table) {
|
||||||
var $tr, row, even, time, k,
|
var $tr, $r, row, even, time, k,
|
||||||
c = table.config,
|
c = table.config,
|
||||||
child = c.cssChildRow,
|
child = c.cssChildRow,
|
||||||
b = table.tBodies,
|
b = table.tBodies,
|
||||||
@ -1047,11 +1045,11 @@
|
|||||||
$tr = $(b[k]).filter(':not(' + c.cssInfoBlock + ')').find('tr:visible:not(.' + c.cssInfoBlock + ')');
|
$tr = $(b[k]).filter(':not(' + c.cssInfoBlock + ')').find('tr:visible:not(.' + c.cssInfoBlock + ')');
|
||||||
if ($tr.length > 1) {
|
if ($tr.length > 1) {
|
||||||
$tr.each(function() {
|
$tr.each(function() {
|
||||||
$tr = $(this);
|
$r = $(this);
|
||||||
// style children rows the same way the parent row was styled
|
// style children rows the same way the parent row was styled
|
||||||
if (!$tr.hasClass(child)) { row++; }
|
if (!$r.hasClass(child)) { row++; }
|
||||||
even = (row % 2 === 0);
|
even = (row % 2 === 0);
|
||||||
$tr
|
$r
|
||||||
.removeClass(css[even ? 1 : 0])
|
.removeClass(css[even ? 1 : 0])
|
||||||
.addClass(css[even ? 0 : 1]);
|
.addClass(css[even ? 0 : 1]);
|
||||||
});
|
});
|
||||||
|
4
js/jquery.tablesorter.min.js
vendored
4
js/jquery.tablesorter.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tablesorter",
|
"name": "tablesorter",
|
||||||
"version": "2.2.1",
|
"version": "2.2.2",
|
||||||
"title": "tablesorter",
|
"title": "tablesorter",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Christian Bach",
|
"name": "Christian Bach",
|
||||||
|
Loading…
Reference in New Issue
Block a user