Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a function when up/down arrows are used to move in a <select>

I have a drop down menu like this:

<select id="test">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>

If I want to run something whenever the user changes their selection, it's easy with jQuery's .change(). However, it is well known that this won't work if the user has the <select> active and is just moving through options with up/down arrows (or other methods of keyboard navigation).

This is a problem for my use case. I need an event to fire based on the selected value even when up/down arrows are used to view different options.

I am not the first person to have this problem. Here's a discussion of this issue which basically says you have to look for keypresses if you want to handle this scenario in all browsers. Other similar questions here have similar answers. But... it doesn't work, as I will illustrate below.

Seemingly the simplest way to fix this is to use jQuery's .keypress() to notice when the <select> is active and a key is pressed. Something like this:

<select id="test">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>

<div id="log">

<script>
  var log = $("#log");
  var select = $("#test");
  select.change(function () { log.append(select.val() + "<br>"); });
  select.keypress(function () { log.append(select.val() + "<br>");; });
</script>

You can try it out here.

I tested this in Chrome 25 (Ubuntu 12.10 and Windows XP), Firefox 19 (Ubuntu 12.10), and IE 7 (Windows XP), which are the only browsers I have immediately at hand.

My code works great in all of them except Firefox. In my example, click the drop down menu twice to select it with the menu closed, then press "down, down, down" (moving to 2, 3, and 4) and "up, up, up" (moving to 3, 2, and 1) and you'll see this output:

2
3
4
3
2
1

Great, perfect. But in Firefox, doing exactly the same thing outputs:

1
2
3
4
3
2

It's lagging by one entry. The outputted value is the previous one, not the current one. This is a problem.

Any ideas how to fix it?

like image 909
dumbmatter Avatar asked Mar 08 '13 19:03

dumbmatter


1 Answers

In FireFox change event is fired after kepress event, you can use keyup instead of keypress:

select.keyup(function () { 
    log.append(this.value + "<br>"); 
});

http://jsbin.com/ezalav/3

like image 57
undefined Avatar answered Oct 30 '22 15:10

undefined