user12882
user12882

Reputation: 4792

How to prevent closing the menu after a select?

I am using the jQuery Autocomplete widget and, inspired by this question in order to prevent closing the menu after select, I came up with this code:

$(#input_field).autocomplete({
  select   : function(event, ui) {

    // I also tried to run 'ui.item.data( "item.autocomplete" );' and it happens
    // the same thing (keep reading for more information).
    ui.item.option.selected = false;

  },
  ...
});

It works: the menu is not closed after select. However, I get the following error (in the Firebug console):

TypeError: ui.item.option is undefined

Even by using option.selected = false I get TypeError: option is undefined but it works as expected.

How can I solve that?

Upvotes: 3

Views: 3414

Answers (1)

Inferpse
Inferpse

Reputation: 4145

Unfortunately there's no option/method in current jQuery UI to handle this issue. The method you trying to use is for older versions of jQuery UI. In current version ui.item doesn't have proporties you trying to access. It only has {"label":"Java","value":"java"} inside, so that's why you have an error.

So to make it works you'll need some sort of hack. By inspecting jQuery UI source code I found that the easiest and most reliable way to do this is to override public close method with out custom method. It's really easy to do if you never need to close autocomplete:

$("#input_field").data('autocomplete').close = function() {};

But it's more complicated if you want to prevent closing only when item is selected with mouse:

// custom close method
(function(){
    var instance = $("#input_field").data('autocomplete');
    var origClose = instance.close, mouseFlag;

    // capture mouse events
    instance.menu.element.on('mousedown', function() {
        mouseFlag = true;
    });
    instance.close = function(e) {
        if(!mouseFlag) {
            // call original method if drop isn't closed by mouse
            origClose.apply(this, arguments);
        } else {
            // clean flag in setTimeout to avoid async events
            setTimeout(function(){
                mouseFlag = false;    
            },1);
        }
    }
}());​

Working JSFiddle

Upvotes: 1

Related Questions