2012-07-16 41 views
5

¿Hay alguna manera de mostrar el conjunto de resultados Autocompletar sobre la entrada de texto?¿Cómo colocar el menú de autocompletar sobre la entrada de texto?

El problema es que lo estoy usando en una aplicación lighbox. El elemento de fondo se establece en el 100% de la altura y el ancho de las páginas, naturalmente no se expandirá con su contenido. Entonces, si el contenido sobre el cuadro de texto aumenta tanto que la entrada se fuerza hacia la parte inferior de la página, y luego el usuario escribe algo en él, aparece el menú Autocompletar y la entrada está hacia el final de la página, el menú hace que las barras de desplazamiento aparezcan

Como el elemento de fondo (de color oscuro) no se expandirá para acomodarlo, ya que el menú está absolutamente posicionado, se ve visualmente feo que la parte inferior de la página aparezca blanca (consistente con el color real de la página) mientras que la parte superior de la página está oscura.

De todos modos, hay que hacer esto para que, antes de que aparezca el menú de autocompletar, se debe verificar la posición de la entrada. Si es, digamos, a más de 300px desde la parte superior, ¿entonces el menú debería aparecer arriba de la entrada? Este es el código:

<!DOCTYPE html> 
<html> 
<head> 
<title>Filter</title> 
<link type="text/css" href="ui/ui.css" rel="stylesheet" /> 
     <script type="text/javascript" src="jquery.js"></script> 
     <script type="text/javascript" src="ui.js"></script> 
