Я пытаюсь отсортировать таблицу по горизонтали.
Сортировка состоит из щелчка по заголовку, поэтому элементы должны быть отсортированы.
Я пробовал код ниже
Но он не сортирует его должным образом. Какое адекватное решение для этого, без каких-либо плагинов?
$('th').click(function() {
var rows = $('tr');
rows.eq(0).find('td').sort(function(a, b) {
return $.text([a]) > $.text([b]) ? 1 : -1;
}).each(function(newIndex) {
var originalIndex = $(this).index();
rows.each(function() {
var td = $(this).find('td');
if (originalIndex !== newIndex)
td.eq(originalIndex).insertAfter(td.eq(newIndex));
});
});
})
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id = "myTable">
<tr>
<th>Product</th>
<td>Golden Watch</td>
<td>Silver Watch</td>
<td>Car 2018</td>
<td>Wooden Table</td>
<td>Sport Car 2019</td>
<td>Perfume</td>
<td>Car 2010</td>
<td>Piano</td>
</tr>
<tr>
<th>Price($)</th>
<td>1000</td>
<td>600</td>
<td>60000</td>
<td>50</td>
<td>100000</td>
<td>100</td>
<td>10000</td>
<td>250000</td>
</tr>
<tr>
<th>Origin Country</th>
<td>Switzerland</td>
<td>USA</td>
<td>Germany</td>
<td>Sweden</td>
<td>Italy</td>
<td>France</td>
<td>England</td>
<td>Austria</td>
</table>
Чтобы отсортировать числа, вам нужно сделать их числовыми, а не строковыми, поскольку 5000 больше 10000 в алфавитном порядке.
@charlietfl Да, те же самые отношения. Он должен отсортировать строку с щелчком по заголовку.
Вот версия решения, которое я придумал.
tr
вместе.
th
был нажат с помощью его innerHTML. Если это одно из строковых полей, я сделал localeCompare для строк. В противном случае, если это числовая цена, я просто вычел их для сортировки.var $tableRows = $('#myTable tr');
var preloadData = $tableRows.first().find('td').map(function(index){
return {
product: $tableRows.eq(0).find('td').eq(index).html().trim()
, price: parseInt($tableRows.eq(1).find('td').eq(index).html().trim(), 10)
, originCountry: $tableRows.eq(2).find('td').eq(index).html().trim()
}
}).get();
$(document).on('click', '#myTable tr', function(e){
var sortDesc = e.target.classList.contains('asc');
var sortingRow
if (e.target.innerHTML === 'Product') {
sortingRow = 0;
preloadData.sort(function(a, b){
if (sortDesc) return b.product.localeCompare(a.product);
return a.product.localeCompare(b.product);
});
} else if (e.target.innerHTML === 'Price($)') {
sortingRow = 1;
preloadData.sort(function(a, b){
if (sortDesc) return b.price - a.price;
return a.price - b.price;
});
} else {
sortingRow = 2;
preloadData.sort(function(a, b){
if (sortDesc) return b.originCountry.localeCompare(a.originCountry);
return a.originCountry.localeCompare(b.originCountry);
});
}
$('#myTable').html(
preloadData.reduce(function($rows, columnData, index){
if (index < 1) {
$rows.eq(0).append('<th>Product</th>');
$rows.eq(1).append('<th>Price($)</th>');
$rows.eq(2).append('<th>Origin Country</th>');
if (!sortDesc) $rows.eq(sortingRow).find('th').addClass('asc');
}
$rows.eq(0).append('<td>'+ columnData.product +'</td>');
$rows.eq(1).append('<td>'+ columnData.price +'</td>');
$rows.eq(2).append('<td>'+ columnData.originCountry +'</td>');
return $rows;
}, $('<tr><tr><tr>'))
);
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id = "myTable">
<tr>
<th>Product</th>
<td>Golden Watch</td>
<td>Silver Watch</td>
<td>Car 2018</td>
<td>Wooden Table</td>
<td>Sport Car 2019</td>
<td>Perfume</td>
<td>Car 2010</td>
<td>Piano</td>
</tr>
<tr>
<th>Price($)</th>
<td>1000</td>
<td>600</td>
<td>60000</td>
<td>50</td>
<td>100000</td>
<td>100</td>
<td>10000</td>
<td>250000</td>
</tr>
<tr>
<th>Origin Country</th>
<td>Switzerland</td>
<td>USA</td>
<td>Germany</td>
<td>Sweden</td>
<td>Italy</td>
<td>France</td>
<td>England</td>
<td>Austria</td>
</table>
Обновлено: добавление настройки класса asc
в строку, отсортированную по возрастанию. Если щелкнуть ее второй раз, она перевернется для сортировки по убыванию.
Вот общий подход, который не заботится о том, сколько строк или какова маркировка.
Сначала он создает массив rowData, где каждый вложенный массив представляет собой массив объектов с исходным номером столбца и текстом из каждой ячейки. При создании этого; атрибут данных добавляется к каждой ячейке, поэтому он знает, что это постоянный номер столбца, который будет использоваться для сохранения отношений столбцов.
Это то, что сначала сортируется, поэтому можно создать объект для хранения исходного номера столбца с новым индексом сортировки. Затем, когда каждая строка ячеек сортируется
// store row data arrays for easy sorting
var rowData = $('tr').map(function(rIdx, row) {
return [$(row).children('td').map(function(cIdx, cell) {
// store col # on each cell to use later for matching column sort order
$(cell).data('col', cIdx + 1);
// these objects used to keep original column numbers with sorted text
return {
col: cIdx + 1,
text: cell.textContent
}
}).get()];
}).get();
var $th=$('#myTable th'),
$rows = $('#myTable tr');
$th.click(function() {
var $cell = $(this),
rIdx = $cell.parent().index(),
isSorted = $cell.hasClass('sorted'),
dir = isSorted ? $cell.hasClass('asc') ? 'dsc':'asc' :'asc';
$cell.removeClass('asc dsc').addClass('sorted '+ dir);
$th.not(this).removeClass('sorted asc dsc');
$rows.each(function() {
var sortedCells = $(this).children('td').sort(rowCellSorter(rIdx, dir));
$(this).append(sortedCells)
});
});
function rowCellSorter(rIdx, dir) {
var sortOrder = getSorterOrder(rIdx, dir);
return function(a, b) {
var aCol = $(a).data('col'),
bCol = $(b).data('col')
return sortOrder[aCol] - sortOrder[bCol]
}
}
function getSorterOrder(rIdx, dir) {
var dataRow = rowData[rIdx].slice().sort(dataRowSorter);
if (dir === 'dsc'){
dataRow.reverse()
}
// object with column num as keys, sort index as values
return dataRow.reduce(function(a, c, i) {
a[c.col] = i;
return a;
}, {});
}
function dataRowSorter(a, b) {
if (isNaN(a.text)) { // text sort
return a.text.localeCompare(b.text)
} else { // num sort
return a.text - b.text
}
}
.asc:after{
content:' > '
}
.dsc:after{
content:' < '
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id = "myTable">
<tr>
<th>Product</th>
<td>Golden Watch</td>
<td>Silver Watch</td>
<td>Car 2018</td>
<td>Wooden Table</td>
<td>Sport Car 2019</td>
<td>Perfume</td>
<td>Car 2010</td>
<td>Piano</td>
</tr>
<tr>
<th>Price($)</th>
<td>1000</td>
<td>600</td>
<td>60000</td>
<td>50</td>
<td>100000</td>
<td>100</td>
<td>10000</td>
<td>250000</td>
</tr>
<tr>
<th>Origin Country</th>
<td>Switzerland</td>
<td>USA</td>
<td>Germany</td>
<td>Sweden</td>
<td>Italy</td>
<td>France</td>
<td>England</td>
<td>Austria</td>
</table>
Сохранить те же отношения столбцов? Если да, то какой должна быть основная сортировка... верхняя строка?