简体   繁体   中英

Using Javascript to sort table with multiple digit entries

I'm trying to add a sortable table to my site but I'm having issues sorting columns with varying digit entries. It works fine when all numbers are the same number of digits in length.

However, when I change the number of digits, the sort function seems to break and sorts them out of order.

The code below is a simple example of this. The table I am working with is much larger and more interesting than people, their jobs and age.

Here is my HTML:

<!DOCTYPE html>
<head>
  <title>Sorting Tables w/ JavaScript</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta charset="utf-8" />
</head>

<body>
  <table class="table-sortable">
    <thead>
      <tr>
        <th>Rank</th>
        <th>Name</th>
        <th>Age</th>
        <th>Occupation</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Dom</td>
        <td>5</td>
        <td>Web Developer</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Rebecca</td>
        <td>29</td>
        <td>Teacher</td>
      </tr>
      <tr>
        <td>3</td>
        <td>John</td>
        <td>100</td>
        <td>Civil Engineer</td>
      </tr>
      <tr>
        <td>4</td>
        <td>Andre</td>
        <td>20</td>
        <td>Dentist</td>
      </tr>
    </tbody>
  </table>

  <script src="./src/tablesort.js"></script>
</body>

JS:

function sortTableByColumn(table, column, asc = true) {
    const dirModifier = asc ? 1 : -1;
    const tBody = table.tBodies[0];
    const rows = Array.from(tBody.querySelectorAll("tr"));

    // Sort each row
    const sortedRows = rows.sort((a, b) => {
        const aColText = a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
        const bColText = b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();

        return aColText > bColText ? (1 * dirModifier) : (-1 * dirModifier);
    });

    // Remove all existing TRs from the table
    while (tBody.firstChild) {
        tBody.removeChild(tBody.firstChild);
    }

    // Re-add the newly sorted rows
    tBody.append(...sortedRows);

    // Remember how the column is currently sorted
    table.querySelectorAll("th").forEach(th => th.classList.remove("th-sort-asc", "th-sort-desc"));
    table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-asc", asc);
    table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-desc", !asc);
}

document.querySelectorAll(".table-sortable th").forEach(headerCell => {
    headerCell.addEventListener("click", () => {
        const tableElement = headerCell.parentElement.parentElement.parentElement;
        const headerIndex = Array.prototype.indexOf.call(headerCell.parentElement.children, headerCell);
        const currentIsAscending = headerCell.classList.contains("th-sort-asc");

        sortTableByColumn(tableElement, headerIndex, !currentIsAscending);
    });
});

Any help on this would be much appreciated!! Thank you all so much for your help on this!

To sort by numeric value:

return parseFloat(aColText) > parseFloat(bColText) ? (1 * dirModifier) : (-1 * dirModifier);

Otherwise, sort will be by string value ("2" is bigger than "10").

In general, to sort by numeric value:

array.sort((a,b)=>parseFloat(a)<parseFloat(b)?-1:1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM