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 pr
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 nodes.
I made a workaround for this issue that can be used to improve A1rPun's answer to support Firefox.
function ensurePreventDefault(select) {
var selectedIndex, scrollTop;
function saveState() {
selectedIndex = select.selectedIndex;
scrollTop = select.scrollTop;
}
saveState();
if (!select.multiple && !select.size) {
select.addEventListener('change', saveState);
}
// use setTimeout to wait a frame and see if the selected index was changed
setTimeout(function () {
select.removeEventListener('change', saveState);
if (select.selectedIndex !== selectedIndex) {
// Damn you, Firefox!
select.selectedIndex = selectedIndex;
select.scrollTop = scrollTop;
}
});
}
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, using setTimeout
. You'll also want to store these values on 'change'
event to fully support a dropdown. Also store scrollTop
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.
You can use it like this:
.addEventListener('keydown', function (event) {
switch (event.which || event.keyCode) {
case 37: // left arrow
case 39: // right arrow
event.preventDefault();
ensurePreventDefault(this);
break;
}
});
This expands on A1rPun's JSFiddle.