Home > Net >  Sort HTML table with Javascript
Sort HTML table with Javascript

Time:09-22

Here is an example code for table sorting taken from javascript.info: https://plnkr.co/edit/5xHStBMfV5AVtoxR?p=preview&preview=

let sortedRows = Array.from(table.tBodies[0].rows).sort((rowA, rowB) => rowA.cells[0].innerHTML.localeCompare(rowB.cells[0].innerHTML));

table.tBodies[0].append(...sortedRows);

My question is: Array.from(table.tBodies[0].rows) produces an array. But cells[0] is not defined for arrays. How does the code work?

CodePudding user response:

The .rows property of a table gives you an HTMLCollection of the rows in the table. Array.from turns the HTMLCollection of rows into an array of rows.

With

.sort((rowA, rowB) => rowA.cells[0] ...

Each parameter is one of the array items being iterated over - a row - neither rowA nor rowB are the array that was created with Array.from. They're the array elements, which are rows.

The array elements (which were originally the HTMLCollection elements) are still rows - and rows have a .cells property.

CodePudding user response:

Your rowA is a TR, so you will have to use fetch cells from it. Array.from just converts an HTML collection/ NodeList to an Array of elements so that you can use Array methods

let sortedRows = Array.from(table.tBodies[0].rows)
  .sort((rowA, rowB) => {
    const cellsA = rowA.querySelectorAll('td')
    const cellsB = rowB.querySelectorAll('td')
    return cellsA[0].innerHTML.localeCompare(cellsB[0].innerHTML)
  });

table.tBodies[0].append(...sortedRows);
<table id="table">
<thead>
  <tr><th>Name</th><th>Surname</th><th>Age</th></tr>
</thead>
<tbody>
  <tr><td>John</td><td>Smith</td><td>10</td></tr>
  <tr><td>Pete</td><td>Brown</td><td>15</td></tr>
  <tr><td>Ann</td><td>Lee</td><td>5</td></tr>
  <tr><td>...</td><td>...</td><td>...</td></tr>
</tbody>
</table>

Data based approach:

const data = [
  { name: "John", surname: "Smith", age: 10},
  { name: "Pete", surname: "Brown", age: 15},
  { name: "Ann", surname: "Lee", age: 5},
]

const sortData = (key) => {
  return data
    .slice()
    .sort((a,b) => {
      return typeof a[key] === "string"
        ? a[key].localeCompare(b[key])
        : a[key] - b[key]
    });
}

const createTable = (data) => {
  return data.map((item) => {
    return `<tr>${
      Object.values(item)
      .map((value) => `<td>${value}</td>`)
      .join("")
    }</tr>`
  }).join("").concat("<tr><td>...</td><td>...</td><td>...</td></tr>")
}
const renderTable = (data) => {
  document
    .getElementById('table')
    .querySelector('tbody').innerHTML = createTable(data)
}

document
  .querySelector('.actionPanel')
  .addEventListener('click', (e) => {
    const text = e.target.textContent.toLowerCase();
    renderTable(sortData(text))
  })

renderTable(data)
<div class='actionPanel'>
  <button>Name</button>
  <button>Surname</button>
  <button>Age</button>
</div>
<table id="table">
  <thead>
    <tr><th>Name</th><th>Surname</th><th>Age</th></tr>
  </thead>
  <tbody></tbody>
</table>

  • Related