Trucsweb.com

Javascript

Sans jQuery

RDFFav

Tableau HTML - Tri dynamique de « dataGrid » sans jQuery

Trier ascendant et descendant des colonnes d’un tableau de données (dataGrid) HTML sans jQueryArray, querySelector, forEach, getElementsByTagName, nth-child, datagrid

Quel plaisir que de travailler avec un langage script, particulièrement le JavaScript. On combine des objets et des méthodes sophistiqués avec de simples chaines de caractère comme un poisson dans l’eau! Tout est dans le guillemet. Il faudrait, après le copier-coller, donner un prix Nobel à celui qui a instauré les guillemets informatiques, et les entités HTML tant qu’à faire! D’ailleurs, Tim Berners-Lee n’a toujours pas son prix Nobel, une honte ;-)

Caractères accentués payés cher

Cet exemple utilise la méthode « localeCompare ». C’est la seule façon native d’espérer régler le problème des caractères accentués. C’est-à-dire d’une part à la merci de l’usager et de l’autre, une pression et un temps d’exécution supplémentaire déjà long en JavaScript. De l’ordre de 5x avec IE11 et Chrome. Déjà 20x avec mon Firefox 36 et jusqu’à 200x sur Android! C’est encore pire avec Safari 5. Dire que la vitesse d’un tri a historiquement été une préoccupation. On peut se consoler sachant que les nouveaux navigateurs sons beaucoup plus performants avec le « localeCompare ».

Voilà donc un tri des colonnes d’un tableau dynamique sans jQuery. « Un petit bout de code qui fait beaucoup », avec moult techniques tant modernes que classiques. Un très bon exemple, syntaxe des plus concises qui n’a rien à envier au jQuery. C’est déjà la moitié du slogan de jQuery « write less, do more » ça. Aucun code, il suffit d’ajouter une classe « avectri » à vos tableaux, le script les détecte et fait le travail, comme si Google était chez vous! Tout est entièrement automatisé et dynamique. Génération des flèches, ajout des événements, et ce pour un nombre "illimité" de tableaux dans une même page HTML.

Pour six bonnes raisons :

  1. Premièrement, parce qu’il est temps de se passer de jQuery ...quand c’est possible.
  2. Parce que la plupart des solutions complètes et exemple en ligne utilisent aussi la librairie jQuery.
  3. Parce que les nouveaux sélecteurs CSS3 sont vraiment plus efficaces, d’ailleurs supporté par jQuery.

NOTE : Le tableau doit être équilibré, sans colspan ni rowspan pour fonctionner.

CSS et HTML minimum

Rien de compliqué, en CSS deux classes pour les flèches et une table HTML avec la classe « averti ». Notez qu’il faut spécifier les colonnes numériques dans l’entête, pour le tri. Avec l’attribut « data-type.

<style>
/* Classe obligatoire pour les flèches */
.flecheDesc {...}
.flecheAsc {...}
</style>

<table class="avectri">
  <thead>
    <tr>
      <th>Entête 1</th>
      <th>Entête 2</th>
      <th class="selection" data-tri="1" data-type="num">Entête 3</th>
    </tr>
  </thead>
  <tbody>
   
  </tbody>
</table>

C’est tout! Avec les entêtes et un <tbody> pour contenir les lignes et colonnes du tableau, sans plus. Optionnel puisque le navigateur ajoute toujours automatiquement le <tbody> s’il est omis. La classe « selection » permet de forcer un tri par défaut. data-type="num" pour un tri numérique et data-tri="1" pour un tri ascendant par défaut.

JavaScript

On commence par initialiser le tableau. C’est-à-dire boucler [].forEach tous les tableaux de la classe « avectri » getElementsByClassName("avectri") du document tout en bouclant chaque entête de chaque tableau querySelectorAll("th").

