Prevent Jquery autocomplete options from closing after each selection
You can do something like this:first define a variable named readyToClose
and set it to be false
at the begining. And when you want to close your menu on next selection, set this variable to the true
. And also we should reimplement the close
method of JQuery UI.
Here I reimplemented the close
method of JQuery UI in your code, not in the source file! This is the same thing we do to render the list in custom way (e.g. http://jqueryui.com/demos/autocomplete/custom-data.html )
var readyToClose = false;$( "#tags" ).autocomplete({ minLength: 0, source: function( request, response ) { // delegate back to autocomplete, but extract the last term response( $.ui.autocomplete.filter( availableTags, extractLast( request.term ) ) ); }, focus: function() { // prevent value inserted on focus return false; }, select: function( event, ui ) { var terms = split( this.value ); // remove the current input terms.pop(); // add the selected item terms.push( ui.item.value ); // add placeholder to get the comma-and-space at the end terms.push( "" ); this.value = terms.join( ", " ); return false; }}).data( "autocomplete" ).close = function(e){ if(readyToClose) clearTimeout(this.closing), this.menu.element.is(":visible") && (this.menu.element.hide(), this.menu.deactivate(), this._trigger("close", e)); else return false; };
Note: In newer versions of jQuery (i.e. 1.9.0), replace "autocomplete" with "uiAutocomplete", as in:
$("#tags") .autocomplete({...}) .data("uiAutocomplete").close = ...
I know it's an old question that may no longer by relevant to the OP, but for the sake of completeness, a cleaner solution would be to extend
the autocomplete widget and overriding _close
, as well as extend
ing the event object in the select
event handler. This allows you to perform custom logic to determine whether the menu should be closed or not on a case by case (event by event) basis. See also http://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/
//override the autocomplete widgetjQuery.widget( "ui.autocomplete", jQuery.ui.autocomplete, { _close: function( event ) { if(event!== undefined && event.keepOpen===true) { //trigger new search with current value this.search( null, event ); return true; } //otherwise invoke the original return this._super( event ); }});$('ac').autocomplete( { ...custom options... select: function( event, ui ) { ...custom logic... if(menu should remain open) { //extend original event with special flag to keep dropdown open //the o-event continues to be passed through the chain of listeners //and will end up being processed during _close() jQuery.extend(event.originalEvent,{keepOpen:true}); //modify value as required jQuery(this).val(...); return false; //prevent selected value from being set, //i.e. keeping modified value above } } });
In the above jQuery.extend(event.originalEvent,{keepOpen:true}); is used to add a special keepOpen
property to event.originalEvent
. Since extend
modifies the original object (first argument), any subsequent use of the same event.originalEvent
will have this property available. Having read and stepped through the code it ends up being the same object that is referenced by event
in the _close
method.This code will break should this change in future, however, it is a lot simpler to maintain than the equivalent of what ingredient_15939 suggested 18 months ago.
The jQuery UI team thinks this is bad UX practice: http://forum.jquery.com/topic/enhanced-autocomplete-interest-in-getting-this-into-jqueryui#14737000001125152
So no built-in way to cancel it. You can try re-triggering the autocomplete after the select & close events. And probably you should cache the results array so that no new requests are made (if it's in Ajax mode).
Didn't get into the details though - I have convinced my UI designer that we don't need this for this version :)