jQuery UI Autocomplete: Determine if search window is open?
Asked Answered
P

2

14

I want to trigger a search in the onclick event of my input, but only if the search window isn't already open. Presently, I do this:

$(this).bind('click.ajaxselect', function(e) {
    if(!$(this).autocomplete('widget').is(':visible')) {
        $(this).autocomplete('search','');
    }
});

But I'm not overly fond of using the :visible selector because it searches up through all the parents as well. Is there some property I can check?

Dialog has this isOpen method, does autocomplete have something similar?

Parliamentarianism answered 23/7, 2011 at 22:24 Comment(0)
Y
21

Wouldn't be hard to set a simple variable:

$('.my_selector').bind('autocompleteopen', function(event, ui) {
    $(this).data('is_open',true);
});

$('.my_selector').bind('autocompleteclose', function(event, ui) {
    $(this).data('is_open',false);
});

Then your listener is easy:

$(this).bind('click.ajaxselect', function(e) {
    if(!$(this).data('is_open')) {
        $(this).autocomplete('search','');
    }
});
Yerxa answered 23/7, 2011 at 22:32 Comment(0)
C
2

I'm pretty late to the party, but I have an alternative, more performant solution to this. Since all that needs to be done is check the value of a CSS attribute, using a state variable and two event handlers to update said variable seems like a very heavy (and possibly brittle) solution. I feel that this style of coding is what makes parts of the javascript-driven web feel sluggish, even though we're provided with enormous computing power nowadays. But I digress.

You can test for the CSS display attribute like this:

$(this).bind('click.ajaxselect', function(e) {
    if($(this).autocomplete('widget')[0].style.display === 'none') {
        $(this).autocomplete('search','');
    }
});

For completeness, here's how to implement such a check in a "context-free" function:

function isSearchWindowOpen(id_of_input_element_the_autocomplete_is_bound_to) {
    return $('#' + id_of_input_element_the_autocomplete_is_bound_to)
        .data('ui-autocomplete')          /* jquery's internal wrapper object */
        .widget()[0]                      /* the actual search window DOM element */
        .style.display === 'block';       /* standard display CSS attribute */
}
Coble answered 12/2, 2016 at 12:12 Comment(5)
I don't think this is more elegant. You're relying on an implementation detail. There are other ways to show and hide things. Also, you have a potential escaping problem if id_of_input_element_the_autocomplete_is_bound_to contains any funny characters such as [ or ..Parliamentarianism
@mpen: Do you think .style.display is an implementation detail (suggesting it might change in the future?). In 2016? OK, maybe "elegant" is a subjective term, but it will definitely perform better. I'll edit that.Coble
@mpen: Anyway thanks for your input. I needed this exact functionality in a project just now, and I needed it in just a few places, so I know my inputs quite well. For the general case, you're right, weird characters without added escaping might screw something up.Coble
Yes. There are other ways to make something invisible. Off the top of my head: you can set opacity to 0, place it off the edge of the screen, or detach it from the DOM. It's also conceivable that W3C will add a proper show/hide feature in JS so that you don't have 'remember' the previous display property.Parliamentarianism
@mpen: Sure, there are (and of course, there will be even) more other ways, but this is (and I'm pretty sure it will remain) the basic form of toggling something in JS.Coble

© 2022 - 2024 — McMap. All rights reserved.