2017-10-17 16 views
1

J'ai une table qui fonctionne en cliquant sur un en-tête, qui trie ensuite la colonne dans l'ordre croissant et décroissant chaque fois que vous cliquez sur l'en-tête. Il trie tout dans l'ordre alphabétique, mais j'en ai besoin pour pouvoir trier numériquement.Trier le tableau numériquement et alphabétiquement en utilisant Javascript

Il semble fonctionner jusqu'à ce que les chiffres dépassent les chiffres uniques dans la même colonne.

Voici le code HTML: (Ignorer le contenu de la NFL, il est juste des données pour tester ce tableau)

<div id="supAll"> 
      <table border="1" class="supTable"> 
       <tr> 
        <th onclick="sortTable('supTable', 0)">Team</th> 
        <th onclick="sortTable('supTable', 1)">SB Wins</th> 
        <th onclick="sortTable('supTable', 2)">SB Losses</th> 
        <th onclick="sortTable('supTable', 3)">Last Won</th> 
       </tr> 
       <tr class="nfc nfcWest"> 
        <td>Arizona Cardinals</td> 
        <td>0</td> 
        <td>1</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcSouth"> 
        <td>Atlanta Falcons</td> 
        <td>10</td> 
        <td>2</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcNorth"> 
        <td>Baltimore Ravens</td> 
        <td>2</td> 
        <td>0</td> 
        <td>2012</td> 
       </tr> 
       <tr class="afc afcEast"> 
        <td>Buffalo Bills</td> 
        <td>11</td> 
        <td>4</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcSouth"> 
        <td>Carolina Panthers</td> 
        <td>22</td> 
        <td>2</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcNorth"> 
        <td>Chicago Bears</td> 
        <td>1</td> 
        <td>1</td> 
        <td>1985</td> 
       </tr> 
       <tr class="afc afcNorth"> 
        <td>Cincinnati Bengals</td> 
        <td>0</td> 
        <td>2</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcNorth"> 
        <td>Cleveland Browns</td> 
        <td>0</td> 
        <td>0</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcEast"> 
        <td>Dallas Cowboys</td> 
        <td>5</td> 
        <td>3</td> 
        <td>1995</td> 
       </tr> 
       <tr class="afc afcWest"> 
        <td>Denver Broncos</td> 
        <td>3</td> 
        <td>5</td> 
        <td>2015</td> 
       </tr> 
       <tr class="nfc nfcNorth"> 
        <td>Detroit Lions</td> 
        <td>0</td> 
        <td>0</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcNorth"> 
        <td>Green Bay Packers*</td> 
        <td>4</td> 
        <td>1</td> 
        <td>2010</td> 
       </tr> 
       <tr class="afc afcSouth"> 
        <td>Houston Texans</td> 
        <td>0</td> 
        <td>0</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcSouth"> 
        <td>Indianapolis Colts</td> 
        <td>2</td> 
        <td>2</td> 
        <td>2006</td> 
       </tr> 
       <tr class="afc afcSouth"> 
        <td>Jacksonville Jaguars</td> 
        <td>0</td> 
        <td>0</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcWest"> 
        <td>Kansas Chiefs*</td> 
        <td>1</td> 
        <td>1</td> 
        <td>1969</td> 
       </tr> 
       <tr class="afc afcWest"> 
        <td>Los Angeles Chargers</td> 
        <td>0</td> 
        <td>1</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcWest"> 
        <td>Los Angeles Rams</td> 
        <td>1</td> 
        <td>2</td> 
        <td>1999</td> 
       </tr> 
       <tr class="afc afcEast"> 
        <td>Miami Dolphins</td> 
        <td>2</td> 
        <td>3</td> 
        <td>1973</td> 
       </tr> 
       <tr class="nfc nfcNorth"> 
        <td>Minnesota Vikings</td> 
        <td>0</td> 
        <td>4</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcEast"> 
        <td>New England Patriots</td> 
        <td>5</td> 
        <td>4</td> 
        <td>2016</td> 
       </tr> 
       <tr class="nfc nfcSouth"> 
        <td>New Orleans Saints</td> 
        <td>1</td> 
        <td>1</td> 
        <td>2009</td> 
       </tr> 
       <tr class="nfc nfcEast"> 
        <td>New York Giants</td> 
        <td>4</td> 
        <td>1</td> 
        <td>2011</td> 
       </tr> 
       <tr class="afc afcEast"> 
        <td>New York Jets*</td> 
        <td>1</td> 
        <td>0</td> 
        <td>1968</td> 
       </tr> 
       <tr class="afc afcWest"> 
        <td>Oakland Raiders</td> 
        <td>3</td> 
        <td>2</td> 
        <td>1983</td> 
       </tr> 
       <tr class="nfc nfcEast"> 
        <td>Philadelphia Eagles</td> 
        <td>0</td> 
        <td>2</td> 
        <td>-</td> 
       </tr> 
       <tr class="afc afcNorth"> 
        <td>Pittsburgh Steelers</td> 
        <td>6</td> 
        <td>2</td> 
        <td>2008</td> 
       </tr> 
       <tr class="nfc nfcWest"> 
        <td>San Francisco 49ers</td> 
        <td>5</td> 
        <td>5</td> 
        <td>1994</td> 
       </tr> 
       <tr class="nfc nfcWest"> 
        <td>Seattle Seahawks</td> 
        <td>1</td> 
        <td>2</td> 
        <td>2013</td> 
       </tr> 
       <tr class="nfc nfcSouth"> 
        <td>Tampa Bay Buccaneers</td> 
        <td>1</td> 
        <td>0</td> 
        <td>2002</td> 
       </tr> 
       <tr class="afc afcSouth"> 
        <td>Tennessee Titans</td> 
        <td>0</td> 
        <td>1</td> 
        <td>-</td> 
       </tr> 
       <tr class="nfc nfcEast"> 
        <td>Washington Redskins</td> 
        <td>3</td> 
        <td>2</td> 
        <td>1991</td> 
       </tr> 
      </table> 
     </div>  
    </div> 

