Ho una tabella HTML molto semplice con 4 colonne:
Facility Name, Phone #, City, Specialty
Voglio che l'utente sia in grado di ordinare solo per Nome struttura e Città .
Come posso codificare questo usando jQuery?
Ho una tabella HTML molto semplice con 4 colonne:
Facility Name, Phone #, City, Specialty
Voglio che l'utente sia in grado di ordinare solo per Nome struttura e Città .
Come posso codificare questo usando jQuery?
Risposte:
Se vuoi evitare tutte le campane e fischietti, allora posso suggerire questo semplice sortElements
plugin . Uso:
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;
});
});
E una demo. (fai clic sulle intestazioni di colonna "città" e "struttura" per ordinare)
Error: illegal character
l'html non è esattamente lo stesso, ho anche thead e tboy, puoi aiutarmi con questo per favore?
$.text([a]) == $.text([b])
utilizzare $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
lo risolverà.
Mi sono imbattuto in questo e ho pensato di buttare i miei 2 centesimi. Fare clic sulle intestazioni di colonna per ordinare in ordine crescente e di nuovo per ordinare in ordine decrescente.
$('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, ad esempio <a href="#">Test</a>
l'ordinamento riguarda <a...
. Per ordinare solo per testo, è necessario modificare html()
l'ultima riga in text()
.
comparer(..)
se sapessi esattamente quale formato desideri supportare). Nel frattempo, se utilizzi yyyy-MM-dd
, l '" string
" ordinamento ordinerà i dati per te. ad es. jsbin.com/pugedip/1
Di gran lunga il più semplice che ho usato è: http://datatables.net/
Sorprendentemente semplice ... basta assicurarsi se si va il percorso di sostituzione DOM (IE, la costruzione di un tavolo e lasciando DataTables riformattarlo) quindi assicurarsi di formattare la vostra tavola con <thead>
e <tbody>
o non funzionerà. Questo è l'unico gotcha.
C'è anche il supporto per AJAX, ecc. Come per tutti i pezzi di codice davvero buoni, è anche MOLTO facile spegnerlo. Saresti sorpreso di ciò che potresti usare, però. Ho iniziato con una DataTable "nuda" che ordinava solo un campo e poi mi sono reso conto che alcune delle funzionalità erano davvero rilevanti per quello che sto facendo. I clienti AMANO le nuove funzionalità.
Punti bonus a DataTables per il supporto completo di ThemeRoller ....
Ho anche avuto buona fortuna con tableorter, ma non è così facile, non altrettanto ben documentato e ha solo funzioni ok.
Abbiamo appena iniziato a utilizzare questo strumento slick: https://plugins.jquery.com/tablesorter/
C'è un video sul suo uso su: http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
Con un tavolo semplice
<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>
La mia risposta sarebbe "state attenti". Molti componenti aggiuntivi di ordinamento di tabelle jQuery ordinano solo ciò che si passa al browser. In molti casi, è necessario tenere presente che le tabelle sono insiemi di dati dinamici e potrebbero contenere potenzialmente miliardi di righe di dati.
Dici che hai solo 4 colonne, ma soprattutto, non menzioni di quante righe stiamo parlando qui.
Se si passano 5000 righe al browser dal database, sapendo che la tabella di database effettiva contiene 100.000 righe, la mia domanda è: qual è il punto nel rendere ordinabile la tabella? Per fare un corretto ordinamento, dovresti rispedire la query al database e lasciare che il database (uno strumento effettivamente progettato per ordinare i dati) faccia l'ordinamento per te.
In risposta diretta alla tua domanda, il miglior componente aggiuntivo per l'ordinamento che ho incontrato è Ingrid. Ci sono molti motivi per cui non mi piace questo componente aggiuntivo ("campane e fischietti inutili ..." come lo chiami tu), ma una delle sue migliori caratteristiche in termini di ordinamento, è che usa ajax e non supponiamo che tu abbia già passato tutti i dati prima che faccia il suo ordinamento.
Riconosco che questa risposta è probabilmente eccessiva (e oltre 2 anni di ritardo) per le tue esigenze, ma mi annoio quando gli sviluppatori nel mio campo trascurano questo punto. Quindi spero che qualcun altro lo raccolga.
Mi sento meglio ora.
Questo è un bel modo di ordinare una tabella:
$(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>
Il violino può essere trovato qui:
https://jsfiddle.net/e3s84Luw/
La spiegazione è disponibile qui: https://www.learningjquery.com/2017/03/how-to-sort-html-table-using-jquery-code
Adoro questa risposta accettata, tuttavia, raramente hai requisiti per ordinare HTML e non devi aggiungere icone che indicano la direzione di ordinamento. Ho preso l'esempio di utilizzo della risposta di accettazione e l'ho risolto rapidamente aggiungendo semplicemente bootstrap al mio progetto e aggiungendo il seguente codice:
<div></div>
all'interno di ciascuno in <th>
modo da avere un posto per impostare l'icona.
setIcon(this, inverse);
dall'uso della risposta accettata, sotto la riga:
th.click(function () {
e aggiungendo il metodo 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();
}
Ecco una demo . - Devi eseguire la demo in Firefox o IE o disabilitare il controllo del tipo MIME di Chrome affinché la demo funzioni. Dipende dal plug-in sortElements, collegato dalla risposta accettata, come risorsa esterna. Solo un avviso!
Ecco un grafico che può essere utile per decidere quale utilizzare: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/
La risposta di @Nick Grealy è ottima, ma non tiene conto dei possibili rowspan
attributi delle celle dell'intestazione della tabella (e probabilmente anche le altre risposte non lo fanno). Ecco un miglioramento della risposta di @Nick Grealy che lo risolve. Anche sulla base di questa risposta (grazie @Andrew Orlov).
Ho anche sostituito la $.isNumeric
funzione con una personalizzata (grazie a @zad) per farlo funzionare con le versioni precedenti di jQuery.
Per attivarlo, aggiungi class="sortable"
al <table>
tag.
$(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;
};
È possibile utilizzare un plug-in jQuery ( breedjs ) che fornisce ordinamento, filtro e impaginazione:
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')
});
});
});
Questo non blocca il / i browser / i, facilmente configurabile ulteriormente:
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()
}
Alla risposta di James, cambierò la funzione di ordinamento solo per renderla più universale. In questo modo ordinerà il testo in ordine alfabetico e numeri come numeri.
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;
}
Un altro approccio per ordinare la tabella HTML. (basato sull'ordinamento 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>
Ho finito per usare la risposta di Nick (la più popolare ma non accettata) https://stackoverflow.com/a/19947532/5271220
e combinato con https://stackoverflow.com/a/16819442/5271220 ma non volevo aggiungere icone o fontawesome al progetto. Gli stili CSS per sort-column-asc / desc ho fatto colore, riempimento, bordo arrotondato.
L'ho anche modificato per andare in classe anziché in qualsiasi modo in modo da poter controllare quali sono ordinabili. Questo potrebbe tornare utile in seguito se ci sono due tabelle, anche se è necessario apportare ulteriori modifiche.
corpo:
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"; ...
... più in basso nel corpo
$("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);
});
funzioni:
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 = "";
});
}
Il mio voto! jquery.sortElements.js e jquery semplice
Molto semplice, molto facile, grazie 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
Un merluzzo migliore!
Funzione per tutte le tabelle in tutti i Th di tutti i tempi ... Guardalo!
DEMO
.live()
.