2012-04-19 37 views
15

Estoy experimentando un comportamiento extraño con jquery ui autocomplete when using it to create a combobox. Cada vez que hago clic en la barra de desplazamiento para desplazarse por la lista de resultados Y luego hago clic en el botón de mi cuadro combinado para cerrar los resultados, la lista de resultados se cierra y luego se abre de nuevo. Espero que cierre el menú.Jquery UI autocompletar botón del cuadro combinado clic evento

Pasos para Repro

  1. open jsfiddle demo
  2. Tipo 'i' en el autocompletar o golpear el botón desplegable.
  3. Haga clic en la vertical de desplazamiento para desplazarse por los resultados
  4. Haga clic en el botón desplegable

script para crear Botón

this.button = $("<button type='button'>&nbsp;</button>") 
    .attr({ "tabIndex": -1, "title": "Show all items" }) 
    .insertAfter(input) 
    .button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }) 
    .removeClass("ui-corner-all") 
    .addClass("ui-corner-right ui-button-icon") 
    .click(function() { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 

     if (input.autocomplete("widget").is(":visible")) { 
      input.autocomplete("close"); 
      return; 
     } 

     // work around a bug (likely same cause as #5265) 
     $(this).blur(); 

     // pass empty string as value to search for, displaying all results 
     input.autocomplete("search", ""); 
     input.focus(); 
}); 

CSS (fuerza de resultados a largo menú para desplazarse)

.ui-autocomplete { 
    max-height: 100px; 
    overflow-y: auto; 
    /* prevent horizontal scrollbar */ 
    overflow-x: hidden; 
    /* add padding to account for vertical scrollbar */ 
    padding-right: 20px; 
} 
/* IE 6 doesn't support max-height 
* we use height instead, but this forces the menu to always be this tall 
*/ 
* html .ui-autocomplete { 
    height: 100px; 
} 

Mi solución podría ser cerrar el widget incluso si el foco se transfiere al propio widget y no al elemento de entrada?

¿Alguna idea de cómo modificar este código para que se comporte de esta manera?

+0

Podría dar el HTML, tal vez un jsFiddle? Sería mucho más fácil conseguirlo entonces. –

+0

No entiendo lo que estás tratando de lograr aquí .. [jsfiddle] (http://jsfiddle.net/vR9s2/2/) –

+0

¿Qué problema estás tratando de resolver? –

Respuesta

5

Sobre la base de los problemas con los diversos eventos de clic de ratón y para el widget automplete, se me ocurrió esto: jsFiddle example.

jQuery:

var input = $('#txtComplete'); 

var data = []; 
var isOpen = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      isOpen = true; 
     }, 
     select: function(event, ui) { 
      isOpen = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon").click(function(event) { 
     input.focus(); 
     if (isOpen) { 
      input.autocomplete("close"); 
      isOpen = false; 
     } else { 
      input.autocomplete("search", ""); 
      event.stopImmediatePropagation(); 
     } 
    }); 
} 
$(window).click(function() { 
    input.autocomplete("close"); 
    isOpen = false; 
}); 
$(function() { 
    _init(); 
    afterInit(); 
});​ 
+0

Pero en su código ... el cuadro combinado no puede hacer clic en la segunda vez. –

+0

@lakshmipriya - Sí, lo es. Funciona bien. – j08691

+0

lo siento ... funciona bien ... –

3

El problema se debe a un problema en la autocompletar de jquery ui. Hay una configuración de evento mousedown para cerrar el menú bajo ciertas condiciones. En una de las condiciones comprueba si el elemento que generó el mousedown es parte del widget de autocompletar. Si no, cierra el menú. Como está virando en el comportamiento del cuadro combinado y su botón no es parte del widget de autocompletar, al hacer clic en el botón se cierra el menú debido a este evento.

Puede ver la condición ofensiva con la razón por la cual está allí comenzando en la línea 205 en el autocomplete source on github. Probablemente valga la pena plantear el problema en los foros de jquery ui ya que su demo de combobox también tiene este error.

ACTUALIZACIÓN

Este evento de reemplazo se basa fuera de jquery-ui 1.8.18. Este evento ha cambiado y es muy probable que cambie de nuevo. Es posible que deba actualizar este código manualmente con cada versión si realiza esta ruta.

Puede asignar el evento mousedown a no cerrar el menú si fuera el botón combo que se ha hecho clic ejecutando el siguiente después de crear su autocompletar (jsfiddle demo).

var input = $('#combotextbox').autocomplete(/*options*/); 
input.data('autocomplete').menu.element.unbind('mousedown').mousedown(function(event) { 
     var self = input.data('autocomplete'); 
     event.preventDefault(); 
     // clicking on the scrollbar causes focus to shift to the body 
     // but we can't detect a mouseup or a click immediately afterward 
     // so we have to track the next mousedown and close the menu if 
     // the user clicks somewhere outside of the autocomplete 
     var menuElement = self.menu.element[0]; 
     if (!$(event.target).closest(".ui-menu-item").length) { 
      setTimeout(function() { 
       $(document).one('mousedown', function(event) { 
        var t = $(event.target); 
        if (event.target !== self.element[0] && event.target !== menuElement && !$.ui.contains(menuElement, event.target) && !t.hasClass('ui-combo-trigger') && !t.parent().hasClass('ui-combo-trigger')) { 
         self.close(); 
        } 
       }); 
      }, 1); 
     } 

     // use another timeout to make sure the blur-event-handler on the input was already triggered 
     setTimeout(function() { 
      clearTimeout(self.closing); 
     }, 13); 
    }); 

Esto elimina el evento MouseDown actual y después lo añade de nuevo con un control añadido para ver si el elemento que desencadenó el evento o su padre (botón de clic o se hace clic en ui-icono dentro del botón) tiene una clase ui-combo-trigger.

El código para crear su botón permanece relativamente sin cambios. Solo tenemos que agregar la nueva clase ui-combo-trigger.

var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon ui-combo-trigger").click(function(event) { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 
     if (input.autocomplete("widget").is(":visible")) { 
      input.autocomplete("close"); 

      return; 
     } 


     // work around a bug (likely same cause as #5265) 
     $(this).blur(); 

     // pass empty string as value to search for, displaying all results 
     input.autocomplete("search", ""); 
     input.focus(); 
     event.stopImmediatePropagation(); 
    }); 
1

Prueba este jsfiddle. Creo que te ayudaré.

var input = $('#txtComplete'); 

var data = []; 
var openCheck = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      openCheck = true; 
     }, 
     select: function(event, ui) { 
      openCheck = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon").click(function(event) { 
     if (openCheck) { 
      input.autocomplete("close"); 
      openCheck = false; 
     } else { 
      input.autocomplete("search", ""); 
     } 
    }); 
} 

$(function() { 
    _init(); 
    afterInit(); 
}); 
+0

Ya no puede usar las teclas de flecha para navegar por la lista. –

+0

Lo siento ... solo agregue input.focus(); hacer clic en evento ... funcionará ... –

0

Brian explicó el problema muy bien. Con jquery ui 11 se puede hacer algo como:

wasOpen = false; 
$button 
    .mousedown(function() { 
    wasOpen = input.autocomplete("widget").is(":visible"); 
    }) 
    .click(function() { 
     input.focus(); 

     // Close if already visible 
     if (wasOpen) { 
      return; 
     } 

ver ejemplo en http://jqueryui.com/autocomplete/#combobox

Cuestiones relacionadas