Oversteer
Oversteer

Reputation: 1828

jquery: arrow up/down keys in input tag change selected <select> item

I know there are hundreds of similar questions out there, and believe me when I say I've read a lot of them, but still the problem remains. If I have an input tag id="input1" and a select id="list1", I want the up/down arrow keys when pressed in the input component to move the selected option in the select list up or down accordingly.

I've set the value of the select tag so that the first item in the options list is selected, but this code doesn't work. I've checked that the bind for the keydown event is working ok, and I've tried setting focus temporarily to the select before triggering a keyup/keydown/keypress (all tried) event on the select component. Should I perhaps be focusing on the select component and then triggering a select or change event before triggering the keypress event?

        deflectEvent = function(event) {
            if((event.which == $.ui.keyCode.UP) ||
              (event.which == $.ui.keyCode.DOWN)) {
                //$('#list1').focus(); //.focus().click();
                $('#list1').trigger(event);
                //$('#input1').focus();
                return false;
            };
        }
        jQuery(function($){$('#input1').bind('keydown',deflectEvent)});

What I observe happening, is errrm, nothing. On IE8 I can press an arrow key and get the focus to shift using $('#list1').focus().focus().click(); but on chrome I can't even do this.

I'm aware of the jquery simulate plugin, although I've not managed to track down any examples of it's use. For example, if you simulate a keypress event, how do you specify which key was pressed?

Thanks.

Upvotes: 3

Views: 14638

Answers (2)

Sam Martin
Sam Martin

Reputation: 1248

Is this what you were after?

$(document).ready(function(){
deflectEvent = function(event) {
    var noOfListItems = $("#list1 > option").length-1;
    var curListItem = $("#list1")[0].selectedIndex;
    if(event.which == $.ui.keyCode.UP) {
         // Decrement the selection by one, unless that will be less than zero, then go to the last option
        var nextListitem = (curListItem-1 < 0) ? noOfListItems : curListItem-1;
        $("#list1")[0].selectedIndex = nextListitem;
    }
    if(event.which == $.ui.keyCode.DOWN){
         // Increment the selection by one, unless that will be more than the number of options, then go to the first option
        var nextListitem = (curListItem+1 > noOfListItems) ? 0 : curListItem+1;
        $("#list1")[0].selectedIndex = nextListitem;
    }
}

jQuery(function($){$('#input1').bind('keydown',deflectEvent)});
});

jsFiddle version

Upvotes: 7

Tumharyyaaden
Tumharyyaaden

Reputation: 2903

Here's working example, http://jsfiddle.net/FEnnA/ I tested it in IE 8.0 FF 3.5, 4, 5, 6 and Chrome (idk the version for Chrome).

HTML:

<input type="text" />
<input type="text" />
<input type="text" />

CSS:

input{
    display:block;
}

JS:

$('input').keydown(function(e){
    if (e.keyCode == 38) {
       $(this).prev().focus();   
    }    
    if (e.keyCode == 40) {
       $(this).next().focus();
    }
});

Upvotes: 2

Related Questions