Die Art und Weise, wie ich HTML-Tabellen im Browser sortiert habe, verwendet einfaches, ungeschminktes Javascript.
Der grundlegende Prozess ist folgender:
- Hinzufügen eines Klick-Handlers zu jeder Tabellenüberschrift
- der Click-Handler notiert den Index der zu sortierenden Spalte
- die Tabelle wird in ein Array von Arrays (Zeilen und Zellen) umgewandelt
- dieses Array wird mit der Javascript-Sortierfunktion sortiert
- werden die Daten aus dem sortierten Array wieder in die HTML-Tabelle eingefügt Tabelle
Die Tabelle sollte natürlich schönes HTML sein. Etwa so...
<table>
<thead>
<tr><th>Name</th><th>Age</th></tr>
</thead>
<tbody>
<tr><td>Sioned</td><td>62</td></tr>
<tr><td>Dylan</td><td>37</td></tr>
...etc...
</tbody>
</table>
Also, zuerst die Klick-Handler hinzufügen...
const table = document.querySelector('table'); //get the table to be sorted
table.querySelectorAll('th') // get all the table header elements
.forEach((element, columnNo)=>{ // add a click handler for each
element.addEventListener('click', event => {
sortTable(table, columnNo); //call a function which sorts the table by a given column number
})
})
Das funktioniert im Moment nicht, weil die sortTable
Funktion, die im Event-Handler aufgerufen wird, nicht existiert.
Schreiben wir es...
function sortTable(table, sortColumn){
// get the data from the table cells
const tableBody = table.querySelector('tbody')
const tableData = table2data(tableBody);
// sort the extracted data
tableData.sort((a, b)=>{
if(a[sortColumn] > b[sortColumn]){
return 1;
}
return -1;
})
// put the sorted data back into the table
data2table(tableBody, tableData);
}
Jetzt kommen wir zum Kern des Problems, wir müssen die Funktionen table2data
um Daten aus der Tabelle zu erhalten, und data2table
um sie nach dem Sortieren wieder einzubauen.
Hier sind sie ...
// this function gets data from the rows and cells
// within an html tbody element
function table2data(tableBody){
const tableData = []; // create the array that'll hold the data rows
tableBody.querySelectorAll('tr')
.forEach(row=>{ // for each table row...
const rowData = []; // make an array for that row
row.querySelectorAll('td') // for each cell in that row
.forEach(cell=>{
rowData.push(cell.innerText); // add it to the row data
})
tableData.push(rowData); // add the full row to the table data
});
return tableData;
}
// this function puts data into an html tbody element
function data2table(tableBody, tableData){
tableBody.querySelectorAll('tr') // for each table row...
.forEach((row, i)=>{
const rowData = tableData[i]; // get the array for the row data
row.querySelectorAll('td') // for each table cell ...
.forEach((cell, j)=>{
cell.innerText = rowData[j]; // put the appropriate array element into the cell
})
});
}
Und das sollte genügen.
Ein paar Dinge, die Sie vielleicht hinzufügen möchten (oder Gründe, warum Sie eine Standardlösung verwenden möchten): Eine Option, um die Richtung und die Art der Sortierung zu ändern, d.h. Sie möchten vielleicht einige Spalten numerisch sortieren ( "10" > "2"
ist falsch, weil es sich um Zeichenketten handelt, wahrscheinlich nicht das, was Sie wollen). Die Möglichkeit, eine Spalte als sortiert zu markieren. Eine Art der Datenüberprüfung.