Enter key press behaves like a Tab in Javascript
Solution 1
I used the logic suggested by Andrew which is very effective. And this is my version:
$('body').on('keydown', 'input, select', function(e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
KeyboardEvent's keycode (i.e: e.keycode
) depreciation notice :- https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
Solution 2
The simplest vanilla JS snippet I came up with:
document.addEventListener('keydown', function (event) {
if (event.keyCode === 13 && event.target.nodeName === 'INPUT') {
var form = event.target.form;
var index = Array.prototype.indexOf.call(form, event.target);
form.elements[index + 1].focus();
event.preventDefault();
}
});
Works in IE 9+ and modern browsers.
Solution 3
Map [Enter] key to work like the [Tab] key
I've rewritten Andre Van Zuydam's answer, which didn't work for me, in jQuery. This caputures both Enter and Shift+Enter. Enter tabs forward, and Shift+Enter tabs back.
I've also rewritten the way self
is initialized by the current item in focus. The form is also selected that way. Here's the code:
// Map [Enter] key to work like the [Tab] key
// Daniel P. Clark 2014
// Catch the keydown for the entire document
$(document).keydown(function(e) {
// Set self as the current item in focus
var self = $(':focus'),
// Set the form by the current item in focus
form = self.parents('form:eq(0)'),
focusable;
// Array of Indexable/Tab-able items
focusable = form.find('input,a,select,button,textarea,div[contenteditable=true]').filter(':visible');
function enterKey(){
if (e.which === 13 && !self.is('textarea,div[contenteditable=true]')) { // [Enter] key
// If not a regular hyperlink/button/textarea
if ($.inArray(self, focusable) && (!self.is('a,button'))){
// Then prevent the default [Enter] key behaviour from submitting the form
e.preventDefault();
} // Otherwise follow the link/button as by design, or put new line in textarea
// Focus on the next item (either previous or next depending on shift)
focusable.eq(focusable.index(self) + (e.shiftKey ? -1 : 1)).focus();
return false;
}
}
// We need to capture the [Shift] key and check the [Enter] key either way.
if (e.shiftKey) { enterKey() } else { enterKey() }
});
The reason textarea
is included is because we "do" want to tab into it. Also, once in, we don't want to stop the default behavior of Enter from putting in a new line.
The reason a
and button
allow the default action, "and" still focus on the next item, is because they don't always load another page. There can be a trigger/effect on those such as an accordion or tabbed content. So once you trigger the default behavior, and the page does its special effect, you still want to go to the next item since your trigger may have well introduced it.
Solution 4
Thank you for the good script.
I have just added the shift event on the above function to go back between elements, I thought someone may need this.
$('body').on('keydown', 'input, select, textarea', function(e) {
var self = $(this)
, form = self.parents('form:eq(0)')
, focusable
, next
, prev
;
if (e.shiftKey) {
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button,textarea').filter(':visible');
prev = focusable.eq(focusable.index(this)-1);
if (prev.length) {
prev.focus();
} else {
form.submit();
}
}
}
else
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
Solution 5
This worked for me:
$(document).on('keydown', ':tabbable', function(e) {
if (e.key === "Enter") {
e.preventDefault();
var $canfocus = $(':tabbable:visible');
var index = $canfocus.index(document.activeElement) + 1;
if (index >= $canfocus.length) index = 0;
$canfocus.eq(index).focus();
}
});
Related videos on Youtube
Ross
Updated on July 05, 2022Comments
-
Ross almost 2 years
I'm looking to create a form where pressing the enter key causes focus to go to the "next" form element on the page. The solution I keep finding on the web is...
<body onkeydown="if(event.keyCode==13){event.keyCode=9; return event.keyCode}">
Unfortunately, that only seems to work in IE. So the real meat of this question is if anybody knows of a solution that works for FF and Chrome? Additionally, I'd rather not have to add onkeydown events to the form elements themselves, but if that's the only way, it will have to do.
This issue is similar to question 905222, but deserving of it's own question in my opinion.
Edit: also, I've seen people bring up the issue that this isn't good style, as it diverges from form behavior that users are used to. I agree! It's a client request :(
-
Ross almost 15 yearsNormally I would agree, but our app lets users set stuff like this separately for their own accounts, and the client is offering money for it, so I don't think we can justify holding our ground.
-
Joel Purra about 12 yearsShort and concise! Started off with something similar as well, but now I've expanded on it - see my answer (on this page) with PlusAsTab.
-
aimfeld almost 11 yearsI suggest removing
textarea
from the selector in the first line. In a textarea, you want to be able to start a new line using the enter key. -
Mike Bethany over 9 yearsI've found that pressing enter for submit is NOT expected and in fact is highly annoying. In fact in every single website I've ever built the client has asked me to change this behavior as it is unwanted. I blame someone [cough]Microsoft[/cough] that can't admit they made a bad choice for this continued behavior in the face of overwhelming evidence that it's not wanted.
-
AVProgrammer about 8 yearsWhat is the purpose of the last bit:
if (e.shiftKey) { enterKey() } else { enterKey() }
? Seems like it should just be:enterKey()
. -
6ft Dan about 8 years@AVProgrammer To have enter act like tab it needs to go in reverse if the shift key is held. The line you asked about allows the enter key to be checked for while the shift key is depressed.
-
SnakeDrak about 8 yearsI suggest ignore fields with
readonly
anddisabled
:filter(':visible:not([readonly]):enabled')
-
Vishal_Kotecha almost 8 yearsI know this is a very old thread but with this code, how do we allow default behavior of <input type="button"/> ? how to allow button to be clicked with enter key?
-
aruno over 7 yearsWas specifically looking for something to steal that considered invisible fields. Most other solutions I found don't. Thanks
-
Jeppe Andreasen over 6 yearsit doesn't make sense to check for e.shiftKey and call enterKey in both cases.
-
6ft Dan over 6 years@JeppeAndreasen If you want it to behave like tab then yes it does. Because Shift+Tab goes in the reverse direction.
-
Jeppe Andreasen over 6 yearsYoure performing the same action regardless if shift is pressed or not. So the if statement is not necessary, as avprogrammer has also pointed out
-
6ft Dan over 6 yearsAVProgrammer was asking, not stating. I've tested the code in my own browser and without the if statement it won't work when shift is held down.
-
Carles S almost 5 yearsCould you please provide with a small explanation of the code to make the answer more understandably ?
-
user11706828 almost 5 yearsfirstly you need to select all input fields in form and then you need to bind keypress event in every input fields , then you need to check whether enter keypress or not and when enter key is press in an input field you need to get index of this input field and add increment to index of it to find next input field and when you find next input field you need to focus on it....!
-
isherwood over 4 yearsThis doesn't seem to be working. The fiddle link is dead (and has been removed).
-
Mat Mannion almost 4 yearsThis will require jquery-ui for the tabbable selector
-
LittleTreeX over 3 yearsWhile this code might "work" for you, please take note that it is not correctly written, and as such, if you attempt to amend it in anyway, you are going to face problems. For ONE:
$.inArray(self, focusable)
returns the INDEX of the found element within the array, and -1 if it is not found. Thus,If ($.inArray(self, focusable))
will not function the way you expect, and will generally always pass. In fact, it does always pass because you cannot compare these jquery objects in this manner, and thus it always returns -1 ! -
Ali Ahmad Pasa about 3 yearsI have used your example there is a one issue for select2 field it reset the focus to first field. Any idea how to fix it?