У мене дуже проста таблиця HTML з 4 колонками:
Facility Name, Phone #, City, Specialty
Я хочу, щоб користувач міг сортувати лише за назвою об'єкта та містом .
Як я можу кодувати це за допомогою jQuery?
У мене дуже проста таблиця HTML з 4 колонками:
Facility Name, Phone #, City, Specialty
Я хочу, щоб користувач міг сортувати лише за назвою об'єкта та містом .
Як я можу кодувати це за допомогою jQuery?
Відповіді:
Якщо ви хочете уникнути всіх дзвіночків, то я можу запропонувати цей простий sortElements
плагін . Використання:
var table = $('table');
$('.sortable th')
.wrapInner('<span title="sort this column"/>')
.each(function(){
var th = $(this),
thIndex = th.index(),
inverse = false;
th.click(function(){
table.find('td').filter(function(){
return $(this).index() === thIndex;
}).sortElements(function(a, b){
if( $.text([a]) == $.text([b]) )
return 0;
return $.text([a]) > $.text([b]) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}, function(){
// parentNode is the element we want to move
return this.parentNode;
});
inverse = !inverse;
});
});
І демонстрація. (для сортування натисніть заголовки стовпців "місто" та "об'єкт")
Error: illegal character
html точно не збігається, у мене також є thead та tboy, чи можете ви мені допомогти з цим?
$.text([a]) == $.text([b])
використання $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
виправите це.
Я натрапив на це, і думав, що кину свої 2 копійки. Клацніть на заголовки стовпців для сортування за зростанням та ще раз для сортування за спаданням.
$('th').click(function(){
var table = $(this).parents('table').eq(0)
var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()))
this.asc = !this.asc
if (!this.asc){rows = rows.reverse()}
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
})
function comparer(index) {
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB)
}
}
function getCellValue(row, index){ return $(row).children('td').eq(index).text() }
table, th, td {
border: 1px solid black;
}
th {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><th>Country</th><th>Date</th><th>Size</th></tr>
<tr><td>France</td><td>2001-01-01</td><td>25</td></tr>
<tr><td><a href=#>spain</a></td><td>2005-05-05</td><td></td></tr>
<tr><td>Lebanon</td><td>2002-02-02</td><td>-17</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>
td
s, наприклад, <a href="#">Test</a>
сортування стосується <a...
. Для сортування за текстом потрібно лише змінити html()
в останньому рядку на text()
.
comparer(..)
якби точно знали, який формат хочете підтримувати). Тим часом, якщо ви використовуєте yyyy-MM-dd
, " string
" сортування буде замовляти дані для вас. наприклад, jsbin.com/pugedip/1
На сьогоднішній день, найпростіший з них, який я використовував: http://datatables.net/
Дивовижно просте ... просто переконайтесь, що ви переходите до маршруту заміни DOM (IE, будуючи таблицю і дозволяючи DataTables переформатувати її), то переконайтеся, що відформатуйте вашу таблицю <thead>
і <tbody>
чи вона не працюватиме. Це про єдиний готч.
Також є підтримка AJAX і т. Д. Як і у всіх справді хороших фрагментів коду, це також ДУЖЕ легко відключити. Ти б здивувався тим, що ти можеш використати. Я почав з "голого" DataTable, який сортував лише одне поле, а потім зрозумів, що деякі функції дійсно стосуються того, що я роблю. Клієнти ЛЮБИТЬ нові функції.
Бонус вказує на DataTables за повну підтримку ThemeRoller ....
У мене теж було пощастило з tableorter, але це не так просто, не так добре зафіксовано і має лише нормальні функції.
Ми щойно почали використовувати цей інструмент гладкого: https://plugins.jquery.com/tablesorter/
Є відео про його використання за адресою: http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
За допомогою простої таблиці
<table id="tableRoster">
<thead>
<tr>
<th><input type="checkbox" class="rCheckBox" value="all" id="rAll" ></th>
<th>User</th>
<th>Verified</th>
<th>Recently Accessed</th>
<th> </th>
</tr>
</thead>
Моя відповідь була б "обережно". Багато додатків для сортування таблиць jQuery сортують лише те, що ви передаєте в браузер. У багатьох випадках потрібно пам’ятати, що таблиці - це динамічні набори даних, які потенційно можуть містити мільйони рядків даних.
Ви згадуєте, що у вас є лише 4 стовпці, але набагато важливіше, ви не згадуєте, скільки рядків ми говоримо тут.
Якщо ви передаєте 5000 рядків у браузер із бази даних, знаючи, що фактична таблиця бази даних містить 100 000 рядків, моє питання: який сенс робити таблицю сортовою? Для того, щоб зробити належне сортування, вам доведеться відправити запит назад до бази даних, і дозволити базі даних (інструменту, який фактично призначений для сортування даних), сортувати за вас.
Що стосується прямої відповіді на ваше запитання, найкращим доповненням для сортування, на які я потрапила, є Інгрід. Є багато причин, що мені не подобається цей додаток ("непотрібні дзвіночки ...", як ви це називаєте), але одна з найкращих його функцій з точки зору сортування - це те, що він використовує ajax, а не " t припустимо, що ви вже передали йому всі дані, перш ніж вона зробить їхнє сортування.
Я усвідомлюю, що ця відповідь, ймовірно, є надмірною (і запізнилася понад 2 роки) на ваші вимоги, але я дратуюся, коли розробники в моїй галузі не помічають цього питання. Тож сподіваюся, що хтось інший підбере це.
Зараз я почуваюся краще.
Це хороший спосіб сортування таблиці:
$(document).ready(function () {
$('th').each(function (col) {
$(this).hover(
function () {
$(this).addClass('focus');
},
function () {
$(this).removeClass('focus');
}
);
$(this).click(function () {
if ($(this).is('.asc')) {
$(this).removeClass('asc');
$(this).addClass('desc selected');
sortOrder = -1;
} else {
$(this).addClass('asc selected');
$(this).removeClass('desc');
sortOrder = 1;
}
$(this).siblings().removeClass('asc selected');
$(this).siblings().removeClass('desc selected');
var arrData = $('table').find('tbody >tr:has(td)').get();
arrData.sort(function (a, b) {
var val1 = $(a).children('td').eq(col).text().toUpperCase();
var val2 = $(b).children('td').eq(col).text().toUpperCase();
if ($.isNumeric(val1) && $.isNumeric(val2))
return sortOrder == 1 ? val1 - val2 : val2 - val1;
else
return (val1 < val2) ? -sortOrder : (val1 > val2) ? sortOrder : 0;
});
$.each(arrData, function (index, row) {
$('tbody').append(row);
});
});
});
});
table, th, td {
border: 1px solid black;
}
th {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr><th>id</th><th>name</th><th>age</th></tr>
<tr><td>1</td><td>Julian</td><td>31</td></tr>
<tr><td>2</td><td>Bert</td><td>12</td></tr>
<tr><td>3</td><td>Xavier</td><td>25</td></tr>
<tr><td>4</td><td>Mindy</td><td>32</td></tr>
<tr><td>5</td><td>David</td><td>40</td></tr>
</table>
Загадку можна знайти тут:
https://jsfiddle.net/e3s84Luw/
Пояснення можна знайти тут: https://www.learningjquery.com/2017/03/how-to-sort-html-table-using-jquery-code
Мені подобається ця прийнята відповідь, проте рідко ви отримуєте вимоги до сортування html та не потрібно додавати піктограми, що вказують напрямок сортування. Я взяв приклад використання прийому відповіді та швидко це виправив, просто додавши завантажувальний проект до свого проекту та додавши наступний код:
<div></div>
всередині кожного, <th>
щоб у вас було місце встановити значок.
setIcon(this, inverse);
з використання прийнятої відповіді під рядком:
th.click(function () {
і додавши метод setIcon:
function setIcon(element, inverse) {
var iconSpan = $(element).find('div');
if (inverse == false) {
$(iconSpan).removeClass();
$(iconSpan).addClass('icon-white icon-arrow-up');
} else {
$(iconSpan).removeClass();
$(iconSpan).addClass('icon-white icon-arrow-down');
}
$(element).siblings().find('div').removeClass();
}
Ось демонстрація . - Вам потрібно або запустити демонстрацію у Firefox або IE, або відключити перевірку типу MIME Chrome для того, щоб демонстрація працювала. Це залежить від плагіну sortElements, пов'язаного прийнятою відповіддю, як зовнішнього ресурсу. Просто голови вгору!
Ось діаграма, яка може бути корисною для вирішення, яку використовувати: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/
@Nick Grealy відповідь чудова, але вона не враховує можливих rowspan
атрибутів комірок заголовка таблиці (і, ймовірно, інші відповіді теж не роблять цього). Ось вдосконалення відповіді @Nick Grealy, яке виправляє це. Виходячи з цієї відповіді теж (дякую @Andrew Orlov).
Я також замінив $.isNumeric
функцію на власну (спасибі @zad), щоб змусити її працювати зі старими версіями jQuery.
Щоб активувати його, додайте class="sortable"
до <table>
тегу.
$(document).ready(function() {
$('table.sortable th').click(function(){
var table = $(this).parents('table').eq(0);
var column_index = get_column_index(this);
var rows = table.find('tbody tr').toArray().sort(comparer(column_index));
this.asc = !this.asc;
if (!this.asc){rows = rows.reverse()};
for (var i = 0; i < rows.length; i++){table.append(rows[i])};
})
});
function comparer(index) {
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index);
return isNumber(valA) && isNumber(valB) ? valA - valB : valA.localeCompare(valB);
}
}
function getCellValue(row, index){ return $(row).children('td').eq(index).html() };
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function get_column_index(element) {
var clickedEl = $(element);
var myCol = clickedEl.closest("th").index();
var myRow = clickedEl.closest("tr").index();
var rowspans = $("th[rowspan]");
rowspans.each(function () {
var rs = $(this);
var rsIndex = rs.closest("tr").index();
var rsQuantity = parseInt(rs.attr("rowspan"));
if (myRow > rsIndex && myRow <= rsIndex + rsQuantity - 1) {
myCol++;
}
});
// alert('Row: ' + myRow + ', Column: ' + myCol);
return myCol;
};
Ви можете використовувати плагін jQuery ( Brejdjs ), який забезпечує сортування, фільтрування та пагинацію:
HTML:
<table>
<thead>
<tr>
<th sort='name'>Name</th>
<th>Phone</th>
<th sort='city'>City</th>
<th>Speciality</th>
</tr>
</thead>
<tbody>
<tr b-scope="people" b-loop="person in people">
<td b-sort="name">{{person.name}}</td>
<td>{{person.phone}}</td>
<td b-sort="city">{{person.city}}</td>
<td>{{person.speciality}}</td>
</tr>
</tbody>
</table>
JS:
$(function(){
var data = {
people: [
{name: 'c', phone: 123, city: 'b', speciality: 'a'},
{name: 'b', phone: 345, city: 'a', speciality: 'c'},
{name: 'a', phone: 234, city: 'c', speciality: 'b'},
]
};
breed.run({
scope: 'people',
input: data
});
$("th[sort]").click(function(){
breed.sort({
scope: 'people',
selector: $(this).attr('sort')
});
});
});
Цей веб-переглядач не відключає веб-переглядача, легко налаштовується далі:
var table = $('table');
$('th.sortable').click(function(){
var table = $(this).parents('table').eq(0);
var ths = table.find('tr:gt(0)').toArray().sort(compare($(this).index()));
this.asc = !this.asc;
if (!this.asc)
ths = ths.reverse();
for (var i = 0; i < ths.length; i++)
table.append(ths[i]);
});
function compare(idx) {
return function(a, b) {
var A = tableCell(a, idx), B = tableCell(b, idx)
return $.isNumeric(A) && $.isNumeric(B) ?
A - B : A.toString().localeCompare(B)
}
}
function tableCell(tr, index){
return $(tr).children('td').eq(index).text()
}
На відповідь Джеймса я лише зміню функцію сортування, щоб зробити її більш універсальною. Таким чином він буде сортувати текст за алфавітом та числами, як числа.
if( $.text([a]) == $.text([b]) )
return 0;
if(isNaN($.text([a])) && isNaN($.text([b]))){
return $.text([a]) > $.text([b]) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}
else{
return parseInt($.text([a])) > parseInt($.text([b])) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}
Ще один підхід до сортування таблиці HTML. (на основі сортування HTML W3.JS )
/* Facility Name */
$('#bioTable th:eq(0)').addClass("control-label pointer");
/* Phone # */
$('#bioTable th:eq(1)').addClass("not-allowed");
/* City */
$('#bioTable th:eq(2)').addClass("control-label pointer");
/* Specialty */
$('#bioTable th:eq(3)').addClass("not-allowed");
var collection = [{
"FacilityName": "MinION",
"Phone": "999-8888",
"City": "France",
"Specialty": "Genetic Prediction"
}, {
"FacilityName": "GridION X5",
"Phone": "999-8812",
"City": "Singapore",
"Specialty": "DNA Assembly"
}, {
"FacilityName": "PromethION",
"Phone": "929-8888",
"City": "San Francisco",
"Specialty": "DNA Testing"
}, {
"FacilityName": "iSeq 100 System",
"Phone": "999-8008",
"City": "Christchurch",
"Specialty": "gDNA-mRNA sequencing"
}]
$tbody = $("#bioTable").append('<tbody></tbody>');
for (var i = 0; i < collection.length; i++) {
$tbody = $tbody.append('<tr class="item"><td>' + collection[i]["FacilityName"] + '</td><td>' + collection[i]["Phone"] + '</td><td>' + collection[i]["City"] + '</td><td>' + collection[i]["Specialty"] + '</td></tr>');
}
.control-label:after {
content: "*";
color: red;
}
.pointer {
cursor: pointer;
}
.not-allowed {
cursor: not-allowed;
}
<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="bioTable" class="w3-table-all">
<thead>
<tr>
<th onclick="w3.sortHTML('#bioTable', '.item', 'td:nth-child(1)')">Facility Name</th>
<th>Phone #</th>
<th onclick="w3.sortHTML('#bioTable', '.item', 'td:nth-child(3)')">City</th>
<th>Specialty</th>
</tr>
</thead>
</table>
Нарешті я використав відповідь Ніка (найпопулярніший, але не прийнятий) https://stackoverflow.com/a/19947532/5271220
і поєднав його з https://stackoverflow.com/a/16819442/5271220, але не хотів додавати піктограми чи приємно в проект. Стилі CSS для сортування стовпців-asc / desc я зробив кольором, набиванням, округлою облямівкою.
Я також модифікував його для класу, а не для будь-якого, щоб ми могли контролювати, які з них можна сортувати. Це також може стати в нагоді пізніше, якщо є дві таблиці, хоча для цього потрібно буде зробити більше модифікацій.
корпус:
html += "<thead>\n";
html += "<th></th>\n";
html += "<th class=\"sort-header\">Name <span></span></i></th>\n";
html += "<th class=\"sort-header\">Status <span></span></th>\n";
html += "<th class=\"sort-header\">Comments <span></span></th>\n";
html += "<th class=\"sort-header\">Location <span></span></th>\n";
html += "<th nowrap class=\"sort-header\">Est. return <span></span></th>\n";
html += "</thead>\n";
html += "<tbody>\n"; ...
... далі вниз по тілу
$("body").on("click", ".sort-header", function (e) {
var table = $(this).parents('table').eq(0)
var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()))
this.asc = !this.asc
if (!this.asc) { rows = rows.reverse() }
for (var i = 0; i < rows.length; i++) { table.append(rows[i]) }
setIcon(e.target, this.asc);
});
функції:
function comparer(index) {
return function (a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB)
}
}
function getCellValue(row, index) {
return $(row).children('td').eq(index).text()
}
function setIcon(element, inverse) {
var iconSpan = $(element).find('span');
if (inverse == true) {
$(iconSpan).removeClass();
$(iconSpan).addClass('sort-column-asc');
$(iconSpan)[0].innerHTML = " ↑ " // arrow up
} else {
$(iconSpan).removeClass();
$(iconSpan).addClass('sort-column-desc');
$(iconSpan)[0].innerHTML = " ↓ " // arrow down
}
$(element).siblings().find('span').each(function (i, obj) {
$(obj).removeClass();
obj.innerHTML = "";
});
}
Мій голос! jquery.sortElements.js та простий jquery
Дуже простий, дуже простий, завдяки nandhp ...
$('th').live('click', function(){
var th = $(this), thIndex = th.index(), var table = $(this).parent().parent();
switch($(this).attr('inverse')){
case 'false': inverse = true; break;
case 'true:': inverse = false; break;
default: inverse = false; break;
}
th.attr('inverse',inverse)
table.find('td').filter(function(){
return $(this).index() === thIndex;
}).sortElements(function(a, b){
return $.text([a]) > $.text([b]) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}, function(){
// parentNode is the element we want to move
return this.parentNode;
});
inverse = !inverse;
});
Dei uma melhorada do código
Одна треска краще!
Функція для всіх таблиць у всіх Th за весь час ... Подивіться!
DEMO
.live()
.