Et ci-dessous voici le code Javascript:

function sortTable(tableClass, n) { 
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0; 

table = document.getElementsByClassName(tableClass)[0]; 
switching = true; 
dir = "asc"; 
while (switching) { 
    switching = false; 
    rows = table.getElementsByTagName("TR"); 
    for (i = 1; i < (rows.length - 1); i++) { 
     shouldSwitch = false; 
     x = rows[i].getElementsByTagName("TD")[n]; 
     y = rows[i + 1].getElementsByTagName("TD")[n]; 
     if (dir == "asc") { 
      if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { 
       shouldSwitch= true; 
       break; 
      } 
     } else if (dir == "desc") { 
      if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) { 
       shouldSwitch= true; 
       break; 
      } 
     } 
    } 
    if (shouldSwitch) { 
     rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 
     switching = true; 
     switchcount ++;  
    } else { 
     if (switchcount == 0 && dir == "asc") { 
      dir = "desc"; 
      switching = true; 
     } 
    } 
} 

}

Si vous exécutez le code que vous pouvez voir dans la colonne du milieu, où il y a différents nombres de taille, il ne les triera plus correctement.

Y a-t-il un moyen d'utiliser ce code/cette fonction pour que mes tables fonctionnent pour le tri à la fois par ordre alphabétique et numérique (quand il dépasse les chiffres uniques)? Et si non, quelqu'un peut m'aider à résoudre ce problème.

EDIT - Cela a été résolu! Si vous consultez le code ci-dessous par Hendeca, et Teldri, vous verrez le code résolu. Les deux versions fonctionnent.

Répondre

2

vous devez analyser les valeurs numériques entier ou flotter avant comparsion

si

if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { 

changements

if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) { 

chaîne comparsion si aucun numéro

var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML); 

var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML); 

