JQuery autocomplete: how to force selection from list (keyboard)
Asked Answered
I

3

30

I am using JQuery UI autocomplete. Everything works as expected, but when I cycle with the up/down keys on the keyboard, I notice that the textbox is filled with items in the list as expected, but when I reach the end of the list and hit the down arrow one more time, the original term that I typed shows up, which basically allows the user to submit that entry.

My question: Is there a simple way to limit the selection to the items in the list, and remove the text in the input from the keyboard selection?

eg: if I have a list that contains {'Apples (AA)', 'Oranges (AAA)', 'Carrots (A)'}, if the user types 'app', I will automatically select the first item in the list ('Apples (AA)' here), but if the user presses the down arrow, 'app' shows up again in the textbox. How can I prevent that?

Thanks.

Interdict answered 27/7, 2012 at 4:5 Comment(3)
everytime the list is loaded it fires an event. Check if only one element is there then fire a click event to the item OR select the itemDifferentiation
I am always selecting the first item, but if I cycle thru the list using the keyboard, it shows the text that is in the textbox when I reach the end of the list. That's what I'm trying to prevent; basically, I want it to go back to the top of the list.Interdict
focus: function( event, ui ) { return false; }Differentiation
I
45

for force selection, you can use "change" event of Autocomplete

        var availableTags = [
            "ActionScript",
            "AppleScript"
        ];
        $("#tags").autocomplete({
            source: availableTags,
            change: function (event, ui) {
                if(!ui.item){
                    //http://api.jqueryui.com/autocomplete/#event-change -
                    // The item selected from the menu, if any. Otherwise the property is null
                    //so clear the item for force selection
                    $("#tags").val("");
                }

            }

        });
Indo answered 17/12, 2012 at 15:36 Comment(2)
The problem with this solution is that if someone types an illegal value into the field and then hits enter, the form is submitted with the illegal value. Still trying to find an elegant solution.Aesculapian
A possible solution is to remove type="submit" from the form and use jQuery to handle the click event on the submit button. In the end, server-side validation is the only thing you can really trust.Meetly
C
3

"Before focus is moved to an item (not selecting), ui.item refers to the focused item. The default action of focus is to replace the text field's value with the value of the focused item, though only if the focus event was triggered by a keyboard interaction. Canceling this event prevents the value from being updated, but does not prevent the menu item from being focused."

reference

On focus event:

focus: function(e, ui) {
    return false;
}
Califate answered 27/7, 2012 at 4:31 Comment(3)
Thanks. That prevents the keyboard navigation from populating the textbox, which bypasses the issue completely.Interdict
Well, after plugging this in, it solves part of the problem: the textbox no longer gets filled as I scroll with the arrow keys, but I'm still able to return the text in the textbox because the down key has an 'extra' slot that takes the focus out of the list. I need it to stay in the list exclusively. Any ideas?Interdict
Well, it's pretty difficult to show in jsfiddle due to the remote data being different from the passed data (no echo/json), but if you check the official jquery ui demo here: jqueryui.com/demos/autocomplete/#event-focus, if you type 'j' and then move the keys up and down, you'll pass the items in the list and then back to 'j' again. All I want to do is to prevent the 'j' from getting selected again, but instead, to go back to the top item 'Java' when I reach the bottom of the list.Interdict
A
2

Define a variable

var inFocus = false; 

Add the following events to your input

.on('focus', function() {
    inFocus = true;
})
.on('blur', function() {
    inFocus = false;
})

And attach a keydown event to the window

$(window)
    .keydown(function(e){
        if(e.keyCode == 13 && inFocus) {
            e.preventDefault();
        }
    });
Arterialize answered 24/6, 2014 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.