J'ai un tableau HTML très simple avec 4 colonnes:
Facility Name, Phone #, City, Specialty
Je veux que l'utilisateur puisse trier uniquement par nom d'établissement et par ville .
Comment puis-je coder cela en utilisant jQuery?
J'ai un tableau HTML très simple avec 4 colonnes:
Facility Name, Phone #, City, Specialty
Je veux que l'utilisateur puisse trier uniquement par nom d'établissement et par ville .
Comment puis-je coder cela en utilisant jQuery?
Réponses:
Si vous voulez éviter toutes les cloches et les sifflets, puis-je suggérer ce simple sortElements
plugin . Usage:
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;
});
});
Et une démo. (cliquez sur les en-têtes de colonne "ville" et "établissement" pour trier)
Error: illegal character
J'obtiens cette erreur le html n'est pas exactement le même, j'ai aussi thead et tboy, pouvez-vous m'aider avec ça s'il vous plaît?
$.text([a]) == $.text([b])
utiliser $.text([a]).toUpperCase() == $.text([b]).toUpperCase()
va le réparer.
Je suis tombé sur ça, et j'ai pensé que je mettrais mes 2 cents. Cliquez sur les en-têtes de colonne pour trier par ordre croissant, et encore une fois pour trier par ordre décroissant.
$('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, par exemple, <a href="#">Test</a>
le tri concerne le <a...
. Pour trier uniquement par texte, vous devez remplacer html()
la dernière ligne par text()
.
comparer(..)
si vous saviez exactement quel format vous souhaitez prendre en charge). En attendant, si vous utilisez yyyy-MM-dd
, " string
" le tri ordonnera les données pour vous. par exemple jsbin.com/pugedip/1
De loin, le plus simple que j'ai utilisé est: http://datatables.net/
Étonnamment simple ... assurez-vous simplement que si vous utilisez la voie de remplacement DOM (IE, créer une table et laisser DataTables le reformater), assurez-vous de formater votre table avec <thead>
et <tbody>
ou cela ne fonctionnera pas. C'est à peu près le seul piège.
Il y a aussi un support pour AJAX, etc. Comme pour tous les très bons morceaux de code, il est aussi TRÈS facile de tout désactiver. Vous seriez surpris de ce que vous pourriez utiliser, cependant. J'ai commencé avec un DataTable "nu" qui n'a trié qu'un seul champ, puis j'ai réalisé que certaines des fonctionnalités étaient vraiment pertinentes pour ce que je fais. Les clients ADORENT les nouvelles fonctionnalités.
Points bonus vers DataTables pour une prise en charge complète de ThemeRoller ....
J'ai également eu de la chance avec le trieur de tables, mais ce n'est pas aussi facile, pas aussi bien documenté et n'a que des fonctionnalités correctes.
Nous venons de commencer à utiliser cet outil astucieux: https://plugins.jquery.com/tablesorter/
Une vidéo sur son utilisation est disponible sur: http://www.highoncoding.com/Articles/695_Sorting_GridView_Using_JQuery_TableSorter_Plug_in.aspx
$('#tableRoster').tablesorter({
headers: {
0: { sorter: false },
4: { sorter: false }
}
});
Avec une table 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>
Ma réponse serait "soyez prudent". De nombreux modules complémentaires de tri de table jQuery trient uniquement ce que vous transmettez au navigateur. Dans de nombreux cas, vous devez garder à l'esprit que les tables sont des ensembles dynamiques de données et peuvent potentiellement contenir des millions de lignes de données.
Vous mentionnez que vous n'avez que 4 colonnes, mais plus important encore, vous ne mentionnez pas le nombre de lignes dont nous parlons ici.
Si vous passez 5000 lignes au navigateur à partir de la base de données, sachant que la table de base de données réelle contient 100000 lignes, ma question est: quel est l'intérêt de rendre la table triable? Afin de faire un tri approprié, vous devez renvoyer la requête à la base de données et laisser la base de données (un outil réellement conçu pour trier les données) faire le tri pour vous.
En réponse directe à votre question, le meilleur module complémentaire de tri que j'ai rencontré est Ingrid. Il y a de nombreuses raisons pour lesquelles je n'aime pas cet add-on ("cloches et sifflets inutiles ..." comme vous l'appelez), mais l'une de ses meilleures fonctionnalités en termes de tri, c'est qu'il utilise ajax, et ne le fait pas. t supposez que vous lui avez déjà transmis toutes les données avant de faire son tri.
Je reconnais que cette réponse est probablement exagérée (et avec plus de 2 ans de retard) pour vos besoins, mais je suis ennuyé lorsque les développeurs de mon domaine négligent ce point. J'espère donc que quelqu'un d'autre le comprendra.
Je me sens mieux maintenant.
C'est une belle façon de trier un tableau:
$(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>
Le violon peut être trouvé ici:
https://jsfiddle.net/e3s84Luw/
L'explication peut être trouvée ici: https://www.learningjquery.com/2017/03/how-to-sort-html-table-using-jquery-code
J'adore cette réponse acceptée, cependant, vous avez rarement besoin de trier html et de ne pas avoir à ajouter d'icônes indiquant le sens de tri. J'ai pris l'exemple d'utilisation de la réponse d'acceptation et j'ai résolu cela rapidement en ajoutant simplement bootstrap à mon projet et en ajoutant le code suivant:
<div></div>
à l'intérieur de chacun <th>
afin que vous ayez une place pour définir l'icône.
setIcon(this, inverse);
à partir de l'utilisation de la réponse acceptée, sous la ligne:
th.click(function () {
et en ajoutant la méthode 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();
}
Voici une démo . - Vous devez soit exécuter la démo dans Firefox ou IE, soit désactiver la vérification de type MIME de Chrome pour que la démo fonctionne. Cela dépend du plugin sortElements, lié par la réponse acceptée, en tant que ressource externe. Juste un avertissement!
Voici un graphique qui peut être utile pour décider lequel utiliser: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/
La réponse de @Nick Grealy est excellente, mais elle ne prend pas en compte les rowspan
attributs possibles des cellules d'en-tête du tableau (et probablement les autres réponses ne le font pas non plus). Voici une amélioration de la réponse de @Nick Grealy qui corrige cela. Basé sur cette réponse aussi (merci @Andrew Orlov).
J'ai également remplacé la $.isNumeric
fonction par une fonction personnalisée (merci @zad) pour la faire fonctionner avec les anciennes versions de jQuery.
Pour l'activer, ajoutez class="sortable"
à la <table>
balise.
$(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;
};
Vous pouvez utiliser un plugin jQuery ( racejs ) qui fournit le tri, le filtre et la pagination:
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')
});
});
});
Celui-ci ne raccroche pas le / les navigateur / s, facilement configurable plus loin:
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()
}
À la réponse de James, je ne changerai que la fonction de tri pour la rendre plus universelle. De cette façon, il triera le texte par ordre alphabétique et des nombres comme des nombres.
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;
}
Une autre approche pour trier le tableau HTML. (basé sur le tri 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>
J'ai fini par utiliser la réponse de Nick (la plus populaire mais non acceptée) https://stackoverflow.com/a/19947532/5271220
et l'a combiné avec https://stackoverflow.com/a/16819442/5271220 mais ne voulait pas ajouter d'icônes ou de fontawesome au projet. Les styles CSS pour sort-column-asc / desc J'ai fait la couleur, le remplissage, la bordure arrondie.
Je l'ai également modifié pour passer par classe plutôt que par aucune afin que nous puissions contrôler celles qui sont triables. Cela pourrait également être utile plus tard s'il y a deux tables, bien que d'autres modifications soient nécessaires pour cela.
corps:
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"; ...
... plus bas dans le corps
$("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);
});
les fonctions:
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 = "";
});
}
Mon vote! jquery.sortElements.js et jquery simple
Très simple, très facile, merci 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
Une morue de mieux!
Fonction pour toutes les tables dans tous Th dans tous les temps ... Regardez-le!
DEMO
.live()
.