2009-03-08 11 views
6

Sto cercando di ottenere il jQuery Live Search with Quicksilver Style di John Resig per lavorare con un controllo multi forma selezionato. Il suo codice è basato su John Nunemaker's Work che sviluppa il suo codice quicksilver.js.jQuery Ricerca dal vivo con stile Quicksilver in una casella di riepilogo a selezione multipla

Il problema che sto avendo è che all'interno di una casella di selezione solo Firefox supporta .hide() sui valori di opzione, non riesco a capire un approccio scattante per IE, Safari, Opera e Chrome.

Ecco un esempio, ho inserito il codice di John R ma è necessario prendere lo quicksilver.js e ospitarlo localmente. Anche in questo caso funziona alla grande in Firefox, ma la chiamata a rows.hide() non fa nulla su altri browser.

Ho provato a racchiudere le etichette in un div e nasconderlo, ma senza fortuna.

Qualche idea?

<!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

Quindi, in sostanza, stai cercando un modo cross-browser per nascondere le opzioni? – James

+0

Sì, per ora funziona solo con Firefox – kevink

risposta

8

L'approccio migliore è solo per aggiungere e rimuovere le opzioni dal DOM.

Ti piace questa:

<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:

Necessità di segnare più di gamma "tutto" piuttosto che le righe.

+0

Ha funzionato come un incantesimo, grazie - avevo battuto la testa contro la scrivania. – kevink

+0

Un problema successivo, qualcuno conosce un buon modo per aggiungere un ritardo, quindi se un utente digita diverse chiavi rapidamente non chiama il filtro ogni keyup? Con un paio di migliaia di opzioni può diventare piuttosto lento. – kevink

+0

Dovresti creare una nuova domanda per questo, ma in breve puoi utilizzare i metodi setTimeout/clearTimeout incorporati di javascript per aggiungere un ritardo prima del filtro. – Joel

Problemi correlati