If I have the following table...
<table role="presentation" data="regMultipleTable">
<tbody>
<tr ><td>hide</td><td>hide</td></tr>
<tr><td >item 1</td><td><font>zebra</font></td></tr>
<tr><td >item 2</td><td><font>ape</font></td></tr>
<tr><td >item 3</td><td><font>dog</font></td></tr>
<tr ><td></td><td><h3>other stuff</h3></td></tr>
</tbody>
</table>
...how come my following jQuery logic sorts all the <tr>
elements? Should it not be sorting only the mid <tr>
elements? How can I exclude the first and the last <tr>
, so they stay where they are?
function sortTable(table, order) {
var asc = order === 'asc',
tbody = table.find('tbody');
/*IN ADDITION TO SLICE() BELOW, I ALSO TRIED:
'tr:not(.d-none,.border-none)'
'tr:not(:first, :last)'
*/
tbody.find('tr').slice(1, -1).sort(function(a, b) {
if (asc) {
return window.jQuery('td:eq(1) font', a).text().localeCompare(window.jQuery('td:eq(1) font', b).text());
} else {
return window.jQuery('td:eq(1) font', b).text().localeCompare(window.jQuery('td:eq(1) font', a).text());
}
}).appendTo(tbody);
}
sortTable(window.jQuery('table[data="regMultipleTable"]'), 'asc');
The end result should be...
<table role="presentation" data="regMultipleTable">
<tbody>
<tr ><td>hide</td><td>hide</td></tr>
<tr><td >item 2</td><td><font>ape</font></td></tr>
<tr><td >item 3</td><td><font>dog</font></td></tr>
<tr><td >item 1</td><td><font>zebra</font></td></tr>
<tr ><td></td><td><h3>other stuff</h3></td></tr>
</tbody>
</table>
Many thanks
CodePudding user response:
Since you are already sorting using a user supplied callback, all you need todo is take care that the first and last <tr>
always "wins" the comparison by getting -1
or 1
respectively.
UPDATE: to support firefox which does some sort of sort optimization, need to check both a
and b
. Refactoring needed.
function sortTable(table, order) {
var asc = order === 'asc',
tbody = table.find('tbody');
tbody.find('tr').sort(function(a, b) {
if (asc) {
if ($(a).is(":first-child")) {
return -1;
}
if ($(a).is(":last-child")) {
return 1;
}
if ($(b).is(":first-child")) {
return 1;
}
if ($(b).is(":last-child")) {
return -1;
}
return window.jQuery('td:eq(1) font', a).text().localeCompare(window.jQuery('td:eq(1) font', b).text());
} else {
if ($(a).is(":first-child")) {
return 1;
}
if ($(a).is(":last-child")) {
return -1;
}
if ($(b).is(":first-child")) {
return -1;
}
if ($(b).is(":last-child")) {
return 1;
}
return window.jQuery('td:eq(1) font', b).text().localeCompare(window.jQuery('td:eq(1) font', a).text());
}
}).appendTo(tbody);
}
sortTable(window.jQuery('table[data="regMultipleTable"]'), 'asc');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table role="presentation" data="regMultipleTable" border=1>
<tbody>
<tr ><td>hide</td><td>hide</td></tr>
<tr><td >item 2</td><td><font>ape</font></td></tr>
<tr><td >item 3</td><td><font>dog</font></td></tr>
<tr><td >item 1</td><td><font>zebra</font></td></tr>
<tr ><td></td><td><h3>other stuff</h3></td></tr>
</tbody>
</table>
CodePudding user response:
or you just can add a class to all the rows you want to sort, like this:
<tr class='sortMe'>
And then change this line:
tbody.find('tr').slice(1, -1).sort(function(a, b) {
to this:
tbody.find('tr.sortMe').slice(1, -1).sort(function(a, b) {
CodePudding user response:
Here is another way of achieving the same - with Vanilla JavaScript:
var [first,...trs]=[...document.querySelector("tbody").children].slice(0,-1);
document.querySelectorAll("button").forEach((btn,i)=>btn.onclick=ev=>{
if(first.srt!==i){
first.srt=i;
trs.sort((a,b)=>a.children[i].textContent.localeCompare(b.children[i].textContent));
}
else trs=trs.reverse();
first.after(...trs);
});
<table role="presentation" data="regMultipleTable">
<tbody>
<tr ><td><button>sort</button></td><td><button>sort</button></td></tr>
<tr><td >item 3</td><td><font>dog</font></td></tr>
<tr><td >item 2</td><td><font>ape</font></td></tr>
<tr><td >item 1</td><td><font>zebra</font></td></tr>
<tr ><td></td><td><h3>other stuff</h3></td></tr>
</tbody>
</table>