Сортировка HTML-таблицы с JavaScript
Я после решения сортировки таблицы (в JavaScript), но пока не могу найти подходящего. Мне просто нужно отсортировать каждую колонку в алфавитном порядке. Ему не нужно игнорировать какой-либо код или какие-либо цифры или работать с валютой. Просто щелчок по заголовку столбца переключает его из отсортированного a-z/z-a.
Кто-нибудь знает о действительно простом решении вроде этого?
Ответы
Ответ 1
Просто вернувшись к старому решению, я подумала, что подправлю его на ~ 5-летний юбилей!
- Простой Javascript (ES6)
- Выполняет сортировку букв и цифр - по возрастанию и по убыванию
- Работает в Chrome, Firefox, Safari (и IE11, см. ниже)
Быстрое объяснение
- добавить событие
click
ко всем ячейкам заголовка (th
)...
- для текущего
table
найдите все строки (кроме первой)...
- сортировать строки по значению столбца, по которому щелкнули...
- вставьте строки обратно в таблицу в новом порядке.
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
)(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
// do the work...
document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
const table = th.closest('table');
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
.forEach(tr => table.appendChild(tr) );
})));
table, th, td {
border: 1px solid black;
}
th {
cursor: pointer;
}
<table>
<tr><th>Country</th><th>Date</th><th>Size</th></tr>
<tr><td>France</td><td>2001-01-01</td><td><i>25</i></td></tr>
<tr><td><a href=#>spain</a></td><td><i>2005-05-05</i></td><td></td></tr>
<tr><td><b>Lebanon</b></td><td><a href=#>2002-02-02</a></td><td><b>-17</b></td></tr>
<tr><td><i>Argentina</i></td><td>2005-04-04</td><td><a href=#>100</a></td></tr>
<tr><td>USA</td><td></td><td>-6</td></tr>
</table>
Ответ 2
Я написал код, который будет сортировать таблицу по строке, предполагая, что только один <tbody>
и ячейки не имеют colspan.
function sortTable(table, col, reverse) {
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
i;
reverse = -((+reverse) || -1);
tr = tr.sort(function (a, b) { // sort rows
return reverse // `-1 *` if want opposite order
* (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
.localeCompare(b.cells[col].textContent.trim())
);
});
for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}
// sortTable(tableNode, columId, false);
Если вы не хотите делать предположения выше, вам нужно подумать о том, как вы хотите вести себя в каждом случае. (например, положить все в один <tbody>
или добавить все предыдущие значения colspan и т.д.)
Затем вы можете присоединить это к каждой из ваших таблиц, например. если заголовки находятся в <thead>
function makeSortable(table) {
var th = table.tHead, i;
th && (th = th.rows[0]) && (th = th.cells);
if (th) i = th.length;
else return; // if no `<thead>` then do nothing
while (--i >= 0) (function (i) {
var dir = 1;
th[i].addEventListener('click', function () {sortTable(table, i, (dir = 1 - dir))});
}(i));
}
function makeAllSortable(parent) {
parent = parent || document.body;
var t = parent.getElementsByTagName('table'), i = t.length;
while (--i >= 0) makeSortable(t[i]);
}
а затем вызовите makeAllSortable
onload.
Пример скрипка, работающий над таблицей.
Ответ 3
Он делает WAY больше, чем "просто сортировка", но dataTables.net делает то, что вам нужно. Я использую его ежедневно и хорошо поддерживается и очень быстро (требуется jQuery)
http://datatables.net/
DataTables - это плагин для библиотеки jQuery Javascript. Это очень гибкий инструмент, основанный на основах прогрессивного улучшения, который добавит дополнительные элементы управления взаимодействием в любую таблицу HTML.
Визуализация Google - это еще один вариант, но требует немного больше настройки данныхTables, но НЕ требует какой-либо конкретной инфраструктуры/библиотеки (кроме google.visualizations):
http://code.google.com/apis/ajax/playground/?type=visualization#table
И есть другие варианты... особенно если вы используете одну из других инфраструктур JS. Dojo, Prototype и т.д. Имеют плагины с улучшенными таблицами, которые обеспечивают минимальную функциональность сортировки таблиц. Многие из них предоставляют больше, но я буду повторять... Я еще не нашел такой мощный, а FAST - как datatables.net.
Ответ 4
Лучший способ, которым я знаю, сортировать таблицу HTML с javascript со следующей функцией.
Просто передайте ему идентификатор таблицы, которую вы хотите отсортировать, и номер столбца в строке. он предполагает, что столбец, который вы сортируете, является числовым или имеет номера в нем и будет выполнять замену регулярных выражений, чтобы получить сам номер (отлично подходит для валют и других чисел с символами в нем).
function sortTable(table_id, sortColumn){
var tableData = document.getElementById(table_id).getElementsByTagName('tbody').item(0);
var rowData = tableData.getElementsByTagName('tr');
for(var i = 0; i < rowData.length - 1; i++){
for(var j = 0; j < rowData.length - (i + 1); j++){
if(Number(rowData.item(j).getElementsByTagName('td').item(sortColumn).innerHTML.replace(/[^0-9\.]+/g, "")) < Number(rowData.item(j+1).getElementsByTagName('td').item(sortColumn).innerHTML.replace(/[^0-9\.]+/g, ""))){
tableData.insertBefore(rowData.item(j+1),rowData.item(j));
}
}
}
}
Пример использования:
$(function(){
// pass the id and the <td> place you want to sort by (td counts from 0)
sortTable('table_id', 3);
});
Ответ 5
Вы можете иметь дело с массивом json и функцией sort
. Это довольно простая управляемая структура для управления (например: сортировка).
Неподтвержденный, но вот идея. Это будет поддерживать множественный порядок и последовательный порядок, если вы передадите массив, в который вы поместите столбцы в том порядке, в котором они должны быть упорядочены.
var DATA_TABLE = {
{name: 'George', lastname: 'Blarr', age:45},
{name: 'Bob', lastname: 'Arr', age: 20}
//...
};
function sortDataTable(arrayColNames, asc) { // if not asc, desc
for (var i=0;i<arrayColNames.length;i++) {
var columnName = arrayColNames[i];
DATA_TABLE = DATA_TABLE.sort(function(a,b){
if (asc) {
return (a[columnName] > b[columnName]) ? 1 : -1;
} else {
return (a[columnName] < b[columnName]) ? 1 : -1;
}
});
}
}
function updateHTMLTable() {
// update innerHTML / textContent according to DATA_TABLE
// Note: textContent for firefox, innerHTML for others
}
Теперь представьте, что вам нужно заказать по имени, затем поименовать и, наконец, по возрасту.
var orderAsc = true;
sortDataTable(['lastname', 'name', 'age'], orderAsc);
Это должно привести к чему-то вроде:
{name: 'Jack', lastname: 'Ahrl', age: 20},
{name: 'Jack', lastname: 'Ahrl', age: 22},
//...
Ответ 6
Nick Grealy - отличный ответ, но он немного странный, если ваши строки находятся внутри <tbody>
(первая строка никогда не сортируется, а после сортировки строки оказываются вне тега tbody, возможно, теряя форматирование).
Это простое решение, однако:
Просто измените:
document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
const table = th.closest('table');
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
.forEach(tr => table.appendChild(tr) );
чтобы:
document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
const table = th.closest('table');
const tbody = table.querySelector('tbody');
Array.from(tbody.querySelectorAll('tr'))
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
.forEach(tr => tbody.appendChild(tr) );
Ответ 7
Вот полный пример использования чистого JavaScript. Алгоритм, используемый для сортировки, в основном BubbleSort. Вот Fiddle.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function sort(ascending, columnClassName, tableId) {
var tbody = document.getElementById(tableId).getElementsByTagName(
"tbody")[0];
var rows = tbody.getElementsByTagName("tr");
var unsorted = true;
while (unsorted) {
unsorted = false
for (var r = 0; r < rows.length - 1; r++) {
var row = rows[r];
var nextRow = rows[r + 1];
var value = row.getElementsByClassName(columnClassName)[0].innerHTML;
var nextValue = nextRow.getElementsByClassName(columnClassName)[0].innerHTML;
value = value.replace(',', '.'); // in case a comma is used in float number
nextValue = nextValue.replace(',', '.');
if (!isNaN(value)) {
value = parseFloat(value);
nextValue = parseFloat(nextValue);
}
if (ascending ? value > nextValue : value < nextValue) {
tbody.insertBefore(nextRow, row);
unsorted = true;
}
}
}
};
</script>
</head>
<body>
<table id="content-table">
<thead>
<tr>
<th class="id">ID <a
href="javascript:sort(true, 'id', 'content-table');">asc</a> <a
href="javascript:sort(false, 'id', 'content-table');">des</a>
</th>
<th class="country">Country <a
href="javascript:sort(true, 'country', 'content-table');">asc</a> <a
href="javascript:sort(false, 'country', 'content-table');">des</a>
</th>
<th class="some-fact">Some fact <a
href="javascript:sort(true, 'some-fact', 'content-table');">asc</a>
<a href="javascript:sort(false, 'some-fact', 'content-table');">des</a>
<th>
</tr>
</thead>
<tbody>
<tr>
<td class="id">001</td>
<td class="country">Germany</td>
<td class="some-fact">16.405</td>
</tr>
<tr>
<td class="id">002</td>
<td class="country">France</td>
<td class="some-fact">10.625</td>
</tr>
<tr>
<td class="id">003</td>
<td class="country">UK</td>
<td class="some-fact">15.04</td>
</tr>
<tr>
<td class="id">004</td>
<td class="country">China</td>
<td class="some-fact">13.536</td>
</tr>
</tbody>
</table>
</body>
</html>
Вы также можете проверить источник здесь: https://github.com/wmentzel/table-sort
Ответ 8
Сортировка строк таблицы по ячейкам.
1. Немного проще и имеет некоторые функции.
2. Различать "число" и "строку" при сортировке
3. Добавить toggle для сортировки по ASC, DESC
var index; // cell index
var toggleBool; // sorting asc, desc
function sorting(tbody, index){
this.index = index;
if(toggleBool){
toggleBool = false;
}else{
toggleBool = true;
}
var datas= new Array();
var tbodyLength = tbody.rows.length;
for(var i=0; i<tbodyLength; i++){
datas[i] = tbody.rows[i];
}
// sort by cell[index]
datas.sort(compareCells);
for(var i=0; i<tbody.rows.length; i++){
// rearrange table rows by sorted rows
tbody.appendChild(datas[i]);
}
}
function compareCells(a,b) {
var aVal = a.cells[index].innerText;
var bVal = b.cells[index].innerText;
aVal = aVal.replace(/\,/g, '');
bVal = bVal.replace(/\,/g, '');
if(toggleBool){
var temp = aVal;
aVal = bVal;
bVal = temp;
}
if(aVal.match(/^[0-9]+$/) && bVal.match(/^[0-9]+$/)){
return parseFloat(aVal) - parseFloat(bVal);
}
else{
if (aVal < bVal){
return -1;
}else if (aVal > bVal){
return 1;
}else{
return 0;
}
}
}
ниже - html sample
<table summary="Pioneer">
<thead>
<tr>
<th scope="col" onclick="sorting(tbody01, 0)">No.</th>
<th scope="col" onclick="sorting(tbody01, 1)">Name</th>
<th scope="col" onclick="sorting(tbody01, 2)">Belong</th>
<th scope="col" onclick="sorting(tbody01, 3)">Current Networth</th>
<th scope="col" onclick="sorting(tbody01, 4)">BirthDay</th>
<th scope="col" onclick="sorting(tbody01, 5)">Just Number</th>
</tr>
</thead>
<tbody id="tbody01">
<tr>
<td>1</td>
<td>Gwanshic Yi</td>
<td>Gwanshic Home</td>
<td>120000</td>
<td>1982-03-20</td>
<td>124,124,523</td>
</tr>
<tr>
<td>2</td>
<td>Steve Jobs</td>
<td>Apple</td>
<td>19000000000</td>
<td>1955-02-24</td>
<td>194,523</td>
</tr>
<tr>
<td>3</td>
<td>Bill Gates</td>
<td>MicroSoft</td>
<td>84300000000</td>
<td>1955-10-28</td>
<td>1,524,124,523</td>
</tr>
<tr>
<td>4</td>
<td>Larry Page</td>
<td>Google</td>
<td>39100000000</td>
<td>1973-03-26</td>
<td>11,124,523</td>
</tr>
</tbody>
</table>
Ответ 9
Если ваша таблица не имеет th
но только td
(с включенными заголовками), вы можете попробовать следующее, основанное на ответе Ника Грели:
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
)(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
// do the work...
document.querySelectorAll('tr:first-child td').forEach(td => td.addEventListener('click', (() => {
const table = td.closest('table');
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
.sort(comparer(Array.from(td.parentNode.children).indexOf(td), this.asc = !this.asc))
.forEach(tr => table.appendChild(tr) );
})));
@charset "UTF-8";
@import url('https://fonts.googleapis.com/css?family=Roboto');
*{
font-family: 'Roboto', sans-serif;
text-transform:capitalize;
overflow:hidden;
margin: 0 auto;
text-align:left;
}
table {
color:#666;
font-size:12px;
background:#124;
border:#ccc 1px solid;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border-collapse: collapse;
width: 100%;
}
table td {
padding:10px;
border-top: 1px solid #ffffff;
border-bottom:1px solid #e0e0e0;
border-left: 1px solid #e0e0e0;
background: #fafafa;
background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa));
background: -moz-linear-gradient(top, #fbfbfb, #fafafa);
width: 6.9in;
}
table tbody tr:first-child td
{
background: #124!important;
color:#fff;
}
table tbody tr th
{
padding:10px;
border-left: 1px solid #e0e0e0;
background: #124!important;
color:#fff;
}
<table>
<tr><td>Country</td><td>Date</td><td>Size</td></tr>
<tr><td>France</td><td>2001-01-01</td><td><i>25</i></td></tr>
<tr><td>spain</td><td>2005-05-05</td><td></td></tr>
<tr><td>Lebanon</td><td>2002-02-02</td><td><b>-17</b></td></tr>
<tr><td>Argentina</td><td>2005-04-04</td><td>100</td></tr>
<tr><td>USA</td><td></td><td>-6</td></tr>
</table>
Ответ 10
Другой подход к сортировке таблицы HTML. (на основе W3.JS HTML Сортировка)
var collection = [{
"Country": "France",
"Date": "2001-01-01",
"Size": "25",
}, {
"Country": "spain",
"Date": "2005-05-05",
"Size": "",
}, {
"Country": "Lebanon",
"Date": "2002-02-02",
"Size": "-17",
}, {
"Country": "Argentina",
"Date": "2005-04-04",
"Size": "100",
}, {
"Country": "USA",
"Date": "",
"Size": "-6",
}]
for (var j = 0; j < 3; j++) {
$("#myTable th:eq(" + j + ")").addClass("control-label clickable");
$("#myTable th:eq(" + j + ")").attr('onClick', "w3.sortHTML('#myTable', '.item', 'td:nth-child(" + (j + 1) + ")')");
}
$tbody = $("#myTable").append('<tbody></tbody>');
for (var i = 0; i < collection.length; i++) {
$tbody = $tbody.append('<tr class="item"><td>' + collection[i]["Country"] + '</td><td>' + collection[i]["Date"] + '</td><td>' + collection[i]["Size"] + '</td></tr>');
}
.control-label:after {
content: "*";
color: red;
}
.clickable {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.w3schools.com/lib/w3.js"></script>
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet" />
<p>Click the <strong>table headers</strong> to sort the table accordingly:</p>
<table id="myTable" class="w3-table-all">
<thead>
<tr>
<th>Country</th>
<th>Date</th>
<th>Size</th>
</tr>
</thead>
</table>
Ответ 11
Сортировка столбца html таблицы при загрузке страницы
var table = $('table#all_items_table');
var rows = table.find('tr:gt(0)').toArray().sort(comparer(3));
for (var i = 0; i < rows.length; i++) {
table.append(rows[i])
}
function comparer(index) {
return function (a, b) {
var v1= getCellValue(a, index),
v2= getCellValue(b, index);
return $.isNumeric(v2) && $.isNumeric(v1) ? v2 - v1: v2.localeCompare(v1)
}
}
function getCellValue(row, index) {
return parseFloat($(row).children('td').eq(index).html().replace(/,/g,'')); //1234234.45645->1234234
}
![enter image description here]()