if (parseInt(cmpX) > parseInt(cmpY)) { 

changer votre fonction à ceci:

function sortTable(tableClass, n) { 
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0; 

table = document.getElementsByClassName(tableClass)[0]; 
switching = true; 
dir = "asc"; 
while (switching) { 
    switching = false; 
    rows = table.getElementsByTagName("TR"); 
    for (i = 1; i < (rows.length - 1); i++) { 
     shouldSwitch = false; 
     x = rows[i].getElementsByTagName("TD")[n]; 
     y = rows[i + 1].getElementsByTagName("TD")[n]; 
       var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML); 
       var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML); 
cmpX=(cmpX=='-')?0:cmpX; 
cmpY=(cmpY=='-')?0:cmpY; 
     if (dir == "asc") { 
      if (cmpX > cmpY) { 
       shouldSwitch= true; 
       break; 
      } 
     } else if (dir == "desc") { 
      if (cmpX < cmpY) { 
       shouldSwitch= true; 
       break; 
      } 
     } 
    } 
    if (shouldSwitch) { 
     rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 
     switching = true; 
     switchcount ++;  
    } else { 
     if (switchcount == 0 && dir == "asc") { 
      dir = "desc"; 
      switching = true; 
     } 
    } 
} 
} 
+0

Bonjour, cela fonctionne très bien pour trier mes colonnes numériques, mais cela m'empêche de pouvoir trier ma première colonne par ordre alphabétique. Seuls les numéros peuvent être triés maintenant. – bevstar7

+0

comme expliqué par stevelacerda7, vous pouvez vérifier si parseInt donne NaN et faire une comparaison de chaîne normale dans ce cas. – teldri

+0

Comment est-ce que je ferais ceci? – bevstar7

0

Le problème est en réalité que vos numéros sont des chaînes. Donc, '14' est inférieur à '4'. Vous pouvez essayer de convertir en nombre d'abord, et si isNaN, alors vous pouvez le tester comme une chaîne, sinon, comme un nombre.

