Search code examples
javascripthtmldomhtml-tabledom-events

How to sort in ascending order a table using a slice of each cell's textContent


so im trying to creat a function that sorts a table based on the 1st cell of each row (excluding the 1st row) the text value of the elements is the value of an input from a form and it has to be (AA111) two letters and 3 numbers

it has to switch the entire row (with all its cells) based on the value of the number(in this expl 111) of the textContent(in this expl AA111) of the 1st cell with the row above (if this one has a greater value)

AAAH and this table can expand each time as it has a button calling a function that adds a new row with different values everytime this button is clicked

i tried to collect each row with a for loop and then collect the value of the 1st cell then do a .slice(2); then transform it into a number with Number()but it seems to be a problem with it as it's not working here's my function

function Sort() {
  let table = document.getElementById('add'); //table id
  let row = table.rows;
  let switching = true;
  let tmp0 = new Array();
  tmp0.length = row.length;
  let tmp1 = new Array();
  tmp1.length = row.length;
  let tmp2 = new Array();
  tmp2.length = row.length;
  let ech;
  while (switching) {
    switching = false;
    for (var i = 1; i < row.length - 1; i++) {
      tmp0[i] = row[i].cells[0].innerText; /* collecting the intire content from the 1st cell of each row then         turning it into a number*/
      tmp1[i] = tmp0[i].slice(2);
      tmp2[i] = Number(tmp1[i]);
      if (tmp2[i] > tmp2[i + 1]) // swicthing the values if the 1st one is greater
      {
        ech = row[i].innerHTML;
        row[i].innerHTML = row[i + 1].innerHTML;
        row[i + 1].innerHTML = ech;
        switching = true;
      }
    }
  }
}

i tried to remove the if condition and .slice part to try and see where the problem is

function Sort() {
  let table = document.getElementById('add');
  let switching = true;
  let row = table.rows;
  while (switching) {
    switching = false;
    for (var i = 1; i < row.length; i++) {
      ech = row[i].innerHTML;
      row[i].innerHTML = row[i + 1].innerHTML;
      row[i + 1].innerHTML = ech;
      switching = true;
    }
  }
}

and this while loop is actually working as it did change the values of the cells each time i pressed the button that i linked this function with

so is it the way that i collected the values that is wrong or is it the use of slice or just everything

please help me see the mistake


Solution

  • Convert the table rows to an array, and use the built-in sort() method with a comparison function that extracts the slice you want.

    Then you can update the table to contain the rows in the sorted order.

    function Sort() {
      let table = document.getElementById('add'); //table id
      let rows = [...table.rows].slice(1); // skip header row
      rows.sort((row1, row2) => Number(row1.cells[0].innerText.slice(2)) - Number(row2.cells[0].innerText.slice(2)));
      rows.forEach(row => table.appendChild(row)); // Add back in new order
    }
    <table id="add">
    <tr><th>Col 1</th><th>Col 2</th></tr>
    <tr><td>AB321</td><td>Row 1</td></tr>
    <tr><td>XX12</td><td>Row 2</td></tr>
    <tr><td>ZX123</td><td>Row 3</td></tr>
    </table>
    
    <button onclick="Sort()">
    Click to sort
    </button>