I am creating a web form with a grid of inputs for creating objects in Django.
It seems that when the focus is on a drop down menu, the up and left arrows select the previous item and right / down arrows select the next item.
I would like to use the left / right arrows to move focus left or right on the grid (a bit like excel does). Can I disable the left / right arrows from changing the menu choice, (while keeping the functionality for the up / down arrows)?
Changing default behavior of controls is sometimes frustrating for users. But other times the user expect it works like excel like in your case :)
You can do something like this:
Key 37 = ← and key 39 is →.
e.preventDefault();
prevents the default behaviour of the key you pressed.Fiddle
While A1rPun's answer does what was asked, it does not work in Firefox. This is because of this Firefox bug, basically
event.preventDefault
doesn't prevent ← and → on<select>
nodes.Workaround
I made a workaround for this issue that can be used to improve A1rPun's answer to support Firefox.
Short version: store the
selectedIndex
and restore it back a frame later.Long version: store the
selectedIndex
, so that we can check later if it was changed by Firefox, usingsetTimeout
. You'll also want to store these values on'change'
event to fully support a dropdown. Also storescrollTop
to prevent Firefox from scrolling inside a multi-select. These are rendered as lists, not as dropdowns, causing Firefox to scroll down or up when the selected index was changed. In case of a multi-select you do not want to listen to it's'change'
event, this will have a reversed effect.Usage
You can use it like this:
JSFiddle
This expands on A1rPun's JSFiddle.
Ruud's Answer works but if you look closely or if you have a lot of code running in the event, you'll see the select value changing the next element and back to the original one.
Here's a solution that works on Firefox, and looks cleaner to me. Untested in other browsers.
The trick is simply to set the select as disabled in the keydown event, then to reenable it on the next frame with a setTimeout. The anonymous function will not run until all the code in the event handler has been processed, assuring that the select is not reenabled too early.
Here's the JSFiddle
IN regard to the answer of Ruud Lenders: works only if you have a single select in the form. If you have multiple select dropdowns then you can use the following version: