tri de la table de jQuery

j'ai un tableau HTML très simple avec 4 colonnes:

Facility Name, Phone #, City, Specialty

je veux que l'utilisateur puisse Trier par nom D'installation, et ville seulement.

Comment puis-je coder ceci en utilisant jQuery?

148
demandé sur Brian Tompsett - 汤莱恩 2010-07-01 21:39:43

13 réponses

si vous voulez éviter toutes les cloches et sifflets alors 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 colonnes" ville "et" installation "pour les trier)

135
répondu James 2016-03-10 15:55:19

je suis tombé sur ceci, et j'ai pensé que je pourrais jeter dans mes 2 cents. Cliquez sur les en-têtes de colonne pour trier l'Ascension, et de nouveau pour trier la descente.

  • Fonctionne dans Chrome, Firefox, Opera ET IE(8)
  • n'utilise que JQuery
  • fait le tri alphabétique et numérique - ascendant et descendant

$('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>

* * mise à jour: 2018

137
répondu Nick Grealy 2018-03-01 02:42:36

de loin, le plus facile que j'ai utilisé est: http://datatables.net /

étonnamment simple...assurez-vous juste que si vous allez à la voie de remplacement de DOM (c.-à-d., la construction d'une table et laisser les données reformater) alors assurez-vous de formater votre table avec <thead> et <tbody> ou il ne fonctionnera pas. C'est la seule chose à corriger.

Il ya aussi un soutien pour AJAX, etc. Comme avec tous les très bons morceaux de code, il est aussi très facile à tourner. Vous seriez surpris de ce que vous pourriez utiliser. J'ai commencé avec un "nu" DataTable 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 aux DataTables pour un support ThemeRoller complet....

j'ai aussi eu de la chance avec tablesorter, mais ce n'est pas aussi facile, pas aussi bien documenté, et n'a que des fonctionnalités ok.

36
répondu bpeterson76 2011-11-27 02:56:47

nous venons de commencer à utiliser cet outil pratique: http://tablesorter.com/docs /

Il y a une vidéo sur son utilisation à: 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>&nbsp;</th>
                  </tr>
        </thead>
15
répondu Ravi Ram 2012-03-02 15:11:30

ma réponse serait"attention". Un grand nombre de jQuery table-tri add-ons trier seulement ce que vous passez au navigateur. Dans de nombreux cas, vous devez garder à l'esprit que les tableaux sont des ensembles dynamiques de données, et pourraient contenir des milliards de lignes de données.

vous mentionnez que vous avez seulement 4 colonnes, mais beaucoup plus important, vous ne mentionnez pas combien de lignes nous parlons ici.

si vous passez 5000 lignes au navigateur à partir du base de données, sachant que la base de données-table contient 100 000 lignes, ma question est: à quoi bon rendre la table sortable? Pour effectuer un tri adéquat, vous devez renvoyer la requête à la base de données, et laisser la base de données (un outil conçu pour trier les données) faire le tri pour vous.

en réponse à votre question, le meilleur tri que j'ai rencontré est Ingrid. Il ya beaucoup de raisons pour lesquelles je n'aime pas cet add-on ("cloches inutiles et de sifflets..."comme vous l'appelez), mais l'une de ses meilleures caractéristiques en termes de tri, c'est qu'il utilise ajax, et de ne pas supposer que vous avez déjà dépassé toutes les données avant qu'il ne la sorte.

je reconnais que cette réponse est probablement exagérée (et avec plus de 2 ans de retard) pour vos besoins, mais je me fâche quand les développeurs dans mon domaine négligent ce point. Donc j'espère que quelqu'un le ramasse sur elle.

je me sens mieux maintenant.

12
répondu cartbeforehorse 2012-10-24 21:26:56

voici un tableau qui pourrait être utile pour décider lequel utiliser: http://blog.sematext.com/2011/09/19/top-javascript-dynamic-table-libraries/

4
répondu SeanDowney 2011-10-07 17:48:45

j'adore cette réponse acceptée, cependant, vous obtenez rarement des exigences pour trier html et ne pas avoir à ajouter des icônes indiquant la direction de tri. J'ai pris l'exemple d'utilisation de accept answer et je l'ai corrigé rapidement en ajoutant bootstrap à mon projet, et en ajoutant le code suivant:

<div></div>

à l'intérieur de chaque <th> , de sorte que vous avez un endroit pour mettre l'icône.

setIcon(this, inverse);

d'après L'Usage de la réponse acceptée, au-dessous de 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 lancer la démo dans Firefox ou IE, ou désactiver la vérification du type MIME de Chrome pour que la démo fonctionne. Il dépend du Plugin sortElements, lié par la réponse acceptée, comme ressource externe. Juste un heads-up!

4
répondu 2013-05-29 20:29:30

vous pouvez utiliser un plugin jQuery ( breedjs ) 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')
    });
  });
});

exemple de travail sur violon

2
répondu João Paulo 2016-04-11 20:54:58

à la réponse de Jacques Je ne changerai la fonction de tri que pour la rendre plus universelle. De cette façon, il classera le texte par ordre alphabétique et les 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;
}
1
répondu Kaloyan Iliev 2013-07-23 08:49:06

@Nick Grealy la réponse est excellente, mais elle ne tient pas compte des attributs possibles rowspan des cellules d'en-tête de 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 aussi remplacé la fonction $.isNumeric par une custom one (merci @zad) pour le faire fonctionner avec des versions plus anciennes de jQuery.

pour l'activer, ajouter class="sortable" à l'étiquette <table> .

$(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;
};
1
répondu Dennis Golomazov 2017-05-23 11:47:15

une autre approche pour trier la table HTML. (basé sur 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>
0
répondu Yi-Ting Liu 2018-08-02 15:16:51

c'est une bonne façon de trier une table:

$(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

0
répondu Julian 2018-09-05 07:13:05

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 mieux! fonction pour toutes les tables en tout temps... L'air!

Démo

-2
répondu Filipe Rudá 2012-08-29 14:03:14