Home > Enterprise >  How to sort table by two columns instead of one
How to sort table by two columns instead of one

Time:02-02

I have a table that I sort ASC by building name. The next column is the corresponding building number for the building. I have a function that will sort the table in ASC order based on the building name. I want to be able to sort by the building name and the building number at the same time. This is a snippet of the table when the page loads. The first <td> which is the building name goes in order. However, the next <td> which is the building number does not go in order.

<tbody >
   <tr>
      <td>ACB</td>
      <td>A2095</td>
   </tr>
   <tr>
      <td>ACB</td>
      <td>E1559</td>      
   </tr>
   <tr>
      <td>ACB</td>
      <td>E1540</td>      
   </tr>
   <tr>
      <td>ADH</td>
      <td>A0001</td>      
   </tr>
   <tr>
      <td>ADH</td>
      <td>E1076</td>     
   </tr>
   <tr>
      <td>ADH</td>
      <td>S0001</td>      
   </tr>
   <tr>
      <td>ADH</td>
      <td>E1075</td>      
   </tr>
</tbody>

This is the function I use the sort the table in ASC order by building name.

$('.meterList').find('tr').sort(function(a, b) {
    return $('td:first', a).text().localeCompare($('td:first', b).text());
 }).appendTo($('.meterList'))

I tried doing something like this to sort by both the first and second <td> but this didnt work.

$('.meterList').find('tr').sort(function(a, b) {
    return $('td:first, td:second', a).text().localeCompare($('td:first, td:second', b).text());
 }).appendTo($('.meterList'))

If anyone has any idea how I can sort by two columns any advice would be greatly appreciated!

CodePudding user response:

This should do it:

const t=(tr,i)=>tr.cells[i].textContent;
$(".meterList tr").get()
  .sort((a,b)=>t(a,0).localeCompare(t(b,0)) || t(a,1).localeCompare(t(b,1)))
  .map(tr=>$(".meterList").append(tr));
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<table><tbody >
   <tr>
  <td>ACB</td>
  <td>A2095</td>
   </tr>
   <tr>
  <td>ACB</td>
  <td>E1559</td>      
   </tr>
   <tr>
  <td>ACB</td>
  <td>E1540</td>      
   </tr>
   <tr>
  <td>ADH</td>
  <td>A0001</td>      
   </tr>
   <tr>
  <td>ADH</td>
  <td>E1076</td>     
   </tr>
   <tr>
  <td>ADH</td>
  <td>S0001</td>      
   </tr>
   <tr>
  <td>ADH</td>
  <td>E1075</td>      
   </tr>
</tbody></table>

First I created a little helper function t(tr,I) that gets me the .textContent of the i-th cell for a given <tr>.

Then I collect all <tr>s in an array (.get() extracts the actuall array of DOM elements from the jQuery object) and .sort() it. The sort-callback function will first compare the first cells (index=0) of two given <tr>s and - only when the comparison returns 0 - the second comparison will take place (looking at the second cells in each <tr>).

This can be done even without creating any visible variables or constants outside the actual jQuery construct. In fact, there is not much jQuery left in the above code and it can just as easily be done without it. ;-)

  •  Tags:  
  • Related