2009-09-15 5 views
1

Je travaille sur un livre jQuery et suis actuellement sur le chapitre du tri des tables. En utilisant l'exemple de code dans le livre j'ai mis en place le scénario de test suivant, quand je clique sur un en-tête de colonne il trie correctement les données d'une manière (ascendante), mais quand je clique sur le même en-tête de colonne je m'attends à ce que les données soient triées en descendant au second clic). Est-ce que quelqu'un peut jeter un oeil à l'exemple de code ci-dessous et dites-moi pourquoi c'est?Fonction de tri de la table jQuery tri uniquement à sens unique

HTML:

<table class="sortable"> 
<thead> 
    <tr> 
    <th class="sort-alpha"><strong>Flat number</strong></th> 
    <th class="sort-alpha"><strong>Tenant name</strong></th> 
    </tr> 
</thead> 
    <tbody> 
    <tr> 
    <td>83</td> 
    <td>Rachel Prouse</td> 
    </tr> 
    <tr> 
    <td>79</td> 
    <td>Natalie Charles</td> 
    </tr> 
    </tbody> 
</table> 

jQuery:

$(document).ready(function() { 

    $('table.sortable').each(function() { 

     var $table = $(this); 
     $('th', $table).each(function(column) { 
      var $header = $(this); 
      if ($header.is('.sort-alpha')) { 

       $header 
        .addClass('clickable') 
        .hover(
         function() { $header.addClass('hover') }, 
         function() { $header.removeClass('hover'); 
         }) 
        .click(function() { 
         var rows = $table.find('tbody > tr').get(); 
         rows.sort(function(a, b) { 
          var keyA = $(a).children('td').eq(column).text().toUpperCase(); 
          var keyB = $(b).children('td').eq(column).text().toUpperCase(); 
          if (keyA < keyB) return -1; 
          if (keyA > keyB) return 1; 
          return 0; 
         }); 

         $.each(rows, function(index, row) { 
          $table.children('tbody').append(row); 
         }); 
        }); 
      } 
     }); 
    }); 
}); 

Répondre

2

Quelque chose comme ce qui suit le fera. Voici un Working Demo

$(function() { 

    $('table.sortable').each(function() { 

     var $table = $(this); 
     $('th', $table).each(function(column) { 
      var $header = $(this); 
      if ($header.hasClass('sort-alpha')) { 

       $header 
        .addClass('clickable') 
        .hover(
         function() { $header.addClass('hover') }, 
         function() { $header.removeClass('hover'); 
         }) 
        .click(function() { 
         $header.hasClass('asc')? 
          $header.removeClass('asc').addClass('desc'): 
          $header.removeClass('desc').addClass('asc'); 
         var rows = $table.find('tbody > tr').get(); 

         rows.sort(function(a, b) { 
          var keyA = $(a).children('td').eq(column).text().toUpperCase(); 
          var keyB = $(b).children('td').eq(column).text().toUpperCase(); 

          if (keyA > keyB) { 
           return ($header.hasClass('asc')) ? 1 : -1; 
           } 
          if (keyA < keyB) { 
           return ($header.hasClass('asc')) ? -1 : 1; 
          } 
          return 0;      
         }); 

         $.each(rows, function(index, row) { 
          $table.find('tbody').append(row); 
         }); 
        }); 
      } 
     }); 
    }); 
}); 
+0

Vous pouvez placer la classe Direction de tri sur la table au lieu de l'en-tête, tel qu'il s'applique à la table. –

+0

Cela ne fonctionne pas si la version de JQuery est> 1.3.2 à cause du paramètre de la méthode 'hasClass ('. Sort-alpha')'; il devrait être 'hasClass ('sort-alpha')' à la place. – deedee

+1

@deedee tout à fait raison, c'est une faute de frappe :) –

0

piste juste si l'utilisateur cliquez sur une même colonne à nouveau et si, faites une rows.reverse(); avant $ .Chaque boucle

ex

if ($(this).hasClass('desc')) 
{ 
    rows.reverse(); 
    $(this).removeClass('desc'); 
} 
else 
{ 
    $(this).addClass('desc'); 
} 
0

Les return déclarations contenues dans le contrôle de votre fonction de tri de l'ordre de tri. Cela dit, vous devrez garder une trace de l'ascendant ou de la descente au niveau de la colonne, puis les modifier en conséquence. Par exemple ...

var asc = true; 

if(asc) { //Ascending 
    if (keyA < keyB) return -1; 
    if (keyA > keyB) return 1; 
} 
else { //Descending 
    if (keyA < keyB) return 1; 
    if (keyA > keyB) return -1; 
} 
return 0;