Mam bardzo prostą tabelę HTML z 4 kolumnami:
Facility Name, Phone #, City, Specialty
Chcę, aby użytkownik mógł sortować tylko według nazwy obiektu i miasta .
Jak mogę to zakodować za pomocą jQuery?
Mam bardzo prostą tabelę HTML z 4 kolumnami:
Facility Name, Phone #, City, Specialty
Chcę, aby użytkownik mógł sortować tylko według nazwy obiektu i miasta .
Jak mogę to zakodować za pomocą jQuery?
Odpowiedzi:
Jeśli chcesz uniknąć wszystkich dzwonków i gwizdów, mogę zasugerować tę prostą sortElements
wtyczkę . Stosowanie:
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;
});
});
I demo. (kliknij nagłówki kolumn „miasto” i „placówka”, aby posortować)
Error: illegal character
html nie jest dokładnie taki sam, mam też thead i tboy, czy możesz mi w tym pomóc?
$.text([a]) == $.text([b])
używać $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
, naprawi to.
Natknąłem się na to i pomyślałem, że dorzucę moje 2 centy. Kliknij nagłówki kolumn, aby posortować rosnąco i ponownie, aby posortować malejąco.
$('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, np <a href="#">Test</a>
. Sortowanie dotyczy <a...
. Aby posortować tylko według tekstu, musisz zmienić html()
w ostatnim wierszu na text()
.
comparer(..)
jeśli wiesz dokładnie, jaki format chcesz obsługiwać). W międzyczasie, jeśli używasz yyyy-MM-dd
" string
" sortowania uporządkuje dane za Ciebie. np. jsbin.com/pugedip/1
Zdecydowanie najłatwiejszy z nich to: http://datatables.net/
Niezwykle proste ... po prostu upewnij się, że wybierzesz trasę zastępującą DOM (IE, budując tabelę i pozwalając DataTables na ponowne jej sformatowanie), a następnie upewnij się, że sformatujesz tabelę za pomocą <thead>
i <tbody>
lub nie zadziała. To chyba jedyny sposób.
Jest też wsparcie dla AJAX, itp. Podobnie jak w przypadku wszystkich naprawdę dobrych fragmentów kodu, BARDZO łatwo jest je wyłączyć. Zdziwiłbyś się jednak, czego możesz użyć. Zacząłem od „gołego” DataTable, który posortował tylko jedno pole, a potem zdałem sobie sprawę, że niektóre funkcje były naprawdę istotne dla tego, co robię. Klienci KOCHAJĄ nowe funkcje.
Dodatkowe punkty do DataTables za pełną obsługę ThemeRoller ...
Miałem też dobre szczęście z tableorter, ale nie jest to tak łatwe, nie tak dobrze udokumentowane i ma tylko dobre funkcje.
Właśnie zaczęliśmy używać tego zgrabnego narzędzia: https://plugins.jquery.com/tablesorter/
Film przedstawiający jego użycie jest dostępny pod adresem : http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
Z prostym stołem
<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>
Moja odpowiedź brzmiałaby: „bądź ostrożny”. Wiele dodatków do sortowania tabel jQuery sortuje tylko to, co jest przekazywane do przeglądarki. W wielu przypadkach należy pamiętać, że tabele są dynamicznymi zbiorami danych i mogą potencjalnie zawierać miliardy wierszy danych.
Wspominasz, że masz tylko 4 kolumny, ale co ważniejsze, nie wspominasz o liczbie wierszy, o których tutaj mówimy.
Jeśli przekażesz do przeglądarki 5000 wierszy z bazy danych, wiedząc, że rzeczywista tabela bazy danych zawiera 100 000 wierszy, moje pytanie brzmi: jaki jest sens w tworzeniu sortowania tabeli? Aby przeprowadzić właściwe sortowanie, należałoby odesłać zapytanie z powrotem do bazy danych i pozwolić bazie danych (narzędziu faktycznie zaprojektowanemu do sortowania danych) przeprowadzić sortowanie za Ciebie.
Odpowiadając wprost na twoje pytanie, najlepszym dodatkiem do sortowania, z jakim się spotkałem, jest Ingrid. Jest wiele powodów, dla których nie podoba mi się ten dodatek ("niepotrzebne dzwonki i gwizdki ...", jak to nazywasz), ale jedną z jego najlepszych cech pod względem rodzaju jest to, że używa Ajaxa i nie robi Załóżmy, że przekazałeś już wszystkie dane, zanim przeprowadzi sortowanie.
Zdaję sobie sprawę, że ta odpowiedź jest prawdopodobnie przesadzona (i spóźniona o ponad 2 lata) dla twoich wymagań, ale denerwuję się, gdy programiści z mojej dziedziny przeoczają ten punkt. Mam więc nadzieję, że ktoś inny to odbierze.
Czuję się teraz lepiej.
To dobry sposób na sortowanie tabeli:
$(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>
Skrzypce można znaleźć tutaj:
https://jsfiddle.net/e3s84Luw/
Wyjaśnienie można znaleźć tutaj: https://www.learningjquery.com/2017/03/how-to-sort-html-table-using-jquery-code
Uwielbiam tę zaakceptowaną odpowiedź, jednak rzadko pojawiają się wymagania dotyczące sortowania html i nie musisz dodawać ikon wskazujących kierunek sortowania. Wziąłem przykład użycia akceptacji odpowiedzi i szybko to naprawiłem, po prostu dodając bootstrap do mojego projektu i dodając następujący kod:
<div></div>
wewnątrz każdego <th>
, aby mieć miejsce na ustawienie ikony.
setIcon(this, inverse);
z Użycie zaakceptowanej odpowiedzi, poniżej linii:
th.click(function () {
i dodając metodę 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();
}
Oto demo . - Musisz albo uruchomić wersję demonstracyjną w przeglądarce Firefox lub IE, albo wyłączyć sprawdzanie typu MIME w przeglądarce Chrome, aby demonstracja działała. Zależy to od wtyczki sortElements, połączonej zaakceptowaną odpowiedzią, jako zasób zewnętrzny. Tylko jedno ostrzeżenie!
Oto wykres, który może być pomocny w podjęciu decyzji, którego użyć: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/
@Nick Grealy za odpowiedź jest super, ale nie bierze pod uwagę możliwe rowspan
atrybutów komórki nagłówka tabeli (i prawdopodobnie inne odpowiedzi nie zrobić albo). Oto ulepszenie odpowiedzi @Nick Grealy, które to rozwiązuje. Na podstawie tej odpowiedzi również (dzięki @Andrew Orlov).
Zastąpiłem również $.isNumeric
funkcję niestandardową (dzięki @zad), aby działała ze starszymi wersjami jQuery.
Aby go aktywować, dodaj class="sortable"
do <table>
tagu.
$(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;
};
Możesz użyć wtyczki jQuery ( breedjs ), która zapewnia sortowanie, filtrowanie i paginację:
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')
});
});
});
Ten nie zawiesza przeglądarek, można je dalej łatwo konfigurować:
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()
}
W odpowiedzi Jamesa zmienię tylko funkcję sortowania, aby była bardziej uniwersalna. W ten sposób posortuje tekst alfabetycznie, a liczby takie jak liczby.
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;
}
Inne podejście do sortowania tabeli HTML. (na podstawie sortowania 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>
Skończyło się na odpowiedzi Nicka (najpopularniejszej, ale nie akceptowanej) https://stackoverflow.com/a/19947532/5271220
i połączyłem to z https://stackoverflow.com/a/16819442/5271220, ale nie chciałem dodawać ikon ani fontawesome do projektu. Style CSS dla sort-column-asc / desc Zrobiłem kolor, dopełnienie, zaokrąglone obramowanie.
Zmodyfikowałem go również tak, aby działał według klas, a nie według jakichkolwiek, abyśmy mogli kontrolować, które z nich można sortować. Może się to również przydać później, jeśli istnieją dwie tabele, chociaż należałoby w tym celu wprowadzić więcej modyfikacji.
ciało:
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"; ...
... dalej w dół ciała
$("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);
});
Funkcje:
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 = "";
});
}
Mój głos! jquery.sortElements.js i proste jquery
Bardzo proste, bardzo łatwe, dzięki 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
Jeden dorsz lepiej!
Funkcja dla wszystkich stołów w całym Th ... Zobacz to!
PRÓBNY
.live()
.