Home > Net >  JQuery sort table data except first and last tr
JQuery sort table data except first and last tr

Time:09-30

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>

  • Related