2009-03-08 6 views
6

J'essaie d'obtenir le jQuery Live Search with Quicksilver Style de John Resig pour qu'il fonctionne avec un contrôle multiformulaire. Son code est basé sur John Nunemaker's Work développant son code quicksilver.js. Le problème que j'ai est que dans une boîte de sélection seulement Firefox prend en charge .hide() sur les valeurs des options, je ne peux pas comprendre une approche rapide pour IE, Safari, Opera et Chrome.Recherche jQuery en direct avec le style Quicksilver dans une zone de liste à sélection multiple

Voici un exemple, j'ai inséré le code de John R mais vous devrez saisir quicksilver.js et l'héberger localement. Encore une fois, cela fonctionne très bien dans Firefox mais l'appel à rows.hide() ne fait rien sur les autres navigateurs.

J'ai essayé d'emballer les étiquettes dans un div et de cacher cela mais pas de chance.

Des idées?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>LiveSearch</title> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script> 
    <script type="text/javascript" src="../jquery/quicksilver.js"></script> 

    <script type="text/javascript" charset="utf-8"> 
    $(document).ready(function() { 
     $('#q').liveUpdate('#posts').focus(); 
    }); 

    jQuery.fn.liveUpdate = function(list){ 
     list = jQuery(list); 

     if (list.length) { 
      // Changed 'li' to 'option' below 
      var rows = list.children('option'), 
       cache = rows.map(function(){ 
       return this.innerHTML.toLowerCase(); 
       }); 

      this 
       .keyup(filter).keyup() 
       .parents('form').submit(function(){ 
        return false; 
       }); 
     } 

     return this; 

     function filter(){ 
      var term = jQuery.trim(jQuery(this).val().toLowerCase()), scores = []; 

      if (!term) { 
       rows.show(); 
      } else { 
       rows.hide(); 

       cache.each(function(i){ 
        var score = this.score(term); 
        if (score > 0) { scores.push([score, i]); } 
       }); 

       jQuery.each(scores.sort(function(a, b){return b[0] - a[0];}), function(){ 
        jQuery(rows[ this[1] ]).show(); 
       }); 
      } 
     } 
    }; 

    </script> 
</head> 
<body> 

<form method="get" autocomplete="off" action=""> 

    <div> 
    <input type="text" value="" name="q" id="q"><br><br> 

    <select id="posts" multiple name="choices" SIZE="10" style="width: 250px"> 
     <option value="1">The Well-Designed Web</option> 
     <option value="2">Welcome John Nunemaker</option> 
     <option value="3">Sidebar Creative: The Next Steps</option> 
     <option value="4">The Web/Desktop Divide</option> 
     <option value="5">2007 in Review</option> 
     <option value="6">Don't Complicate the Solution</option> 
     <option value="7">Blog to Business</option> 
     <option value="8">Single Line CSS</option> 
     <option value="9">The Great Divide</option> 
     <option value="10">What's in a Name?</option> 
    </select> 

    </div> 


</form> 

</body> 
</html> 
+0

Donc, fondamentalement, vous êtes à la recherche d'un moyen multi-navigateur pour cacher les options? – James

+0

Oui, jusqu'à présent cela ne fonctionne que dans Firefox – kevink

Répondre

8

La meilleure approche consiste simplement à ajouter et supprimer des options du DOM.

Comme ceci:

<script type="text/javascript" charset="utf-8"> 
    $(document).ready(function() { 
     $('#q').liveUpdate('#posts').focus(); 
    }); 

    jQuery.fn.liveUpdate = function(list){ 
     list = jQuery(list); 

     if (list.length) { 
       // Changed 'li' to 'option' below 
       var rows = list.children('option'), 
        cache = rows.map(function(){ 
        return this.innerHTML.toLowerCase(); 
        }); 

       var all = rows; 
       all.each(function(i){ 
        $(this).attr("itext", this.innerHTML.toLowerCase()); 
       }); 

       this 
         .keyup(filter).keyup() 
         .parents('form').submit(function(){ 
           return false; 
         }); 
     } 

     return this; 

     function filter(){ 
       var term = jQuery.trim(jQuery(this).val().toLowerCase()), scores = []; 

       if (!term) { 
         list.append(all); 
       } else { 
         rows.remove(); 

         all.each(function(i){ 
           var score = $(this).attr("itext").score(term); 
           if (score > 0) { scores.push([score, i]); } 
         }); 

         jQuery.each(scores.sort(function(a, b){return b[0] - a[0];}), function(){ 
           list.append(all[this[1]]); 
         }); 

         rows = list.children('option'); 
       } 
     } 
    }; 

    </script> 

EDIT:

Besoin de marquer sur tableau "tous" plutôt que des lignes.

+0

Cela a fonctionné comme un charme, merci - je me cognais la tête contre le bureau. – kevink

+0

Un problème de suivi, quelqu'un sait un bon moyen d'ajouter un délai, donc si un utilisateur tape plusieurs touches rapidement, il n'appelle pas de filtre à chaque touche? À quelques milliers d'options, cela peut devenir assez lent. – kevink

+0

Vous devriez créer une nouvelle question pour cela, mais en un mot, vous pouvez utiliser les méthodes setTimeout/clearTimeout de javascript pour ajouter un délai avant le filtrage. – Joel

Questions connexes