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>