<style> 
div.filtertab { display: inline-block; height: 30px; background:url(filter.png); border-radius: 5px; position: relative; margin: 10px 45px 10px 8px; cursor: pointer; -moz-user-select: none; box-shadow: 4px 2px 2px #aaaaaa; } 

div.filtertab span.filtertext { position: relative; margin-top: 4px; margin-left: 11px; margin-right: 1px;font-family:cursive,"Comic Sans"; font-size: 0.9em; float: left; display: inline-block; } 

span.arrow { display: inline-block; border-top: 5px solid transparent; width: 0px; height: 0px; border-bottom: 5px solid transparent; border-right: 8.66px solid transparent; border-left: 8.66px solid #333333; margin-left: 7px; margin-top: 10.5px; } 

.dateheaders { background: url(select.png); width: 120px; height: 28px; position: absolute; top: 0px; left: 0px; border-radius: 5px; cursor: pointer; display: inline-block; z-index: 55; } 

.toheader { left: 183px } 

.spandatew { font-weight: bold; position: relative; top: 2px; left: 6px; color: white; font-family: "lucida grande",tahoma,verdana,arial,sans-serif; font-weight: bold; color: white; font-size: 0.8em; } 

div.arrow { height: 0px; width: 0px; position: absolute; display: inline-block; border-bottom: 5px solid transparent; border-right: 5px solid transparent; border-left: 5px solid transparent; border-top: 5px solid white; right: 8px; top: 12px; } 

input#from,input#to {width:107px;height:20px; position: relative; top: -30px; opacity: 0.01; cursor: pointer; } 

input#from { left: 22px; } 

input#to { left: 79px; } 

div#ui-datepicker-div { left: -10px; } 

div#diva1 { width: 190px; position: absolute; display: none; z-index: 10; outline: none;} 

div#diva2 { width: 190px; position: absolute; display: none; z-index: 10; outline: none;} 

#datecontainer { position: relative; width: 400px; height: 30px; background: red; left: 10px; } 

.inpdiv { position: relative; margin-top: 6px; margin-left: 7px; background: #E2E6FF; border-radius: 3px; margin-bottom: 5px; display inline-block; float: left; margin-right: 3px; } 

.inpdiv span.content { position: relative; top: 1px; left: 2px; padding: 2px 5px 6px 2px; font-size: 0.9em; display: inline-block; font-family: cursive,"Comic Sans";} 

.inpdiv span.cancel { display: inline-block; border-radius: 3px; position: relative; top: 5px; margin: 3px 3px 3px 4px; height: 12px; width:12px; background: #bdbbae; cursor: pointer; } 

.letter { position: absolute; display: inline-block; right: 4.4px; top: 4.7px; cursor: pointer; FONT-FAMILY: SANS-SERIF; FONT-SIZE: 0.9EM; } 

div.friends { width: 400px; position: relative; overflow: hidden; border: 1px solid #4496e7; border-radius: 5px; cursor: text; height: 35px; height: auto !important; min-height: 35px; left: 5px; } 
div.friends2 { margin-top: 10px; } 

div.friendsc { position: relative; top: 100px; left: 350px; width: 410px; padding: 10px 0px; height: auto !important; height: 80px; min-height: 80px; background: green;} 

div.clear { clear: both; width: 100%; height: 10px; } 

button { position: absolute; top: 300px; left: 450px; } 

input { position: relative; margin: 9px 0px 10px 10px; border: 0px solid white; float: left; max-width: 382px; } 

div#outerfilter { width: 900px; background: grey; position: relative; min-height: 400px; max-height: 500px; margin:auto; top: 10px; overflow: auto; padding-bottom: 20px; } 
div#innerfilter { position: relative; top: 0px; left: 0px; width: 880px; min-height: 400px;background: #eaeaea; } 
.filtersection { position: relative; float: left; width: 440px; min-height: 400px; height: auto !important; } 
</style> 
<script type="text/javascript"> 
$(document).ready(function(){ 
(function($){ 

$.fn.autoGrowInput = function(o) { 

      o = $.extend({ 
       maxWidth: 1000, 
       minWidth: 0, 
       comfortZone: 70 
      }, o); 

      this.filter('input:text').each(function(){ 

       var minWidth = o.minWidth || $(this).width(), 
        val = '', 
        input = $(this), 
        testSubject = $('<tester/>').css({ 
         position: 'absolute', 
         top: -9999, 
         left: -9999, 
         width: 'auto', 
         fontSize: input.css('fontSize'), 
         fontFamily: input.css('fontFamily'), 
         fontWeight: input.css('fontWeight'), 
         letterSpacing: input.css('letterSpacing'), 
         whiteSpace: 'nowrap' 
        }), 
        check = function() { 

         if (val === (val = input.val())) {return;} 

         // Enter new content into testSubject 
         var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); 
         testSubject.html(escaped); 

         // Calculate new width + whether to change 
         var testerWidth = testSubject.width(), 
          newWidth = Math.min((testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth, o.maxWidth - 1), 
          currentWidth = input.width(), 
          isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth) 
               || (newWidth > minWidth && newWidth < o.maxWidth); 

         // Animate width 
         if (isValidWidthChange) { 
          input.width(newWidth); 
         } 

        }; 

       testSubject.insertAfter(input); 

       $(this).bind('keyup keydown blur update', check); 

      }); 

      return this; 

     }; 

    })(jQuery); 

arr = ["Soumyashree Chakraborty", "Payel","Jinia","Soujinia","Apoorva","Mona","Shamarpita","Pratik","Pranendra","Bhushan","Bijesh","Salma","Swift","Anushka","Radhe","Amol","Bardha","Sujata","Rohit","Amit","Anuradha","Amrita","Ajay","Sumil","Sachin","Sourav","Anmol","Britannia","Anamika","Priyanka"]; 
$("span.letter").live('click',function() { 
$(this).parent().parent().find("input").focus(); 
$(this).parent().remove(); 
    }); 

options = { 
      source: arr.slice(0,5), 
      minLength: 1, 
      select: function(event,ui) { 
      $('<span class = "inpdiv"><span class = "content">'+ui.item.value+'</span><span class = "cancel"></span><span class="letter">X</span></span>').replaceAll(this); 
      $("<input type='text' size='3' />").appendTo(curautocomp).focus(); 
      event.preventDefault(); 
      }, 
      focus: function(e,ui) { 
      e.preventDefault(); 
      }, 
      autoFocus: true, 
      delay: 0 
      }; 
$("input").live("focus", function (event) { 
curautocomp = $(this).parent(); 
$(this).autocomplete(options); 
$(this).autoGrowInput({ 
    comfortZone: 5, 
    minWidth: 15, 
    maxWidth: 382 
}); 
}); 
















}); 
</script> 
</head> 
<body> 
<div id = 'outerfilter'> 
<div id = 'innerfilter'> 
<div class = 'filtersection'> 
<div class="filtertab"><span class="filtertext">Filter by Forum</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
<div class="filtertab"><span class="filtertext">Not Asked by</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
<div class="filtertab"><span class="filtertext">Has No Answer by</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
<div class="filtertab"><span class="filtertext">No of Answers</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
</div> 
<div class = 'filtersection'> 
<div class="filtertab"><span class="filtertext">Asked by</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
<div class="filtertab"><span class="filtertext">Has Answer by</span><span class='arrow'></span></div> 
<br /> 
<div class = "friends"> 
<input type = "text" size = "2" value = "" /> 
</div> 
<div class="filtertab"><span class="filtertext">Filter by Date</span><span class='arrow'></span></div> 
<br /> 
<div id = 'datecontainer'> 
<div class = 'dateheaders fromheader'> 
<span class = 'spandatew'>Select a date</span> 
<div class = 'arrow'></div> 
</div> 
<div class = 'dateheaders toheader'> 
<span class = 'spandatew'>Select a date</span> 
<div class = 'arrow'></div> 
</div> 
<div id = 'diva1'></div> 
<div id = 'diva2'></div> 
</div> 
</div> 
<div class = 'clear'></div> 
</div> 
</div> 
</body> 
</html> 
+0

Deberías incluir alguna demostración o fuente que podamos ver :) – OptimusCrime

+0

El código fuente es enorme, hay muchos archivos CSS de donde se han obtenido diferentes estilos, ¡es muy difícil incluir todo eso! – SexyBeast

+0

¿El sitio está disponible en línea? Entiendo lo que intentas hacer, pero es difícil encontrar una solución sin ver cómo se combinan todas las cosas. Es como tratar de caminar sin piernas en la oscuridad total. – OptimusCrime

Respuesta

6

Usted querrá agregar una función open a sus opciones de autocompletar. A partir de ahí, puede ajustar los resultados basándose en su posición y altura actuales. Esto debería cerrar:

open: function(event, ui){ 
    var $input = $(event.target), 
     $results = $input.autocomplete("widget"), 
     top = $results.position().top, 
     height = $results.height(), 
     inputHeight = $input.height(), 
     newTop = top - height - inputHeight; 

    $results.css("top", newTop + "px"); 
} 
+1

¡Gracias! ¡Eso era exactamente lo que estaba buscando! Por supuesto, no quiero que el menú se muestre arriba siempre, así que agregué un cheque que si el 'offset(). Top + height()' de '$ results' excede la altura del documento, solo entonces debería ingresar el último línea de su código; de lo contrario, muestre el menú como lo hace naturalmente debajo. ¡Gracias de nuevo! – SexyBeast

+0

@Cupidvogel ¡Me alegra que haya funcionado para ti! Tuve que hacer algo muy similar a esto hace unas semanas, así que todavía estaba fresco en mi mente – lbstr

4

Esto pone juntos la solución de Ibstr y comentario de Cupidvogel mientras que la adición de detección de posición de desplazamiento ventana:

open: function (event, ui) { 
    var $input = $(event.target); 
    var $results = $input.autocomplete("widget"); 
    var scrollTop = $(window).scrollTop(); 
    var top = $results.position().top; 
    var height = $results.outerHeight(); 
    if (top + height > $(window).innerHeight() + scrollTop) { 
     newTop = top - height - $input.outerHeight(); 
     if (newTop > scrollTop) 
      $results.css("top", newTop + "px"); 
    } 
} 

Tenga en cuenta que estoy usando outerHeight vez de la altura porque quiero tener en consideración el grosor del borde también.

El autocompletado se orientará hacia la parte superior solo si hay espacio suficiente para que encaje completamente encima del cuadro de entrada.

Cuestiones relacionadas