Tengo una tabla HTML muy simple con 4 columnas:
Facility Name, Phone #, City, Specialty
Quiero que el usuario pueda ordenar por nombre de instalación y ciudad solamente.
¿Cómo puedo codificar esto usando jQuery?
Tengo una tabla HTML muy simple con 4 columnas:
Facility Name, Phone #, City, Specialty
Quiero que el usuario pueda ordenar por nombre de instalación y ciudad solamente.
¿Cómo puedo codificar esto usando jQuery?
Respuestas:
Si desea evitar todas las campanas y silbatos, entonces puedo sugerir este simple sortElements
complemento . 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;
});
});
Y una demo. (haga clic en los encabezados de columna "ciudad" y "instalación" para ordenar)
Error: illegal character
el html no es exactamente el mismo, también tengo thead y tboy, ¿me pueden ayudar con esto por favor?
$.text([a]) == $.text([b])
usar $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
lo arreglará.
Encontré esto, y pensé en tirar mis 2 centavos. Haga clic en los encabezados de columna para ordenar de forma ascendente, y nuevamente para ordenar de manera descendente.
$('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, por ejemplo, <a href="#">Test</a>
la clasificación se refiere a <a...
. Para ordenar por texto solo necesita cambiar html()
en la última línea a text()
.
comparer(..)
si supiera exactamente qué formato desea admitir). Mientras tanto, si usa yyyy-MM-dd
" string
", la ordenación ordenará los datos por usted. por ejemplo jsbin.com/pugedip/1
De lejos, el más fácil que he usado es: http://datatables.net/
Increíblemente simple ... solo asegúrese de ir a la ruta de reemplazo DOM (es decir, construir una tabla y dejar que DataTables la vuelva a formatear), luego asegúrese de formatear su tabla con <thead>
y<tbody>
o no va a funcionar. Esa es la única trampa.
También hay soporte para AJAX, etc. Como con todas las piezas de código realmente buenas, también es MUY fácil desactivarlo todo. Sin embargo, te sorprendería lo que podrías usar. Comencé con un DataTable "desnudo" que solo clasificó un campo y luego me di cuenta de que algunas de las características eran realmente relevantes para lo que estoy haciendo. Los clientes aman las nuevas características.
Puntos de bonificación a DataTables para soporte completo de ThemeRoller ...
También he tenido buena suerte con el clasificador de tablas, pero no es tan fácil, no está tan bien documentado y solo tiene características correctas.
Recién comenzamos a usar esta herramienta ingeniosa: https://plugins.jquery.com/tablesorter/
Hay un video sobre su uso en: http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
Con una mesa simple
<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>
Mi respuesta sería "ten cuidado". Muchos complementos de ordenación de tablas jQuery solo clasifican lo que pasa al navegador. En muchos casos, debe tener en cuenta que las tablas son conjuntos de datos dinámicos y que podrían contener miles de millones de líneas de datos.
Usted menciona que solo tiene 4 columnas, pero mucho más importante, no menciona cuántas filas estamos hablando aquí.
Si pasa 5000 líneas al navegador desde la base de datos, sabiendo que la tabla de base de datos real contiene 100,000 filas, mi pregunta es: ¿cuál es el punto de hacer que la tabla sea ordenable? Para hacer una ordenación adecuada, debe enviar la consulta de vuelta a la base de datos y dejar que la base de datos (una herramienta realmente diseñada para ordenar datos) haga la clasificación por usted.
Sin embargo, en respuesta directa a su pregunta, el mejor complemento de clasificación que he encontrado es Ingrid. Hay muchas razones por las que no me gusta este complemento ("campanas y silbidos innecesarios ..." como lo llamas), pero una de sus mejores características en términos de género es que usa ajax y no No asuma que ya le pasó todos los datos antes de que haga su clasificación.
Reconozco que esta respuesta es probablemente exagerada (y con más de 2 años de retraso) para sus requisitos, pero me molesta cuando los desarrolladores en mi campo pasan por alto este punto. Así que espero que alguien más se dé cuenta.
Me siento mejor ahora.
Esta es una buena manera de ordenar una tabla:
$(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>
El violín se puede encontrar aquí:
https://jsfiddle.net/e3s84Luw/
La explicación se puede encontrar aquí: https://www.learningjquery.com/2017/03/how-to-sort-html-table-using-jquery-code
Me encanta esta respuesta aceptada, sin embargo, rara vez tienes requisitos para ordenar html y no tienes que agregar iconos que indiquen la dirección de clasificación. Tomé el ejemplo de uso de la respuesta de aceptación y lo arreglé rápidamente simplemente agregando bootstrap a mi proyecto y agregando el siguiente código:
<div></div>
dentro de cada uno <th>
para que tenga un lugar para configurar el icono.
setIcon(this, inverse);
del Uso de la respuesta aceptada, debajo de la línea:
th.click(function () {
y agregando el método 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();
}
Aquí hay una demostración . - Necesita ejecutar la demostración en Firefox o IE, o deshabilitar la comprobación de tipo MIME de Chrome para que la demostración funcione. Depende del complemento sortElements, vinculado por la respuesta aceptada, como un recurso externo. Sólo un aviso!
Aquí hay un cuadro que puede ser útil para decidir cuál usar: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/
La respuesta de @Nick Grealy es excelente, pero no tiene en cuenta los posibles rowspan
atributos de las celdas del encabezado de la tabla (y probablemente las otras respuestas tampoco lo hacen). Aquí hay una mejora de la respuesta de @Nick Grealy que corrige eso. Basado en esta respuesta también (gracias @Andrew Orlov).
También he reemplazado la $.isNumeric
función por una personalizada (gracias @zad) para que funcione con versiones anteriores de jQuery.
Para activarlo, agréguelo class="sortable"
a la <table>
etiqueta.
$(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;
};
Puede usar un complemento jQuery ( breedjs ) que proporciona clasificación, filtro y paginación:
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')
});
});
});
Este no cuelga el / los navegador / s, más fácil de configurar:
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()
}
A la respuesta de James, solo cambiaré la función de clasificación para hacerlo más universal. De esta manera, ordenará el texto alfabéticamente y los números como números.
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;
}
Otro enfoque para ordenar la tabla HTML. (basado en W3.JS HTML Sort )
/* 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>
Terminé usando la respuesta de Nick (la más popular pero no aceptada) https://stackoverflow.com/a/19947532/5271220
y lo combiné con https://stackoverflow.com/a/16819442/5271220 pero no quise agregar iconos o fontawesome al proyecto. Los estilos CSS para sort-column-asc / desc hice color, relleno, borde redondeado.
También lo modifiqué para ir por clase en lugar de por cualquiera para poder controlar cuáles se pueden ordenar. Esto también podría ser útil más adelante si hay dos tablas, aunque sería necesario realizar más modificaciones para eso.
cuerpo:
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"; ...
... más abajo en el cuerpo
$("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);
});
funciones:
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 = "";
});
}
¡Mi voto! jquery.sortElements.js y jquery simple
Muy simple, muy fácil, gracias 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
One cod mejor!
Función para todas las tablas en todo Th en todos los tiempos ... ¡Míralo!
MANIFESTACIÓN
.live()
.