jquery-ui autocomplete jquery-ui-autocomplete

jQuery UI Autocompletar desactivar seleccionar y cerrar eventos



jquery-ui autocomplete (5)

Estoy usando Autocompletar de jQuery UI de manera ligeramente diferente de lo que probablemente fue creado para hacer.

Básicamente, quiero mantener todas las mismas funciones, la única diferencia es que cuando aparece el cuadro de sugerencias, no oculto el cuadro de sugerencias cuando un usuario hace una selección y tampoco quiero que esa selección llene el cuadro de entrada que .autocomplete se adjunta a.

Por lo tanto, he estado leyendo la documentación de la interfaz de usuario de jQuery, y parece que hay una manera de deshabilitar los eventos Select: y Close: pero encuentro que la forma en que lo explicaron es muy confusa y, por lo tanto, esta es la razón por la que Estoy aquí pidiendo ayuda.

Mi jQuery

$( "#comment" ).autocomplete({ source: "comments.php", minLength: 4, // Attempt to remove click/select functionality - may be a better way to do this select: function( event, ui ) { return false; }, // Attempt to add custom Class to the open Suggestion box - may be a better way open : function (event, ui) { $(this).addClass("suggestion-box"); }, // Attempt to cancel the Close event, so when someone makes a selection, the box does not close close : function (event, ui) { return false; } });

Documentación oficial de jQuery UI

Se activa cuando se selecciona un elemento del menú; ui.item se refiere al elemento seleccionado. La acción predeterminada de seleccionar es reemplazar el valor del campo de texto con el valor del elemento seleccionado. La cancelación de este evento evita que el valor se actualice, pero no impide que el menú se cierre.

Ejemplos de código

Supply a callback function to handle the select event as an init option. $( ".selector" ).autocomplete({ select: function(event, ui) { ... } }); Bind to the select event by type: autocompleteselect. $( ".selector" ).bind( "autocompleteselect", function(event, ui) { ... });

Confusión

Lo que me confunde es que parecen sugerir que se elimine el .autocomplete y se reemplace por .bind ("autocompleteselect"), lo que deshabilitará el autocompletado por completo.

Muchas gracias por cualquier ayuda que puedas dar.


Inspirándome en la solución de Andrews, encontré una manera de mantener el autocompletado abierto en la selección con menos impacto en la funcionalidad principal:

var selected; //flag indicating a selection has taken place var $input = $("input").autocomplete({ source: [''Hello'', ''Goodbye'', ''Foo'', ''Bar''], select: function( event, ui ) { selected = true; } }); //Override close method - see link below for details (function(){ var originalCloseMethod = $input.data("autocomplete").close; $input.data("autocomplete").close = function(event) { if (!selected){ //close requested by someone else, let it pass originalCloseMethod.apply( this, arguments ); } selected = false; }; })();

Entonces, la idea es neutralizar el método de cierre cuando sea apropiado, como lo indica la bandera seleccionada. Tener la marca seleccionada en el espacio de nombres global probablemente no sea la mejor idea, pero eso es para que otra persona mejore en :-).

Más sobre los métodos de anulación


Ir con $ input.data ("autocompletar"). Menu.options.selected = function () {} provocó que el valor no se mantuviera después de seleccionar un elemento diferente (nuestra implementación se debe agregar al final. Es posible que solo sea necesario agregar e.preventDefault ( ) o devuelva falso antes de adjuntar el código). Así que acabo de hacer un cambio en el evento de cierre. Ejemplo: poner una variable externa y escribir un método propio es mejor, pero tampoco le gustó. Primero pensé en llamar al método manualmente pasando un parámetro cuando necesito cerrar autocompletar a mano. (en nuestra implementación, el cliente requería que la lista estuviera abierta al hacer clic en los elementos, pero cerrar cuando el mouse abandona el contenedor del cuadro de texto.

Así que simplemente adjunté autocompletar al contenedor de elementos del cuadro de texto y adjunté mouseenter y mouseleave. Para determinar si debería cerrarse, usé la variable personalizada jQuery (this) .data ("canClose"). Básicamente, lo que hace es simplemente volver a abrir el autocompletado con el método de búsqueda cuando la variable es ''falsa''.

Aquí está el código final:

element.autocomplete({ minLength:0, source: source, appendTo: element.parent(), close: function () { if (!jQuery(this).data("canClose")) { jQuery(this).autocomplete(''search'', ''''); } return false; } }); element.mouseenter(function () { element.data("canClose", false); jQuery(this).autocomplete(''search'', ''''); }); element.parent().mouseleave(function () { element.data("canClose", true); element.delay(2000).autocomplete("close"); });

Si necesita hacer el agregado en lugar de reemplazar el valor, agregue el controlador de selección en el constructor:

select: function (event, ui) { var text = element.text().trim(); if (text.length > 0 && !text.endsWith(",")) { text += ", "; } jQuery(this).text((text + ui.item.label)); jQuery(this).focus(); return false; }


La segunda sintaxis que utiliza .bind() es simplemente otra forma de adjuntar un controlador de eventos a los eventos personalizados de jQueryUI. Esto es exactamente lo mismo que definir el controlador de eventos dentro de las opciones del widget (usando select: function(event, ui) { } )

Imagínese si tuviera varios widgets de autocompletado en la página y quisiera ejecutar la misma función cuando alguno de ellos activara el evento "seleccionar", por ejemplo:

$(".autocomplete").bind("autocompleteselect", function(event, ui) { /* Will occur when any element with an autocomplete widget fires the * autocomplete select event. */ });

En cuanto a cancelar el evento select , tienes eso correcto. Sin embargo, cancelar el evento de close es un poco más difícil; parece que devolver falso desde el controlador de eventos no funcionará (el close se activa después de que el menú se haya cerrado). Podría realizar una pequeña piratería y simplemente reemplazar la función de select con la suya:

var $input = $("input").autocomplete({ source: [''Hello'', ''Goodbye'', ''Foo'', ''Bar''] }); $input.data("autocomplete").menu.options.selected = function(event, ui) { var item = ui.item.data( "item.autocomplete" ); $input.focus(); };

Aquí hay un ejemplo http://jsfiddle.net/ZGmyp/ de eso: http://jsfiddle.net/ZGmyp/

No estoy seguro de cuáles son las ramificaciones de anular el evento cercano, pero no parece que esté sucediendo nada loco en el simple ejemplo. Yo diría que este es un tipo de uso poco natural del widget, por lo que puede haber consecuencias inesperadas.


Probé las diversas ideas que otros han presentado aquí sin éxito.

Estoy usando Jquery 2.1.4 con UI 1.11.4 y así es como funcionó esto:

Javascript:

<script> var lookup_selectable = false; var lookup_term = ''''; $(function() { $( "#lookup" ).autocomplete({ source: "lookup_processor.php", minLength: 3, renderItem: function( ul, item ) { // This function is called for each item returned from the ''source:'' // It is up to you to ensure that a list item element is returned. // do whatever logic on the item data to determine if it should not be slectable.. //Example: // The backend "source" has handled the logic of what is selectable or not // and has set a ''selectable'' parameter that we can use if(item.selectable){ // return the item unchanged from autocompletes default behavior return $("<li></li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").appendTo(ul); }else{ // this item is not selectable so lets apply a class named ''item-disabled'' to give a visual queue. // We are also wrapping the label in a span instead of an anchor just to show that the item is still clickable, darn! return $(''<li class="ui-menu-item item-disabled"></li>'').data("item.autocomplete", item).append(''<span>''+item.label+''</span>'').appendTo(ul); } }, select: function( event, ui ) { // This item was clicked .. // save the item.clickable value to our own external variable // Note: We have to do this because the item object is not available in the ''close'' function :-( lookup_selectable = ui.item.selectable; // the item object is available inside the ui parameter // store the current search term lookup_term = $(''#lookup'').val(); // do any additional stuff based on the item selected, if needed... }, close: function(event, ui){ // This function fires after select: and after autocomplete has already "closed" everything. This is why event.preventDefault() won''t work. // ** ui is an empty object here so we have to use our own variable to check if the selected item is "selectable" or not.. if (! lookup_selectable){ // We need to undo what autocomplete has already done.. $(''#lookup'').val(lookup_term); // Restore the search term value $(''#''+event.currentTarget.id).show(); // Keep the selection window open // ta-da! To the end user, nothing changes when clicking on an item that was not selectable. } } }); }); </script>

CSS:

<style> li.ui-menu-item.item-disabled { text-decoration: none; line-height: 1.5; color: #ccc; } </style>

Fuente de fondo "lookup_processor.php":

<?php $search_results = array(); // ..do whatever to get the data for each item $item_data = getting_item_data(); foreach ($item_data as $data){ // The id, label, and value keys are the typical keys that autocomplete expects, but you can add ass many others as you want.. // For our example we are setting the ''selectable'' key to true or false based on some simple example logic $search_results[] = array( ''id''=>$data[''id''], ''label''=>$data[''label''], ''value''=>$data[''value''], ''selectable''=>$data[''some_thing_to_check'']>0?true:false, // This is the parameter our ''select:'' function is looking for ''send_it_all_if_you_want''=>json_encode($data)); // this is just an example of how you can send back anything you want ); } // send the results back to autocomplete echo json_encode($search_results); exit; ?>


Tomé una ruta ligeramente diferente para esto y me expandí en el fiddle de Andrew

El propósito es que siempre quise que el autocompletar se mostrara mientras que cierta entrada tenía un enfoque, lo que permite múltiples selecciones.

$("#myInput").autocomplete({ source: ["Test", "This", "Doesnt", "Close"], minLength: 0, select: function (event, ui) { // Add your own custom login to manipulate ui.item.label and add what you need the input field (and ui.item.value if required.) // We''ve customised how we want the select to "work" so prevent the default // of auto clearing the input. event.preventDefault(); }, close : function(event) { // We''re closing the autocomplete - check if the input still has focus... if ($("#myInput").is(":focus")) { // Prevent the auto complete from closing. event.preventDefault(); // Make sure we''re reshowing the autcomplete - since the input would have momentarily // lost focus when we selected an item. $("#myInput").autocomplete("search", "") } } }); $("#myInput").focus(function () { // We''re not taking any filtering into account for this example. $(this).autocomplete("search", "") });