// Boucler les tableaux de classe « avectri ».
[].forEach.call( document.getElementsByClassName("avectri")...

// On récupère la première ligne du tableau, surment le <thead>.
// pour boucleer les entêtes du <thead>, c’est à dire les <th>.
var oEntete = oTableau.getElementsByTagName("tr")[0];
[].forEach.call( oEntete.querySelectorAll("th")...

Tout ça pour ajouter à chaque entête la flèche innerHTML, les attributs setAttribute et l’événement addEventListener:

oTh.innerHTML += "<span class=\"flecheAsc\"></span>";
oTh.setAttribute("data-tri", "1");
oTh.setAttribute("data-pos", nI);
oTh.addEventListener("click", twTriTableau, false);
// Test pour forcer le tri par défaut
if (oTh.className=="selection") {
  oTh.click();
}
nI++;

La flèche est en fait une classe CSS dans un <span>. L’attribut data-tri servira de valeur booléenne pour identifier la direction du tri. Quant à l’attribut data-pos, c’est un index, pour palier à une lacune en pure JavaScript. En effet aucun Index n’est disponible pour les items ou les nœuds du « NodeList »! Voilà une bonne façon de palier au problème, c’est dynamique any way! Quant à l’événement, il permet de capturer le clic sur l’entête qui appellera la fonction « twTriTableau ».

La fonction appelé après un clic sur un entête.

Cette fonction ne fait pas que trier la colonne. Elle commence par supprimer la classe « selection » des entêtes. Pour ensuite l’ajouter à la nouvelle entête sélectionnée. Puis elle récupère getAttribute la position de l’index « data-pos » de la colonne sélectionnée ainsi que la valeur booléenne « data-tri » qui indique la direction du tri courant. Pour évaluer la nouvelle direction et sauvegarder la nouvelle valeur dans l’attribut setAttribute.

  // Boucle chaque entête pour suppromer la classe
  [].forEach.call( this.parentNode.querySelectorAll("th"), function(oTh) {oTh.classList.remove("selection");});
  // Ajoute la classe pour l’entête sélectionné.
  this.className = "selection";

  // Des colonne numérique, Récupération de la position de l’index et de la direction
  var sFonctionTri = (this.getAttribute("data-type")=="num") ? "compareNombres" : "compareLocale";
  var nIndex = this.getAttribute("data-pos");
  var nBoolDir = this.getAttribute("data-tri");
  // Évaluation et assignation de la nouvelle direction
  this.setAttribute("data-tri", (nBoolDir=="0") ? "1" : "0");

Contrairement au jQuery, il n’y a pas de « switch » natif en JavaScript. J’ai dû faire plus d’une solution pour ajuster la flèche parce que j’avais l’ambition d’utiliser les nouvelles méthodes. Par exemple :

// Mauvais
if (this.getAttribute("data-tri")==0) {
  this.querySelector("span").classList.remove("flecheAsc");
  this.querySelector("span").classList.add("flecheDesc");
} else {
  this.querySelector("span").classList.remove("flecheDesc");
  this.querySelector("span").classList.add("flecheAsc");
}

Pour réaliser que la bon viel attribut « className » était encore mieux, étant donnée qu’il n’y a qu’une seule classe.

// Mieux
if (this.getAttribute("data-tri")==0) {
  this.querySelector("span").className = "flecheAsc");
} else {
  this.querySelector("span").className = "flecheDesc");
}

// Encore mieux, dans sa plus simple expression :
this.querySelector("span").className = (nBoolDir=="0") ? "flecheAsc" : "flecheDesc");
Et enfin le tri

L’idée est toute simple, récupérer les données du <tbody> du tableau sélectionné pour les intégrer dans une matrice « aColonne ».

// Construit la matrice
// Récupère le tableau (tbody)
var oTbody = this.parentNode.parentNode.parentNode.getElementsByTagName("tbody")[0]; 
var oLigne = oTbody.rows;
var nNbrLigne = oLigne.length;
var aColonne = new Array(), i, j, oCel;
for(i = 0; i < nNbrLigne; i++) {
  oCel = oLigne[i].cells;
  aColonne[i] = new Array();
  for(j = 0; j < oCel.length; j++){
    aColonne[i][j] = oCel[j].innerHTML;
  }
}

On se retrouve avec une matrice « aColonne » qu’il suffit de trier selon la colonne sélectionnée (nIndex de l’attribut « data-pos »), les colonne numérique avec la fonction numérique, sinon, c’est localCompare pour prendre en charge les caractères accentués :

// Récupère le numéro de la colonne
var nIndex = this.getAttribute("data-pos");

// Récupère le type de tri (numérique ou par défaut « local »)
var sFonctionTri = (this.getAttribute("data-type")=="num") ? "compareNombres" : "compareLocale";

// Tri
aColonne.sort(eval(sFonctionTri));

// Tri numérique
function compareNombres(a, b) {return a[nIndex-1] - b[nIndex-1];}

// Tri local (pour support utf-8)
function compareLocale(a, b) {return a[nIndex-1].localeCompare(b[nIndex-1]);}

// Renverse la matrice dans le cas d’un tri descendant
if (nBoolDir==0) aColonne.reverse();

Le dernière ligne permet d’inverser l’ordre de la matrice dans le cas d’un tri est descendant « nBoolDir = 0 »

Selon vjeux, le tri JavaScript peut être optimisé, jusqu’à 5 fois plus performant en forçant le navigateur à ignorer la conversion toString. En réalité mes chiffres sont plus sobre et any way localeCompare fait sauter la pile à lui seul! Enfin voilà l’exemple :

