2009-03-08 15 views
6

Estoy tratando de obtener el jQuery Live Search with Quicksilver Style de John Resig para que funcione con un control de selección de formularios múltiples. Su código se basa John Nunemaker's Work desarrollando su código quicksilver.js.jQuery Live Search con Quicksilver Style en un cuadro de lista de selección múltiple

El problema que tengo es que dentro de un cuadro de selección solo Firefox admite .hide() en valores de opción, no puedo descifrar un enfoque ágil para IE, Safari, Opera y Chrome.

He aquí un ejemplo, he introducido el código de John R pero tendrá que tomar quicksilver.js y alojarlo localmente usted mismo. De nuevo, esto funciona muy bien en Firefox, pero la llamada a rows.hide() no hace nada en otros navegadores.

He intentado envolver las etiquetas en un div y ocultar eso, pero no tuve suerte.

¿Alguna 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

¿Básicamente, estás buscando una forma de navegador cruzado para ocultar las opciones? – James

+0

Sí, hasta ahora solo funciona en Firefox – kevink

Respuesta

8

El mejor enfoque es simplemente para agregar y eliminar opciones del DOM.

De esta manera:

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

que marcar más de matriz "todos" en lugar de filas.

+0

Eso funcionó como un amuleto, gracias - me había estado golpeando la cabeza contra el escritorio. – kevink

+0

Un problema de seguimiento, cualquiera sabe una buena manera de agregar un retraso así que si un usuario teclea varias teclas rápidamente, ¿no llamará para filtrar todas las teclas? En un par de miles de opciones, puede ser bastante lento. – kevink

+0

Debería crear una nueva pregunta para eso, pero en resumen puede usar los métodos incorporados de setTimeout/clearTimeout de javascript para agregar un retraso antes de filtrar. – Joel

Cuestiones relacionadas