2
\$\begingroup\$

I have written a code to sort a main table containing tables in each of its rows. Here I am trying to sort the table by first sorting the rows in each of the main rows and then sorting the table from the sorted main rows. Whenever I click on headers the table is sorted in ascending and descending order alternately. How can I make this code more efficient and elegant in a JS way?

let headers = document.querySelectorAll('.percentage_header');
headers.forEach(header => header.addEventListener('click', sortAll));

var sortDir = 1;

var mainTable = document.querySelector('.main_results_table');
var mainTableRows =  Array.from(mainTable.querySelectorAll('.main_table_rows'));

var individualRowsFromMainTableRows = document.querySelectorAll('.individual_rows');

function sortAll() {
  individualRowsFromMainTableRows.forEach(function(row) { 
    individualStudentResults = Array.from(row.querySelectorAll(".single_test_row"));
    individualStudentResults.sort(function(a,b){
      if(a.querySelector(".percentage_value") == undefined) return 1;
    if(b.querySelector(".percentage_value") == undefined) return 0;
    return sortDir == -1 ? (a.querySelector(".percentage_value").textContent > b.querySelector(".percentage_value").textContent) : (a.querySelector(".percentage_value").textContent < b.querySelector(".percentage_value").textContent);
    // return parseFloat(a.querySelector(".theory_percentage_value").textContent) - parseFloat(b.querySelector(".theory_percentage_value").textContent) * sortDir;
    })
    individualStudentResults.forEach(individualStudentResult => row.appendChild(individualStudentResult));
  })  

  mainTableRows.sort((a, b) => sortDir * (getVal(a) - getVal(b)));            
  mainTableRows.forEach(mainTableRow => mainTable.appendChild(mainTableRow));
  sortDir = -sortDir
}

function getVal(rw) {
    var a = parseFloat(rw.querySelector('.individual_rows .single_test_row .percentage_value').textContent);
    return a ? a : 0;
}
<table class="main_results_table">
  
    <tr class="main_table_rows">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="individual_rows">
          <tr class="row_header">
            <th>person_status</th>
            <th class="percentage_header">Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">48%</td>
              <td>88%</td>
            </td>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">N/A</td>
              <td>88%</td>
            </td>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">22%</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    
    <tr class="main_table_rows">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="individual_rows">
          <tr class="row_header">
            <th>person_status</th>
            <th class="percentage_header">Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">58%</td>
              <td>88%</td>
            </td>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">68%</td>
              <td>88%</td>
            </td>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">78%</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr class="main_table_rows">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="individual_rows">
          <tr class="row_header">
            <th>person_status</th>
            <th class="percentage_header">Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">99%</td>
              <td>88%</td>
            </td>
          </tr>
          <tr class="single_test_row">
            <td class="values">
              <td class="percentage_value">N/A</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
 </table>

\$\endgroup\$
  • \$\begingroup\$ You're sorting the rows with the class main_table_rows instead of the rows inside the individual_rows tables \$\endgroup\$ – SpoonMeiser Jun 3 at 12:02
  • \$\begingroup\$ Am I not sorting the rows inside the individual_rows first and then sorting the main_table_rows as per the sorted individual_rows inside each of the main_table_rows? As soon as the sortAll function is called I thought I am doing the same. Please tell me where I am wrong. \$\endgroup\$ – Laxman Jun 4 at 6:55
  • \$\begingroup\$ Sorry, I misread it. Your sort function for individual rows returns either 0, 1, true or false though, where it should return either -1, 0 or 1 \$\endgroup\$ – SpoonMeiser Jun 4 at 9:29
  • \$\begingroup\$ I do not know if it is a silly question but what does returning -1, 0 or 1 do differently from the present values? I do not know the difference. \$\endgroup\$ – Laxman Jun 4 at 11:49
  • \$\begingroup\$ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… \$\endgroup\$ – SpoonMeiser Jun 4 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.