// Tri de la matrice
// Plus rapide en bloquant la conversion toString
var save = Object.prototype.toString;
Object.prototype.toString = function () { return String.fromCharCode(this.key); };
aColonne.sort(eval(sFonctionTri));
Object.prototype.toString = save;
function compareNombres(a, b) {return a[nIndex-1] - b[nIndex-1];}
function compareLocale(a, b) {return a[nIndex-1].localeCompare(b[nIndex-1])}

Et finalement on boucle la matrice pour réintégrer les valeurs dans le tableau HTML.

// Construit les colonne du nouveau tableau
for(i = 0; i < nNbrLigne; i++){
  aColonne[i] = "<td>"+aColonne[i].join("</td><td>")+"</td>";
}

// assigne les lignes au tableau
oTbody.innerHTML = "<tr>"+aColonne.join("</tr><tr>")+"</tr>";
Code complet stylisé
Tableau HTML
<table class="avectri">
  <thead>
    <tr>
      <th>Entête 1</th>
      <th>Entête 2</th>
      <th  data-tri="1" class="selection" data-type="num">Entête 3</th>
    </tr>
  </thead>
  <tbody>
    <tr><td>...</td><td>...</td><td>...</td></tr>
    ...
  </tbody>
</table>
CSS du tableau
<style>
/* Classe obligatoire pour les flèches */
.flecheDesc {
  width: 0; 
  height: 0; 
  float:right;
  margin: 10px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid black;
}
.flecheAsc {
  width: 0; 
  height: 0;
  float:right;
  margin: 10px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid black;
}

