Tôi có một bảng HTML rất đơn giản với 4 cột:
Facility Name, Phone #, City, Specialty
Tôi muốn người dùng chỉ có thể sắp xếp theo Tên Cơ sở và Thành phố .
Làm cách nào để viết mã này bằng jQuery?
Tôi có một bảng HTML rất đơn giản với 4 cột:
Facility Name, Phone #, City, Specialty
Tôi muốn người dùng chỉ có thể sắp xếp theo Tên Cơ sở và Thành phố .
Làm cách nào để viết mã này bằng jQuery?
Câu trả lời:
Nếu bạn muốn tránh tất cả các chuông và còi thì tôi có thể đề xuất plugin đơn giản nàysortElements
. Sử dụng:
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;
});
});
Và một bản demo. (nhấp vào tiêu đề cột "thành phố" và "cơ sở" để sắp xếp)
Error: illegal character
, html không hoàn toàn giống nhau, tôi cũng có thead và tboy, bạn có thể giúp tôi với vấn đề này không?
$.text([a]) == $.text([b])
sử dụng $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
sẽ sửa nó.
Tôi đã xem qua điều này và nghĩ rằng tôi sẽ ném 2 xu của mình. Nhấp vào tiêu đề cột để sắp xếp tăng dần và một lần nữa để sắp xếp giảm dần.
$('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, ví dụ như <a href="#">Test</a>
sắp xếp liên quan đến <a...
. Để sắp xếp theo văn bản, bạn chỉ cần thay đổi html()
trong dòng cuối cùng text()
.
comparer(..)
nếu bạn biết chính xác định dạng bạn muốn hỗ trợ). Trong khi đó, nếu bạn sử dụng yyyy-MM-dd
, " string
" sắp xếp sẽ sắp xếp dữ liệu cho bạn. ví dụ: jsbin.com/pugedip/1
Cho đến nay, cách dễ nhất tôi đã sử dụng là: http://datatables.net/
Thật đơn giản ... chỉ cần đảm bảo nếu bạn đi theo lộ trình thay thế DOM (IE, xây dựng bảng và để DataTables định dạng lại nó) thì hãy đảm bảo định dạng bảng của bạn <thead>
và <tbody>
nó sẽ không hoạt động. Đó là về gotcha duy nhất.
Ngoài ra còn có hỗ trợ cho AJAX, v.v. Cũng như tất cả các đoạn mã thực sự tốt, RẤT dễ dàng tắt tất cả. Bạn sẽ ngạc nhiên về những gì bạn có thể sử dụng, mặc dù. Tôi đã bắt đầu với một DataTable "trần" chỉ sắp xếp một trường và sau đó nhận ra rằng một số tính năng thực sự phù hợp với những gì tôi đang làm. Khách hàng YÊU các tính năng mới.
Điểm thưởng cho DataTables để hỗ trợ ThemeRoller đầy đủ ....
Tôi cũng đã gặp may mắn với trình sắp xếp bảng, nhưng nó không dễ dàng như vậy, không hoàn toàn bằng tài liệu và chỉ có các tính năng ok.
Chúng tôi mới bắt đầu sử dụng công cụ khéo léo này: https://plugins.jquery.com/tablesorter/
Có một video về việc sử dụng nó tại: http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
Với một cái bàn đơn giản
<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>
Câu trả lời của tôi sẽ là "cẩn thận". Rất nhiều tiện ích sắp xếp bảng jQuery chỉ sắp xếp những gì bạn chuyển đến trình duyệt. Trong nhiều trường hợp, bạn phải nhớ rằng các bảng là tập hợp dữ liệu động và có khả năng chứa hàng trăm dòng dữ liệu.
Bạn có đề cập rằng bạn chỉ có 4 cột, nhưng quan trọng hơn, bạn không đề cập đến việc chúng ta đang nói về bao nhiêu hàng.
Nếu bạn chuyển 5000 dòng tới trình duyệt từ cơ sở dữ liệu, biết rằng bảng cơ sở dữ liệu thực tế chứa 100.000 hàng, câu hỏi của tôi là: điểm nào trong việc tạo bảng có thể sắp xếp được? Để thực hiện sắp xếp hợp lý, bạn phải gửi truy vấn trở lại cơ sở dữ liệu và để cơ sở dữ liệu (một công cụ thực sự được thiết kế để sắp xếp dữ liệu) thực hiện việc sắp xếp cho bạn.
Trong câu trả lời trực tiếp cho câu hỏi của bạn, tiện ích sắp xếp tốt nhất mà tôi gặp phải là Ingrid. Có nhiều lý do mà tôi không thích tiện ích bổ sung này ("chuông và còi không cần thiết ..." như bạn gọi), nhưng một trong những tính năng tốt nhất về mặt sắp xếp, là nó sử dụng ajax và không ' T giả định rằng bạn đã truyền tất cả dữ liệu trước khi thực hiện.
Tôi nhận ra rằng câu trả lời này có thể là quá mức cần thiết (và trễ hơn 2 năm) cho các yêu cầu của bạn, nhưng tôi cảm thấy khó chịu khi các nhà phát triển trong lĩnh vực của tôi bỏ qua điểm này. Vì vậy, tôi hy vọng người khác chọn nó.
Bây giờ tôi thấy khá hơn rồi.
Tôi thích câu trả lời được chấp nhận này, tuy nhiên, hiếm khi bạn nhận được yêu cầu sắp xếp html và không phải thêm biểu tượng cho biết hướng sắp xếp. Tôi đã lấy ví dụ sử dụng câu trả lời chấp nhận và sửa nó nhanh chóng bằng cách thêm bootstrap vào dự án của tôi và thêm đoạn mã sau:
<div></div>
bên trong mỗi <th>
cái để bạn có một nơi để đặt biểu tượng.
setIcon(this, inverse);
từ Cách sử dụng của câu trả lời được chấp nhận, bên dưới dòng:
th.click(function () {
và bằng cách thêm phương thức 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();
}
Đây là một bản demo . - Bạn cần chạy bản demo trong Firefox hoặc IE hoặc tắt kiểm tra loại MIME của Chrome để bản demo hoạt động. Nó phụ thuộc vào Plugin sortElements, được liên kết bởi câu trả lời được chấp nhận, dưới dạng tài nguyên bên ngoài. Chỉ cần một cái đầu lên!
Đây là một cách hay để sắp xếp một bảng:
$(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>
Fiddle có thể được tìm thấy ở đây:
https://jsfiddle.net/e3s84Luw/
Lời giải thích có thể được tìm thấy ở đây: https://www.learningjquery.com/2017/03/how-to-sort-html-table-USE-jquery-code
Đây là một biểu đồ có thể hữu ích khi quyết định sử dụng: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-lologists/
Câu trả lời của @Nick Grealy rất hay, nhưng nó không rowspan
tính đến các thuộc tính có thể có của các ô tiêu đề bảng (và có lẽ các câu trả lời khác cũng không làm điều đó). Đây là một cải tiến của câu trả lời của @Nick Grealy để khắc phục điều đó. Dựa trên câu trả lời này quá (cảm ơn @Andrew Orlov).
Tôi cũng đã thay thế $.isNumeric
chức năng này bằng một tùy chỉnh (cảm ơn @zad) để làm cho nó hoạt động với các phiên bản jQuery cũ hơn.
Để kích hoạt nó, thêm class="sortable"
vào <table>
thẻ.
$(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;
};
Bạn có thể sử dụng một plugin jQuery ( Breedjs ) cung cấp sắp xếp, bộ lọc và phân trang:
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')
});
});
});
Cái này không treo trình duyệt, dễ dàng cấu hình hơn nữa:
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()
}
Theo phản hồi của James, tôi sẽ chỉ thay đổi chức năng sắp xếp để làm cho nó phổ quát hơn. Bằng cách này, nó sẽ sắp xếp văn bản theo thứ tự chữ cái và số như số.
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;
}
Một cách tiếp cận khác để sắp xếp bảng HTML. (dựa trên Sắp xếp HTML của 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>
Cuối cùng tôi đã sử dụng câu trả lời của Nick (phổ biến nhất nhưng không được chấp nhận) https://stackoverflow.com/a/19947532/5271220
và kết hợp nó với https://stackoverflow.com/a/16819442/5271220 nhưng không muốn thêm biểu tượng hoặc phông chữ vào dự án. Các kiểu CSS cho sort-cột-asc / desc tôi đã tô màu, đệm, viền tròn.
Tôi cũng đã sửa đổi nó để đi theo lớp chứ không phải bất kỳ để chúng tôi có thể kiểm soát cái nào có thể sắp xếp được. Điều này cũng có thể có ích sau này nếu có hai bảng mặc dù cần phải sửa đổi nhiều hơn cho điều đó.
thân hình:
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"; ...
... xuống cơ thể
$("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);
});
chức năng:
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 = "";
});
}
Phiếu bầu của tôi! jquery.sortElements.js và jquery đơn giản
Rất đơn giản, rất dễ dàng, cảm ơn 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 làm código
Một cod tốt hơn!
Chức năng cho tất cả các bảng trong tất cả các thời gian ... Nhìn nó!
BẢN GIỚI THIỆU
.live()
.