_sortTable: function(n, context) { 
    var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0; 
    table = document.getElementById(context.options.id); 
    switching = true; 

    //Set the sorting direction to ascending: 
    dir = "asc"; 
    /*Make a loop that will continue until 
    no switching has been done:*/ 
    while (switching) { 
     //start by saying: no switching is done: 
     switching = false; 
     rows = table.getElementsByClassName("row"); 
     /*Loop through all table rows (except the 
     first, which contains table headers):*/ 
     for (i = 0; i < (rows.length - 1); i++) { 
      //start by saying there should be no switching: 
      shouldSwitch = false; 
      /*Get the two elements you want to compare, 
      one from current row and one from the next:*/ 
      x = rows[i].getElementsByClassName("cell")[n]; 
      y = rows[i + 1].getElementsByClassName("cell")[n]; 
      /*check if the two rows should switch place, 
      based on the direction, asc or desc:*/ 
      x = Number(x.innerHTML.toLowerCase()) ? Number(x.innerHTML.toLowerCase()) : x.innerHTML.toLowerCase(); 
      y = Number(y.innerHTML.toLowerCase()) ? Number(y.innerHTML.toLowerCase()) : y.innerHTML.toLowerCase(); 

      if (dir == "asc") { 
       if (x > y) { 
        //if so, mark as a switch and break the loop: 
        shouldSwitch= true; 
        break; 
       } 
      } else if (dir == "desc") { 
       if (x < y) { 
        //if so, mark as a switch and break the loop: 
        shouldSwitch= true; 
        break; 
       } 
      } 
     } 
     if (shouldSwitch) { 
      /*If a switch has been marked, make the switch 
      and mark that a switch has been done:*/ 
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 
      switching = true; 
      //Each time a switch is done, increase this count by 1: 
      switchcount ++; 
     } else { 
      /*If no switching has been done AND the direction is "asc", 
      set the direction to "desc" and run the while loop again.*/ 
      if (switchcount == 0 && dir == "asc") { 
      dir = "desc"; 
      switching = true; 
      } 
     } 
    } 
+0

Comment est-ce que je ferais ceci? – bevstar7

+0

Les deux autres réponses sur cette page ont réussi à résoudre mon problème. Merci pour l'aide en tout cas. – bevstar7

2

Vous devez convertir la valeur de la cellule de table à un nombre si elle est un chiffre et le laisser comme une chaîne si elle est un nom. Cela fera fonctionner la comparaison dans les deux cas. Voici un code mis à jour:

function sortTable(tableClass, n) { 
    var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0; 

    table = document.getElementsByClassName(tableClass)[0]; 
    switching = true; 
    dir = "asc"; 
    while (switching) { 
     switching = false; 
     rows = table.getElementsByTagName("TR"); 
     for (i = 1; i < (rows.length - 1); i++) { 
      shouldSwitch = false; 
      x = rows[i].getElementsByTagName("TD")[n]; 
      y = rows[i + 1].getElementsByTagName("TD")[n]; 
      var xContent = (isNaN(x.innerHTML)) 
       ? (x.innerHTML.toLowerCase() === '-') 
        ? 0 : x.innerHTML.toLowerCase() 
       : parseFloat(x.innerHTML); 
      var yContent = (isNaN(y.innerHTML)) 
       ? (y.innerHTML.toLowerCase() === '-') 
        ? 0 : y.innerHTML.toLowerCase() 
       : parseFloat(y.innerHTML); 
      if (dir == "asc") { 
       if (xContent > yContent) { 
        shouldSwitch= true; 
        break; 
       } 
      } else if (dir == "desc") { 
       if (xContent < yContent) { 
        shouldSwitch= true; 
        break; 
       } 
      } 
     } 
     if (shouldSwitch) { 
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 
      switching = true; 
      switchcount ++;  
     } else { 
      if (switchcount == 0 && dir == "asc") { 
       dir = "desc"; 
       switching = true; 
      } 
     } 
    } 
} 

En testant pour voir si la chaîne est un nombre, vous pouvez déterminer si vous souhaitez convertir cette valeur ou non. Voici le changement pertinent:

var xContent = (isNaN(x.innerHTML)) ? x.innerHTML.toLowerCase() : parseFloat(x.innerHTML); 
var yContent = (isNaN(y.innerHTML)) ? y.innerHTML.toLowerCase() : parseFloat(y.innerHTML); 

EDIT: Ajout de code pour gérer le cas d'un caractère - et converti chaîne de chiffres pour flotter au lieu de entier pour traiter les nombres décimaux. La nouvelle vérification est:

var xContent = (isNaN(x.innerHTML)) 
     ? (x.innerHTML.toLowerCase() === '-') 
      ? 0 : x.innerHTML.toLowerCase() 
     : parseFloat(x.innerHTML); 
var yContent = (isNaN(y.innerHTML)) 
     ? (y.innerHTML.toLowerCase() === '-') 
      ? 0 : y.innerHTML.toLowerCase() 
     : parseFloat(y.innerHTML); 
+1

Ce code n'a pas fonctionné, je pense à cause du placement de votre changement. Je pense qu'il devrait être au-dessus et en dehors de 'if (dir == "asc") {' Si vous consultez l'autre réponse sur cette page, ce code fonctionne et est similaire au vôtre. Si vous lisez ma dernière réponse, j'ai un nouveau problème ... Dans certaines colonnes, j'utilise '-' comme un blanc pour indiquer l'équivalent de 'N/A', ce qui n'est évidemment pas un nombre. Et avec n'importe quelle colonne contenant ce symbole, elle ne le triera pas correctement. Y at-il un moyen de contourner cela? Ou un moyen de convertir ce symbole afin qu'il soit essentiellement égal à 0 (sans avoir à écrire 0)? – bevstar7

+0

@ bevstar7 Vous avez raison, c'était au mauvais endroit! J'ai également ajouté un test pour gérer le cas d'un '-' dans une colonne. Cela renvoie juste un '0' s'il rencontre un' -' à des fins de tri. Ce code fonctionne pour moi et gère le cas '-'. – Hendeca

+0

J'ai réussi à utiliser l'autre code pour résoudre mon problème (ils ont aussi résolu le problème '-'), mais j'ai juste essayé le vôtre et ça marche aussi! Merci pour l'aide. – bevstar7