JQuery UI autocomplete - Hide list after hiting enter
Asked Answered
A

4

21

I have an input. I use the Jquery UI autocomplete to propose suggestions to the user. Lets image I have in my list 3 items: item1, item2, item3. What I am looking for is the list to be closed when the user hits enter. For instance if the user only enters "it", all 3 elements will be displayed. In that case if he hits enter I would like the list to be closed. I do not manage to comue up with a solution for that. Hope someone can help. Cheers. Marc.

http://jsfiddle.net/vXMDR/

My html:

<input id="search" type="input" />​

My js:

$(function() {

    var availableTags = [
            "item1","item2","item3"
        ];

    $("#search").autocomplete({
        source:availableTags,
        minLength: 0
        });
});​
Ax answered 7/3, 2012 at 13:28 Comment(0)
P
27
$(function() {

    var availableTags = [
            "item1","item2","item3"
        ];

    $("#search").autocomplete({
        source:availableTags,
        minLength: 0
    }).keyup(function (e) {
        if(e.which === 13) {
            $(".ui-menu-item").hide();
        }            
    });
});​

http://jsfiddle.net/vXMDR/2/

Phonetic answered 7/3, 2012 at 13:32 Comment(7)
In my real case scenario I already have a keyup event that filters a table on my page. That solution will be conflicting I guess... What is the e in the parenthisis?Ax
Hmm, I'm not sure why you would hide the item instead of just calling the explicit close method - docs.jquery.com/UI/Autocomplete#method-closeLied
OHHHHH ! I get it! e is the key code... 13 is the code for the enter key... is my understanding correct?Ax
Yes, exactly. Sorry for not responding sooner. Personally I would prefer using the close method as per @Lied answer.Phonetic
Note that this code will only hide the items in the auto completion list, but not hide the list itself. See @Lied for a better method.Oleum
This doens't work if you hit enter before the list is loaded. For example if using google maps API might take 2 seconds to load the list. Enter 'New York' and hit enter straight away, then the list is loaded after you have hidden it.Capability
Side note for this, not sure if its due to a newer version of Jquery-UI but I had to do this as $(".ui-helper-hidden-accessible").hide(); as it was a div within .ui-helper-hidden-accessibleTomboy
L
28

Here is the solution: http://jsfiddle.net/vXMDR/3/

Let me know if you have questions.

The magic is binding the autocomplete close method to keypress

 $("#search").keypress(function(e){ 
    if (!e) e = window.event;   
    if (e.keyCode == '13'){
      $('#search').autocomplete('close');
      return false;
    }
  });

UPDATE

$("#search").keypress(function(e){ binds keypress of the #search element to the function specified, passing in the event object. You could also write this as $("#search").on('keypress', function(e) {...

if (!e) e = window.event; ensures that if a valid event was not passed in, it sets e to the current window.event object.

Finally, if (e.keyCode == '13'){ tests that event keycode value is equal to the 'enter' key. For a list of valid keycodes, see here.

Here is the documentation for autocomplete close method - http://docs.jquery.com/UI/Autocomplete#method-close

Lied answered 7/3, 2012 at 13:34 Comment(3)
Ok but be careful with the accepted answer, hide() the elements is not the same or documented way of closing the autocomplete feature.Lied
Note that if it's in a form that is to be submitted, it's better to use this as a callback for the submit event of the form. $('#search').autocomplete({foo: bar}).closest('form').submit(function () { $('#search').autocomplete('close'); })Oleum
Like karim79's solution, this doens't work if you hit enter before the list is loaded. For example if using google maps API might take 2 seconds to load the list. Enter 'New York' and hit enter straight away, then the list is loaded after you have hidden it.Capability
P
27
$(function() {

    var availableTags = [
            "item1","item2","item3"
        ];

    $("#search").autocomplete({
        source:availableTags,
        minLength: 0
    }).keyup(function (e) {
        if(e.which === 13) {
            $(".ui-menu-item").hide();
        }            
    });
});​

http://jsfiddle.net/vXMDR/2/

Phonetic answered 7/3, 2012 at 13:32 Comment(7)
In my real case scenario I already have a keyup event that filters a table on my page. That solution will be conflicting I guess... What is the e in the parenthisis?Ax
Hmm, I'm not sure why you would hide the item instead of just calling the explicit close method - docs.jquery.com/UI/Autocomplete#method-closeLied
OHHHHH ! I get it! e is the key code... 13 is the code for the enter key... is my understanding correct?Ax
Yes, exactly. Sorry for not responding sooner. Personally I would prefer using the close method as per @Lied answer.Phonetic
Note that this code will only hide the items in the auto completion list, but not hide the list itself. See @Lied for a better method.Oleum
This doens't work if you hit enter before the list is loaded. For example if using google maps API might take 2 seconds to load the list. Enter 'New York' and hit enter straight away, then the list is loaded after you have hidden it.Capability
Side note for this, not sure if its due to a newer version of Jquery-UI but I had to do this as $(".ui-helper-hidden-accessible").hide(); as it was a div within .ui-helper-hidden-accessibleTomboy
C
0

I have modified the shanabus solution further, to allow for the time delay due to the callback.

http://jsfiddle.net/vXMDR/46/

This is a simple hack to store whether or not to display the autocomplete as a boolean. (I am using setTimeOut to create the scenario where there is a wait, it is the problem scenario not the solution.)

shouldComplete = true;

$("#search").autocomplete({
    source:function (request, response) {            
        setTimeout(
            function() {
                response(shouldComplete ? availableTags : null);
            },
            2000);
    }        
    ,
    minLength: 0
    });

Then when the enter button is pressed the flag is set to false. Any other key reactivates the flag.

$("#search").keypress(function(e){
    if (!e) e = window.event;   
    if (e.keyCode == '13'){
      $('#search').autocomplete('close');
        shouldComplete = false;
      return false;
    }
        else
        {
            shouldComplete = true;
        }
  });

It is possible to do this more elegantly I am sure, but this does solve the problem that the drop down might appear later on.

Capability answered 22/9, 2013 at 19:9 Comment(0)
V
-1

I ran into this issue and was not able to use the close() method because my autocomplete was being re-rendered on every load of a Backbone view. As such, a new autocomplete element was appended to the DOM and those stuck around even though the attached input element was getting blown away and recreated. The superfluous autocomplete elements were causing a few problems, but the worst was when the user pressed enter quickly enough, I would go through this sequence:

  1. User types text
  2. Request for suggestions begins execution
  3. The keypress event is triggered and executes a full text search (the user did not select something from autocomplete)
  4. The view reloads, the input field and other elements are re-rendered and a new autocomplete element is appended to the end of the DOM
  5. The original request for suggestions returns with a response and the suggestions are displayed.

Note that the suggestions displayed in step 5 are now tied to an autocomplete container that is no longer associated with my input field, so any events like pressing esc or clicking elsewhere on the screen will do nothing. The suggestions are stuck there until a full reload of the page occurs.

I ended up fixing this by storing the mainContainerId of the most recently created autocomplete element and removing it manually.

// during rendering
self.currentAutoComplete = $("#input-element").autocomplete({
  // set options
});

// later
if (this.currentAutoComplete) {
  $("#" + this.currentAutoComplete.mainContainerId).remove();
}
Validate answered 25/9, 2013 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.