/* Classe optionnelle pour le style */
.tableau {width:100%;table-layout: fixed;border-collapse: collapse;}
.tableau td {padding:.3rem}
.zebre tbody tr:nth-child(odd) {background-color: #d6d3ce;border-bottom:1px solid #ccc;color:#444;}
.zebre tbody tr:nth-child(even) {background-color: #c6c3bd;border-bottom:1px solid #ccc;color:#444;}
.zebre tbody tr:hover:nth-child(odd) {background-color: #999690;color:#ffffff;}
.zebre tbody tr:hover:nth-child(even) {background-color: #999690;color:#ffffff;}
.avectri th {text-align:center;padding:5px 0 0 5px;vertical-align: middle;background-color:#999690;color:#444;cursor:pointer;
	-webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}
.avectri th.selection {background-color:#5d625c;color:#fff;}
.avectri th.selection .flecheDesc {border-bottom-color: white;}
.avectri th.selection .flecheAsc {border-top-color: white;}
.zebre tbody td:nth-child(3) {text-align:center;}
</style>
Javascript
<script>
  // Tri dynamique de tableau HTML
  // Auteur : Copyright © 2015 - Django Blais
  // Source : http://trucsweb.com/tutoriels/Javascript/tableau-tri/
  // Sous licence du MIT.
  function twInitTableau() {
    // Initialise chaque tableau de classe « avectri »
       [].forEach.call( document.getElementsByClassName("avectri"), function(oTableau) {
       var oEntete = oTableau.getElementsByTagName("tr")[0];
       var nI = 1;
  	  // Ajoute à chaque entête (th) la capture du clic
  	  // Un picto flèche, et deux variable data-*
  	  // - Le sens du tri (0 ou 1)
  	  // - Le numéro de la colonne
      [].forEach.call( oEntete.querySelectorAll("th"), function(oTh) {
        oTh.addEventListener("click", twTriTableau, false);
        oTh.setAttribute("data-pos", nI);
        if(oTh.getAttribute("data-tri")=="1") {
         oTh.innerHTML += "<span class=\"flecheDesc\"></span>";
        } else {
          oTh.setAttribute("data-tri", "0");
          oTh.innerHTML += "<span class=\"flecheAsc\"></span>";
        }
        // Tri par défaut
        if (oTh.className=="selection") {
          oTh.click();
        }
        nI++;
      });
    });
  }
  
  function twInit() {
    twInitTableau();
  }
  function twPret(maFonction) {
    if (document.readyState != "loading"){
      maFonction();
    } else {
      document.addEventListener("DOMContentLoaded", maFonction);
    }
  }
  twPret(twInit);

  function twTriTableau() {
    // Ajuste le tri
    var nBoolDir = this.getAttribute("data-tri");
    this.setAttribute("data-tri", (nBoolDir=="0") ? "1" : "0");
    // Supprime la classe « selection » de chaque colonne.
    [].forEach.call( this.parentNode.querySelectorAll("th"), function(oTh) {oTh.classList.remove("selection");});
    // Ajoute la classe « selection » à la colonne cliquée.
    this.className = "selection";
    // Ajuste la flèche
    this.querySelector("span").className = (nBoolDir=="0") ? "flecheAsc" : "flecheDesc";

    // Construit la matrice
    // Récupère le tableau (tbody)
    var oTbody = this.parentNode.parentNode.parentNode.getElementsByTagName("tbody")[0]; 
    var oLigne = oTbody.rows;
    var nNbrLigne = oLigne.length;
    var aColonne = new Array(), i, j, oCel;
    for(i = 0; i < nNbrLigne; i++) {
      oCel = oLigne[i].cells;
      aColonne[i] = new Array();
      for(j = 0; j < oCel.length; j++){
        aColonne[i][j] = oCel[j].innerHTML;
      }
    }

    // Trier la matrice (array)
    // Récupère le numéro de la colonne
    var nIndex = this.getAttribute("data-pos");
    // Récupère le type de tri (numérique ou par défaut « local »)
    var sFonctionTri = (this.getAttribute("data-type")=="num") ? "compareNombres" : "compareLocale";
    // Tri
    aColonne.sort(eval(sFonctionTri));
    // Tri numérique
    function compareNombres(a, b) {return a[nIndex-1] - b[nIndex-1];}
    // Tri local (pour support utf-8)
    function compareLocale(a, b) {return a[nIndex-1].localeCompare(b[nIndex-1]);}
    // Renverse la matrice dans le cas d’un tri descendant
    if (nBoolDir==0) aColonne.reverse();
    
    // Construit les colonne du nouveau tableau
    for(i = 0; i < nNbrLigne; i++){
      aColonne[i] = "<td>"+aColonne[i].join("</td><td>")+"</td>";
    }

    // assigne les lignes au tableau
    oTbody.innerHTML = "<tr>"+aColonne.join("</tr><tr>")+"</tr>";
  }
</script>
Nom Ville Âge
LucMontréal28
PierreÉloi-20
GastonRivière-du-Loup21
PaulCacouna26
BertrandLes Boules-12
AnnetteSaint-Arsène32
Ti-GuyRimouski470
DjangoL’Isle-Verte49
ClaudeRimouski39
Alternatives

« Data Grids » en JavaScript

Modules pour jQuery

Prototypes

Autres

, Analyste programmeurConception oznogco multimédia (http://oznogco.com), Trucsweb
Dernière mise à jour :

Commentaires

  • Je cherchais une solution permettant de faire des tris numériques sur une colonne d'un tableau et aussi la solution que vous présentez m'intéressait-elle. Mais, est-ce moi qui ait la berlue ou quoi : dans le tableau d'exemple en bas de page, les colonnes sont bien triées mais, pas le tableau lui-même. Je veux dire par là que l'intérêt de pouvoir faire un tri sur une colonne est que les autres colonnes soient réordonnées simultannément. Ce qui n'est pas le cas dans le tableau proposé. st-ce moi qui ai mal compris ?
    64x64
    GUILLEMONT

    2015-06-14 8:40:44

    • Oh, merci! Effectivement, c'est moi qui avais la berlue! Pas facile de vieillir. Le script pouvait bien être très léger. J'ai adapté le script, moins performant, mais toujours aussi petit et surtout compatible avec les caractères accentués. Merci.
      64x64
      oznog
      http://www.trucsweb.com
      2015-06-14 23:12:25

      • Bonjour, je cherche une solution simple pour désactiver le tri sur une colonne. Est-ce possible ? Merci de votre aide et merci pour ce script au combien efficace. HP
        64x64
        HP

        2015-10-28 13:35:57
        • Salut, Le script détecte les entêtes de tableau (th) à l'aide de la méthode « queryselectorAll » et du sélecteur « th ». Dans la fonction « twInitTableau() » : oEntete.queryselectorAll(th); 1. Il suffit de spécifier une class comme sélecteur, par exemple la classe « tri » : oEntete.queryselectorAll(th.tri); 2. Et bien sûr d'ajouter la classe dans le tableau : <thead> <tr> <th class="tri" data-pos="1" data-tri="1">Nom</th> <th data-pos="2" data-tri="1">Ville</th> <th class="tri" data-pos="3" data-tri="0" data-type="num">Âge</th> </tr> </thead> Seule les entêtes avec la classe « tri » activera le tri. P.S. Pour enlever la main sur l'entête (cursor:pointer;) il faut enlever le code du curseur dans la classe de base pour les entête (.avectri th) puis spécifier le curseur dans la nouvelle classe « tri » : .avectri th.tri { cursor:pointer;}
          64x64
          oznog
          http://www.trucsweb.com
          2015-10-28 13:54:14


        • Bonjour, déjà merci pour ce code il est très simple et marche parfaitement ! Je souhaiterais qu'au chargement de la page le tableau soit trié par Date (ce qui correspond à ma dernière colonne), comment faire svp ?
          64x64
          COUPE

          2015-11-12 10:48:25
          • Salut, Bonne idée pour le tri par défaut. J'ai utilisé la classe « selection » pour détecter la colonne à trier au départ. Par exemple ta dernière colonne : <th class="selection">Date</th> Et j'ajoute dans la boucle de l'init : // Détection de la colonne à trier par défaut if (oTh.className=="selection") { // Forcer le clic pour faire le tri par défaut oTh.click(); } En passant, j'ai aussi ajouté un bout de code pour un tri ascendant ou descendant : <th data-tri="1">Âge</th> if(oTh.getAttribute(data-tri)=="1") { oTh.innerHTML += "<span class=\flecheDesc\></span>"; } else { oTh.setAttribute(data-tri, 0); oTh.innerHTML += <span "class=\flecheAsc\></span>"; } Pour le tri par date, tu dois t'assurer d'avoir un format aaaa-mm-jj sinon tu dois ajouter un tri spécial pour les dates...
            64x64
            oznog
            http://www.trucsweb.com
            2015-11-12 16:59:27
            • Bonjour ! Je sais que je réponds tard à votre réponse mais ca ne fonctionne pas du tout le tri automatique dans mon tableau...
              64x64
              COUPE

              2016-01-07 20:55:19



        • Le tri fonctionne très bien avec l'exemple, mais il ne veut rien savoir avec mon tableau (15 colonnes sur environ 350 lignes... une idée?
          64x64
          Nui
          http://martha-group.com
          2015-12-20 2:7:1
          • Salut, Je viens de le tester avec un tableau de 10 colonne sur 400 lignes sans aucun problème. J'ai aussi testé avec Bootstrap et jQuery au cas, et ça fonctionne sans aucune différence. Veuillez tester votre tableau dans une page vide, sans autre code. Merci.
            64x64
            oznog
            http://www.trucsweb.com
            2016-01-04 14:30:14


          • Bonsoir, Merci pour ce code très concis. Malheureusement, je n'y connais pas grand chose en script ... Mon tableau possède plusieurs colonnes en numérique et j'aimerais pouvoir effectuer le tri sur chacune de ces colonnes. Sans rien changer à votre code, j'ai ajouté mes colonnes numériques de la façon suivante dans <table> : <th data-tri="1" class="selection" data-type="num">colonne numérique 1</th> <th data-type="num">colonne numérique 2</th> <th data-type="num">colonne numérique 3</th> <th data-type="num">colonne numérique 4</th> Mais le tri n'est effectué que pour la colonne numérique 1, pas pour les autres. Y a-t-il une solution simple ? Merci beaucoup.
            64x64
            pacific

            2016-01-02 16:10:31
            • Salut, Je ne comprends pas, je viens de le tester avec un très gros tableau et ça fonctionne? Voilà mon entête : <table class="tableau zebre avectri"> <thead> <tr> <th data-tri="1" class="selection" data-type="num">colonne numérique 1</th> <th data-type="num">colonne numérique 2</th> <th data-type="num">colonne numérique 3</th> <th data-type="num">colonne numérique 4</th> <th data-type="num">colonne numérique 5</th> <th data-type="num">colonne numérique 6</th> <th data-type="num">colonne numérique 7</th> <th data-type="num">colonne numérique 8</th> </tr> </thead> ...
              64x64
              oznog
              http://www.trucsweb.com
              2016-01-04 14:28:15
              • Bonjour et meilleurs vœux pour 2016 ! Merci pour votre réponse. Je viens de découvrir le pourquoi de l'erreur : j'ai modifié mes valeurs de cellules et me suis rendu compte que le tri fonctionnait bien avec des valeurs numériques entières mais mon tableau comporte des colonnes numériques avec nombres décimaux. Je ne sais pas si votre code est conçu pour cela ou si une petite modification le permettrait. Merci et bonne journée.
                64x64
                pacific

                2016-01-05 8:5:26
                • Re Le problème est résolu : il faut entrer les valeurs numériques avec un "." et non une "," :) Reste un petit détail : si l'on attribue un lien hypertexte à certaines valeurs de cellule non numériques, le tri ne semble pas se faire correctement.
                  64x64
                  pacific

                  2016-01-05 9:47:18
                  • Salut, Oui, bonne année dans la PAIX! Pauvre francophone ; - ) C'est nous les bizarres encore une fois, j'applique toujours un ajustement sur les nombres pour les convertir en système anglais à la source. Mais effectivement, impossible dans ce cas sans faire une passe, du genre convertir chaque nombre lors du tri! Chose absolument stupide mais obligatoire! On en gaspille de l'énergie avec cette virgule et ce chauvinisme mondial! Ou se la faire facile et tout afficher en anglais, avec des points... En fait c'est exactement la même chose pour les hyperliens ou encore les images, ce ne sont pas des nombres ni du texte. D'ailleurs avec les hyperliens le tri doit se faire sur le lien ou le texte? Et l'image, selon la description (alt) ou selon son URL... En d'autres mots, pour un tri complexe, il faut une solution à chaque cas. Texte, nombre, nombre négatif, nombre décimal avec virgule, images, hyperlien ou tout autre HTML. D'ailleurs pourquoi trier des images? Et pourquoi pas ne pas empêcher tout simplement le tri dans une colonne avec un hyperlien! P.S. Parlant de point et de virgule. La langue et la culture sont une richesse de la nature qui permet différence forme de pensée et manière de voir le monde. Au delà de cet exemple insignifiant, Il faut les protéger comme la prunelle de nos yeux! Le merveuilleux Web permet enfin une pensée non-linéaire perdu depuis des siècles mais elle pourrait aussi l'uniformiser à grande vitesse, voir banaliser et en faire une seule manière de pensé globale à la Gutenberg...
                    64x64
                    oznog
                    http://www.trucsweb.com
                    2016-01-05 12:45:45





            • Bonjour, J'ai des paramètres dans chacun de mes tr (un onclick et une class), le problème et que quand l'on filtre le tr est complètement reconstruit et donc vide est t'il possible de garder mes paramètres ?
              64x64
              Thony

              2016-02-11 11:43:39
              • Salut, Effectivement, bonne observation. Le problème vient du fait que le tableau est entièrement transposé dans une matrice (ARRAY) à deux dimensions. C'est à dire « ligne X colonne »! Comme toute bonne matrice. Il suffit de transférer les valeurs (innerHTML) du tableau dans la matrice : aColonne[i][j] = oCel[j].innerHTML; Il faudrait pouvoir transférer les classes, les évènements (tous!) onclick, onmouseover etc et autres paramètres comme data-* etc. Impossible dans une matrice il faut passer un objet au lieu d'une valeur. Exemple : oMonObjet.maValeur = oCel[j].innerHTML; oMonObjet.maClass = oCel[j].className; ... aColonne[i][j] = oMonObjet; Même chose pour la création du tableau après le tri et bien sûr sans utiliser le facilitateur « .join » et surtout sans passer par les lignes, mais cellule par cellule pour ajuster le TD... Exemple : //Boucle sMaNouvelleLigner += "<td"; // Il y a une class. if (aColonne[i][j].maClass!='') {sMaNouvelleLigner += " class="+aColonne[i][j].maClass;} // Autres, comme onclick... // Fin de la balise TD sMaNouvelleLigner += ">"; sMaNouvelleLigner += aColonne[i][j].maValeur; sMaNouvelleLigner += "</td>"; // Fin boucle Reste à le faire...
                64x64
                oznog
                http://www.trucsweb.com
                2016-02-11 13:37:57
                • Si ça peu aider voici ce que j'ai fait: // Construit la matrice // Récupère le tableau (tbody) var oTbody = this.parentNode.parentNode.parentNode.getElementsByTagName("tbody")[0]; var oLigne = oTbody.rows; var nNbrLigne = oLigne.length; var nbattribut = 2; //on rajoute le nombre d’attribut que l'on souhaite récupérer var aColonne = new Array(), i, j, oCel; for(i = 0; i < nNbrLigne; i++) { oCel = oLigne[i].cells; aColonne[i] = new Array(); aColonne[i][0] = oLigne[i].getAttribute("class"); //on récupère les attributs et on les met en début de tableau aColonne[i][1] = oLigne[i].getAttribute("onclick"); //on récupère les attributs et on les met en début de tableau var nbcolone_o=oCel.length; var nbcolone=nbcolone_o+nbattribut; //on rajoute les colonnes attributs for(j = nbattribut; j < nbcolone; j++){ aColonne[i][j] = oCel[j-nbattribut].innerHTML; } //on construit les lignes avec les attributs } // Construit les colonne du nouveau tableau for(i = 0; i < nNbrLigne; i++){ for(j = nbattribut; j < nbcolone; j++){ //on enleve les colonnes attributs if(j==nbattribut){ cellules = "<td>"+aColonne[i][j]+"</td>"; //on écris les cellules de nos lignes }else{ cellules += "<td>"+aColonne[i][j]+"</td>"; //on écris les cellules de nos lignes } } if(i==0){ oTbody.innerHTML ="<tr class='"+aColonne[i][0]+"'onclick="+aColonne[i][1]+"'>"+cellules+"</tr>"; //on écrit les attributs }else{ oTbody.innerHTML +="<tr class='"+aColonne[i][0]+"'onclick="+aColonne[i][1]+"'>"+cellules+"</tr>"; //on écrit les attributs } } Voilà j'ai essayé de commenter un peu pour que ça soit compréhensible, c'est surement pas optimisé mais ça fait ce que je veux :). Et encore merci pour ton super script !!! :) ------------------------------ J'ai oublié cette partie: var nIndex = this.getAttribute("data-pos"); nIndex = +nIndex; nIndex = nbattribut+nIndex; très importante ^^"
                  64x64
                  Thony

                  2016-02-11 14:42:41
                  • Oui, c'est une façon de faire, et d'ailleurs plus simple sur les lignes que les cellules. En fait c'est un ajustement perso. Il suffit d'ajouter une classe sur les cellules ou d'autres événements pour devoir refaire l'ensemble du script selon les cas. Personnellement j'ajouterais une fonction qui passe le tableau seulement une fois généré (et après chaque tri) pour ajouter les événements. Un simple twAjouteLesclasseEtEvenements("monTableau") qui ajoute les événement sur chaque ligne. Normalement c'est la façon de faire. Merci pour ton exemple.
                    64x64
                    oznog
                    http://www.trucsweb.com
                    2016-02-11 14:52:44
                    • Bonjour, je n'avais pas vu la réponse précédente initialement crée par Thony. j'ai trouvé ton script et j'ai franchement aimé le code et le principe. j'ai tenté de l'adapté, chose faite mais comme lui j'avais tous les attirbuts de <TR> <TD> qui sautent. je commence en dans ce domaine et j'ai mis longtemps à comprendre que le tableau était complètement re crée et en lisant ta réponse avec la matrice cela correspond à mon affichage les éléments refaits en séparateur "," etc. je n'arrive pas à créer la modification pour réaliser cela. j'ai voulu "et cru" quand créant une sauvegarde de oTbody je pourrais l'utiliser pour la ré injecter avec getAttributes mais je n'arrive pas toujours null renvoyé etc. Et je ne comprends pas tout à fait ce que tu veux dire par : Un simple twAjouteLesclasseEtEvenements("monTableau") Pourrais tu m'éclairer ?
                      64x64
                      Ronanb

                      2016-02-14 19:37:48
                      • Salut, Désolé, les commentaires sont modérés, l'abus de formulaire doit même être enseigné au HEC! Malheureusement je suis sur un contrat qui prend tout mon temps, je te reviens d'ici peu pour la solution...
                        64x64
                        oznog
                        http://www.trucsweb.com
                        2016-02-16 13:2:5






              • bonjour, Bizarrement chez moi, la flèche vers le haut ne s'affiche pas.
                64x64
                Didier

                2016-03-19 17:2:35

                • Bonjour, Tout fonctionne parfaitement, sauf les flèches. Elles ne sont pas visibles. Pouvez vous m'aider svp ? Merci !
                  64x64
                  Lucile

                  2016-06-22 15:25:39

                  • Bonjour, merci pour le code. Je l'utilise sur un tableau et sur Firefox, le tri fonctionne parfaitement. Par contre, sur IE, cela ne marche pas : pas de flèches et les entêtes non cliquables.
                    64x64
                    Cathy

                    2016-11-16 14:5:1
                    • Salut, La seule façon de faire du débogage, c'est d'isoler le problème. Déjà, il faut connaitre la version d'IE en question. Le code est compatible Edge et IE11 et en principe IE10. J'ose espérer la version 9 mais c'est fort possible que non. Rien en dessous de IE9 avec cette technique. Mais la flèche est en pure CSS, ce n'est pas une question d'accès à une image ni à l'encodage d'une police. Essai le directement : <style> .flecheDesc { width: 0; height: 0; margin: 10px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 5px solid black; } </style> <span class="flecheDesc"></span> Ciao
                      64x64
                      oznog
                      http://www.trucsweb.com
                      2016-11-16 14:23:19

                      • Je n'avais pas lu le « non cliquable ». C'est probablement IE9 ou moins. IE9 prend en charge le « addEventListener » mais il faut absolument définir le doctype HTML5 en haut du document : <!DOCTYPE html> Pour IE8 et moins, il faut plutôt la méthode « attachEvent »! Voilà une fonction pour la conversion (http://www.w3schools.com/jsref/met_document_addeventlistener.asp) : function twAddEvent(sEvenement, oElement, sFonction) { if (oElement.addEventListener) // W3C DOM oElement.addEventListener(sEvenement,sFonction,false); else if (oElement.attachEvent) { // IE DOM oElement.attachEvent("on"+sEvenement, sFonction); } } twAddEvent("click",oTh,twTriTableau);
                        64x64
                        oznog
                        http://www.trucsweb.com
                        2016-11-16 14:48:24
                        • Merci pour ces réponses. Effectivement, je suis sur IE8 (pas de mon choix).
                          64x64
                          Cathy

                          2016-11-18 9:16:13



                      • Bonjour, merci pour ce code. Le rendu du tableau me plait bien. Mais je n'arrive pas à faire fonctionner le tri correctement pour des colonnes contenant des icônes et des hyperliens du type <td><img src="...."><a href="...">Nom affiché dans le tableau</a></td>. Y-a-t-il un moyen d'adapter le code facilement ?
                        64x64
                        Christophe

                        2016-12-01 9:47:56
                        • Salut, Comme précisé, ce code fait un tri texte ou numérique et rien d'autre. Il ne fonctionne pas avec les nombres négatifs, nombres décimaux avec les virgules, les images, les hyperliens ou tout autre HTML. C'est impossible (voir la réponse plus haute à la même question) sans retirer les images et les hyperliens avant le tri. Si je n'avais pas le choix, mais vraiment pas le choix, j’ajouterais un attribut avec le contenu à trier sans image et sans hyperlien. Et modifier le code pour faire le tri à partir de cet attribut au lieu du contenu « innerHTML ». <td data-contenu="Nom affiché dans le tableau"><img src="...."><a href="...">Nom affiché dans le tableau</a></td> Puis dans le code du tri lors du transfert dans la matrice, récupérer cette valeur : // au lieu de : aColonne[i][j] = oCel[j].innerHTML; // utiliser l'attribut data-contenu aColonne[i][j] = oCel[j].getAttribute("data-contenu"); Note que tu te ramasses avec un autre attribut (data-contenu) à gérer et donc à ajouter lors du rendu du tableau.
                          64x64
                          oznog
                          http://www.trucsweb.com
                          2016-12-01 14:33:18


                        • Bonjour, Merci de ta réponse par rapport au tri. J'ai une autre question, plus bloquante : Le tableau marche très bien sur une page en local et en http. Mais mon site est en https avec IE 11 et du coup la parti script ne se charge pas et du coup, le tri ne marche pas. Je ne sais pas si c'est le https qui est en cause (je ne m'y connais pas), mais en mode debug j'obtiens une erreur "L'objet ne gère pas la propriété ou la méthode " getElementsByClassName" au niveau de l'initialisation du tableau "avectri". Sous Firefox, le tableau continue à marcher parfaitement, même en https. Peux-tu m'aider ?
                          64x64
                          Christophe

                          2016-12-14 18:23:11
                          • Bonjour et bonne année ! Finalement j'ai trouvé comment faire. Cela n'a rien à avoir ni avec le côté HTTPS, ni avec la méthode évoquée. J'ai simplement rajouté la ligne suivante dans la partie HEAD de la page et du coup ça marche partout : <META content="IE=11.0000" http-equiv="X-UA-Compatible">
                            64x64
                            Christophe

                            2017-01-04 14:49:52


                          • Bonjour, Beau boulot, merci ! Je souhaite avoir des largeur de colonnes fixe. J'ai ajouter aux th (j'en ai 2) une classe puis défini la largeur en css : .mesure { max-width: 20% !important; } .objet { max-width: 70% !important; } .etat { max-width: 10% !important; } Mais cela ne fonctionna pas. Saurait tu me dire comment rendre fixe la largeur des colonnes ? Merci d'avance.
                            64x64
                            Gilles Godiveau

                            2016-12-22 16:9:22

                            10/10 sur 1 revues.
                                   Visites : 13936 - Pages vues : 14817
                            X

                            Trucsweb.com Connexion

                            Connexion

                            X

                            Trucsweb.com Mot de passe perdu

                            Connexion

                            X

                            Trucsweb.com Conditions générales

                            Conditions

                            Responsabilité

                            La responsabilité des Trucsweb.com ne pourra être engagée en cas de faits indépendants de sa volonté. Les informations mises à disposition sur ce site le sont uniquement à titre purement informatif et ne sauraient constituer en aucun cas un conseil ou une recommandation de quelque nature que ce soit.

                            Aucun contrôle n'est exercé sur les références et ressources externes, l'utilisateur reconnaît que les Trucsweb.com n'assume aucune responsabilité relative à la mise à disposition de ces ressources, et ne peut être tenue responsable quant à leur contenu.

                            Droit applicable et juridiction compétente

                            Les règles en matière de droit, applicables aux contenus et aux transmissions de données sur et autour du site, sont déterminées par la loi canadienne. En cas de litige, n'ayant pu faire l'objet d'un accord à l'amiable, seuls les tribunaux canadien sont compétents.

                            X

                            Trucsweb.com Trucsweb

                            X

                            Trucsweb.com Glossaire

                            X

                            Trucsweb.com Trucsweb

                            X

                            Trucsweb.com Trucsweb

                            Conditions

                            Aucun message!

                            Merci.

                            X
                            Aucun message!
                            X

                            Trucsweb.com Créer un compte

                            Créer un compte

                            .
                            @