mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Modified sorting algorithms; Add sortStable. Fixes #419.
Moved empty cell coding back inside of sort functions; fixes multi-column sorting with empty cells.
This commit is contained in:
parent
dfd7b7cea0
commit
c5a7109f2a
@ -1178,6 +1178,19 @@ From the example function above, you'll end up with something similar to this HT
|
|||||||
<td><a href="example-option-sortreset-sortrestart.html">Example</a></td>
|
<td><a href="example-option-sortreset-sortrestart.html">Example</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr id="sortstable">
|
||||||
|
<td><a href="#" class="permalink">sortStable</a></td>
|
||||||
|
<td>Boolean</td>
|
||||||
|
<td>false</td>
|
||||||
|
<td>
|
||||||
|
Setting this option to <code>true</code> and sorting two rows with exactly the same content, the original sort order is maintained (<span class="version">v2.14</span>).
|
||||||
|
<div class="collapsible"><br>
|
||||||
|
This isn't exactly a <a href="http://en.wikipedia.org/wiki/Unstable_sort#Stability">stable sort</a> because the sort order maintains the original unsorted order when sorting the column in an ascending direction. When sorting the column in a descending order, the opposite of the original unsorted order is returned. If that doesn't make any sense, please refer to <a href="">issue #
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr id="sortmultisortkey">
|
<tr id="sortmultisortkey">
|
||||||
<td><span class="permalink">sortMultiSortKey</span></td>
|
<td><span class="permalink">sortMultiSortKey</span></td>
|
||||||
<td>String</td>
|
<td>String</td>
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
sortForce : null, // column(s) first sorted; always applied
|
sortForce : null, // column(s) first sorted; always applied
|
||||||
sortList : [], // Initial sort order; applied initially; updated when manually sorted
|
sortList : [], // Initial sort order; applied initially; updated when manually sorted
|
||||||
sortAppend : null, // column(s) sorted last; always applied
|
sortAppend : null, // column(s) sorted last; always applied
|
||||||
|
sortStable : false, // when sorting two rows with exactly the same content, the original sort order is maintained
|
||||||
|
|
||||||
sortInitialOrder : 'asc', // sort direction on first click
|
sortInitialOrder : 'asc', // sort direction on first click
|
||||||
sortLocaleCompare: false, // replace equivalent character (accented characters)
|
sortLocaleCompare: false, // replace equivalent character (accented characters)
|
||||||
@ -665,14 +666,9 @@
|
|||||||
// sort direction, true = asc, false = desc
|
// sort direction, true = asc, false = desc
|
||||||
dir = order === 0;
|
dir = order === 0;
|
||||||
|
|
||||||
// set a & b depending on sort direction
|
if (c.sortStable && a[col] === b[col] && l === 1) {
|
||||||
x = dir ? a : b;
|
return a[orgOrderCol] - b[orgOrderCol];
|
||||||
y = dir ? b : a;
|
}
|
||||||
|
|
||||||
// determine how to sort empty cells
|
|
||||||
e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
|
||||||
if (x[col] === '' && e !== 0) { return ((typeof(e) === 'boolean') ? (e ? -1 : 1) : (e || 1)) * (dir ? 1 : -1); }
|
|
||||||
if (y[col] === '' && e !== 0) { return ((typeof(e) === 'boolean') ? (e ? 1 : -1) : (-e || -1)) * (dir ? 1 : -1); }
|
|
||||||
|
|
||||||
// fallback to natural sort since it is more robust
|
// fallback to natural sort since it is more robust
|
||||||
num = /n/i.test(getCachedSortType(c.parsers, col));
|
num = /n/i.test(getCachedSortType(c.parsers, col));
|
||||||
@ -685,8 +681,12 @@
|
|||||||
}
|
}
|
||||||
// fall back to built-in numeric sort
|
// fall back to built-in numeric sort
|
||||||
// var sort = $.tablesorter["sort" + s](table, a[c], b[c], c, colMax[c], dir);
|
// var sort = $.tablesorter["sort" + s](table, a[c], b[c], c, colMax[c], dir);
|
||||||
sort = c.numberSorter ? c.numberSorter(x[col], y[col], dir, colMax[col], table) : ts.sortNumeric(x[col], y[col], num, colMax[col]);
|
sort = c.numberSorter ? c.numberSorter(x[col], y[col], dir, colMax[col], table) :
|
||||||
|
ts[ 'sortNumeric' + (dir ? 'Asc' : 'Desc') ](a[col], b[col], num, colMax[col], col, table);
|
||||||
} else {
|
} else {
|
||||||
|
// set a & b depending on sort direction
|
||||||
|
x = dir ? a : b;
|
||||||
|
y = dir ? b : a;
|
||||||
// text sort function
|
// text sort function
|
||||||
if (typeof(cts) === 'function') {
|
if (typeof(cts) === 'function') {
|
||||||
// custom OVERALL text sorter
|
// custom OVERALL text sorter
|
||||||
@ -696,7 +696,7 @@
|
|||||||
sort = cts[col](x[col], y[col], dir, col, table);
|
sort = cts[col](x[col], y[col], dir, col, table);
|
||||||
} else {
|
} else {
|
||||||
// fall back to natural sort
|
// fall back to natural sort
|
||||||
sort = ts.sortNatural(x[col], y[col]);
|
sort = ts[ 'sortNatural' + (dir ? 'Asc' : 'Desc') ](a[col], b[col], col, table, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sort) { return sort; }
|
if (sort) { return sort; }
|
||||||
@ -1082,6 +1082,7 @@
|
|||||||
if ( xD < yD ) { return -1; }
|
if ( xD < yD ) { return -1; }
|
||||||
if ( xD > yD ) { return 1; }
|
if ( xD > yD ) { return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// chunk/tokenize
|
// chunk/tokenize
|
||||||
xN = a.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
xN = a.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
||||||
yN = b.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
yN = b.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
|
||||||
@ -1104,6 +1105,22 @@
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ts.sortNaturalAsc = function(a, b, col, table, c) {
|
||||||
|
if (a === b) { return 0; }
|
||||||
|
var e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
||||||
|
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; }
|
||||||
|
return ts.sortNatural(a, b);
|
||||||
|
};
|
||||||
|
|
||||||
|
ts.sortNaturalDesc = function(a, b, col, table, c) {
|
||||||
|
if (a === b) { return 0; }
|
||||||
|
var e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
||||||
|
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; }
|
||||||
|
return ts.sortNatural(b, a);
|
||||||
|
};
|
||||||
|
|
||||||
// basic alphabetical sort
|
// basic alphabetical sort
|
||||||
ts.sortText = function(a, b) {
|
ts.sortText = function(a, b) {
|
||||||
return a > b ? 1 : (a < b ? -1 : 0);
|
return a > b ? 1 : (a < b ? -1 : 0);
|
||||||
@ -1112,22 +1129,41 @@
|
|||||||
// return text string value by adding up ascii value
|
// return text string value by adding up ascii value
|
||||||
// so the text is somewhat sorted when using a digital sort
|
// so the text is somewhat sorted when using a digital sort
|
||||||
// this is NOT an alphanumeric sort
|
// this is NOT an alphanumeric sort
|
||||||
ts.getTextValue = function(a, d, mx) {
|
ts.getTextValue = function(a, num, mx) {
|
||||||
if (mx) {
|
if (mx) {
|
||||||
// make sure the text value is greater than the max numerical value (mx)
|
// make sure the text value is greater than the max numerical value (mx)
|
||||||
var i, l = a ? a.length : 0, n = mx + d;
|
var i, l = a ? a.length : 0, n = mx + num;
|
||||||
for (i = 0; i < l; i++) {
|
for (i = 0; i < l; i++) {
|
||||||
n += a.charCodeAt(i);
|
n += a.charCodeAt(i);
|
||||||
}
|
}
|
||||||
return d * n;
|
return num * n;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ts.sortNumeric = function(a, b, dir, mx) {
|
ts.sortNumericAsc = function(a, b, num, mx, col, table) {
|
||||||
if (a === b) { return 0; }
|
if (a === b) { return 0; }
|
||||||
if (isNaN(a)) { a = ts.getTextValue(a, dir, mx); }
|
var c = table.config,
|
||||||
if (isNaN(b)) { b = ts.getTextValue(b, dir, mx); }
|
e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
||||||
|
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 (isNaN(a)) { a = ts.getTextValue(a, num, mx); }
|
||||||
|
if (isNaN(b)) { b = ts.getTextValue(b, num, mx); }
|
||||||
|
return a - b;
|
||||||
|
};
|
||||||
|
|
||||||
|
ts.sortNumericDesc = function(a, b, num, mx, col, table) {
|
||||||
|
if (a === b) { return 0; }
|
||||||
|
var c = table.config,
|
||||||
|
e = c.string[ (c.empties[col] || c.emptyTo ) ];
|
||||||
|
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 (isNaN(a)) { a = ts.getTextValue(a, num, mx); }
|
||||||
|
if (isNaN(b)) { b = ts.getTextValue(b, num, mx); }
|
||||||
|
return b - a;
|
||||||
|
};
|
||||||
|
|
||||||
|
ts.sortNumeric = function(a, b) {
|
||||||
return a - b;
|
return a - b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -968,7 +968,7 @@ ts.filter = {
|
|||||||
arry = $.grep(arry, function(value, indx) {
|
arry = $.grep(arry, function(value, indx) {
|
||||||
return $.inArray(value, arry) === indx;
|
return $.inArray(value, arry) === indx;
|
||||||
});
|
});
|
||||||
arry = (ts.sortNatural) ? arry.sort(function(a, b) { return ts.sortNatural(a, b); }) : arry.sort(true);
|
arry = (ts.sortNatural) ? arry.sort(function(a, b) { return ts.sortNatural(a, b, column, tabl); }) : arry.sort(true);
|
||||||
|
|
||||||
// Get curent filter value
|
// Get curent filter value
|
||||||
currentValue = c.$table.find('thead').find('select.tablesorter-filter[data-column="' + column + '"]').val();
|
currentValue = c.$table.find('thead').find('select.tablesorter-filter[data-column="' + column + '"]').val();
|
||||||
|
Loading…
Reference in New Issue
Block a user