128 votes

Trier un tableau HTML avec JavaScript

Je suis à la recherche d'une solution de tri de tableaux (en JavaScript), mais je n'arrive pas à en trouver une qui convienne. J'ai juste besoin qu'elle trie chaque colonne par ordre alphabétique. Il n'est pas nécessaire d'ignorer le code, les chiffres ou de travailler avec des devises. Il suffit d'un clic sur l'en-tête de la colonne pour la faire passer du tri a-z/z-a.

Quelqu'un connaît-il une solution vraiment simple comme celle-ci ?

0voto

vault Points 719

Je suis très reconnaissant pour le réponse acceptée y la fixation de jedwards mais je les trouve aussi peu lisibles. Voici donc ma version remaniée et verbeuse :

// Remember that strings are false positives for isNaN
const isEmptyOrNaN = (obj) => obj === "" || isNaN(obj);

const getCellValueInColumn = (tr, columnIdx) =>
  tr.children[columnIdx].innerText || tr.children[columnIdx].textContent;

const compareCellValues = (cellValue1, cellValue2) => {
  return isEmptyOrNaN(cellValue1) || isEmptyOrNaN(cellValue2)
    ? cellValue1.toString().localeCompare(cellValue2)
    : cellValue1 - cellValue2;
};

const compareFnFactory = (columnIdx, ascending) => (firstEl, secondEl) => {
  const cellValue1 = getCellValueInColumn(firstEl, columnIdx);
  const cellValue2 = getCellValueInColumn(secondEl, columnIdx);
  return ascending
    ? compareCellValues(cellValue1, cellValue2)
    : compareCellValues(cellValue2, cellValue1);
};

document.querySelectorAll("th").forEach((th) =>
  th.addEventListener("click", () => {
    const table = th.closest("table");
    const tbody = table.querySelector("tbody");
    const columnIdx = Array.from(th.parentNode.children).indexOf(th);
    const compareFn = compareFnFactory(columnIdx, (this.ascending = !this.ascending));
    Array.from(tbody.querySelectorAll("tr"))
      .sort(compareFn)
      .forEach((tr) => tbody.appendChild(tr));
  })
);

Si vous trouvez des espaces ou des parenthèses supplémentaires, des retraits inutiles, etc., c'est parce que j'ai formaté le code avec Prettier.

J'ai enveloppé ce code dans un :

javascript: (function () {
  // Code here
})();

et le mettre dans un bookmarklet, donc maintenant je peux trier les colonnes dans la console d'administration de Keycloak.

0voto

giovnn Points 21

Je me suis retrouvé à utiliser la méthode de @NickGrealy pour trier les articles et ça marche très bien ! ( https://stackoverflow.com/a/49041392/18045902 )

Le problème que j'ai rencontré est que j'utilise un format différent pour la date : jj-mm-aa au lieu du format ISO.

Comme je transmets les données d'un fichier .php sous la forme d'une chaîne, j'ai dû convertir la chaîne en date puis la comparer avec ><==.

Substituer la fonction de comparaison

// Returns a function responsible for sorting a specific column index 
// (idx = columnIndex, asc = ascending order?).
var comparer = function(idx, asc) { 

// This is used by the array.sort() function...
return function(a, b) { 

    // This is a transient function, that is called straight away. 
    // It allows passing in different order of args, based on 
    // the ascending/descending order.
    return function(v1, v2) {

        // sort based on a numeric or localeCompare, based on type...
        return (v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2)) 
            ? v1 - v2 
            : v1.toString().localeCompare(v2);
    }(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
}

} ;

avec ça :

    var comparer = function(idx, asc) { 

// This is used by the array.sort() function...
return function(a, b) { 

    // This is a transient function, that is called straight away. 
    // It allows passing in different order of args, based on 
    // the ascending/descending order.
    return function(v1, v2) {

        if(v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2)){
            x = v1 - v2;
            console.log(v1); 
        } else if(v1.includes("-")) {
            var partsArray1 = v1.split('-');
            var partsArray2 = v2.split('-');
            var data1 = new Date(partsArray1[2],partsArray1[1],partsArray1[0]);
            var data2 = new Date(partsArray2[2],partsArray2[1],partsArray2[0]);
            if(data1>data2){
                x=1;
            } else if (data1<data2) {
                x=-1;
            } else if (data1==data2) {
                x=0;
            }

        } else {
            x = v1.toString().localeCompare(v2);
        }
        // sort based on a numeric or localeCompare, based on type...
        //return (v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2)) 
        //    ? v1 - v2 
        //    : v1.toString().localeCompare(v2);

        return x;

    }(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
}
};

NOTE : ceci ne fonctionnera que si la date que vous essayez d'analyser est une chaîne au format dd-mm-YY. Si vous avez besoin d'un format différent, changez le caractère includes() et split() (dans mon cas, c'est "-") et l'ordre de la date que vous créez avec Date().

S'il y a un problème avec cette méthode, veuillez commenter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X