Can you please tell me how to move focus on to the next field when the enter key is press? I use the dform
plugin (which converts JSON to a form).
I Go
it looks the same, but I offer something simple, maybe helpful, and easy to remember, and this is what I use
html
<input placeholder="nama">
<input placeholder="email">
<input placeholder="password">
<button>MASUK<button>
js
$('INPUT').keydown( e => e.which === 13?$(e.target).next().focus():"");
Try the following JavaScript code that I modified from your fiddle. The default behavior of the select elements will be to expand on the keypress. The plus sign at the beginning of +$(this).attr("tabindex")
Converts the text attribute value to int.
$(".ui-dform-text").keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert($(this).attr("tabindex"));
var index = +$(this).attr("tabindex") + 1;
$("[tabindex='" + index +"']").focus();
}
});
The following code should do it; it uses the tabIndex
property. Let us know if that's is not acceptable:
$(function() {
$('input').on('keypress', function(e) {
e.which !== 13 || $('[tabIndex=' + (+this.tabIndex + 1) + ']')[0].focus();
});
});
The drop down already has enter key slated for opening the drop down.
JS FIDDLE DEMO
To be able to do something before moving to the next form element, you can use the following version:
$(function() {
$(document).on('keypress', function(e) {
var that = document.activeElement;
if( e.which == 13 ) {
e.preventDefault();
alert( "dd" );
$('[tabIndex=' + (+that.tabIndex + 1) + ']')[0].focus();
}
});
});
DEMO
This is mostly a joke but here is a Vanilla JS version using the newest APIs as long as you have a modern browser, it should be bullet proof
Here's what's happening:
And just like that you have some really unreadable code that is mostly parenthesis and arrow functions :)
// NodeList of applicable inputs, select, button
let NodesArray = document.querySelectorAll(`
#form input:not([disabled])[type]:not([type=\"hidden\"]),
#form select:not([disabled]),
#form button:not([disabled])[type=\"submit\"]
`);
// Spread the array to an object so we can load the next node without
// keeping track of indexes (barf)
(NodesObject => {
// Node and NextNode are Elements.
// You can update and get data if you want
Object.keys(NodesObject).forEach(i => (({ Node, NextNode }) => {
// Break if we dont have a NextNode
if (NextNode === false) return;
Node.addEventListener('keypress', KeyboardEvent => {
// Only continue if event.key was "Enter"
if (KeyboardEvent.key !== "Enter") return;
// Dont submit, thx
KeyboardEvent.preventDefault();
// Do the thing
NextNode.focus();
// Not all elements have a select method
if (typeof NextNode.select === 'function') NextNode.select();
});
})({
Node: NodesObject[i],
NextNode: NodesObject[(parseInt(i) + 1)] ?? false
}));
})({ ...NodesArray });
It fails because this
is the document
in your code.
You want to use the index of the currently focused item (document.activeElement
), or if you use delegated events you can make sure this
is the current item.
This final version works whether there are tabindexes
or not. It also wraps around:
They both use a custom jQuery selector that I add called :focusable
to select all focusable element (including links):
// register jQuery extension
jQuery.extend(jQuery.expr[':'], {
focusable: function (el, index, selector) {
return $(el).is('a, button, :input, [tabindex]');
}
});
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
// Get all focusable elements on the page
var $canfocus = $(':focusable');
var index = $canfocus.index(this) + 1;
if (index >= $canfocus.length) index = 0;
$canfocus.eq(index).focus();
}
});
You can use the same custom selector in the event handler if you like. Then it will even work on anchor links (if you change the event to keydown instead of keypress):
$(document).on('keydown', ':focusable', function (e) {
This also uses a delegated on
, listening for the keydown
event on the document
. It then applies the jQuery selector, it then applies the function to any matching element that caused the event. This is much more efficient as it only applies the selector at event time (rather than apply multiple event handler to each DOM matching element).
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
//alert("dd")
var index = $('.ui-dform-text').index(document.activeElement) + 1;
$('.ui-dform-text').eq(index).focus();
}
});
*Note: alerts can interfere with focus
, so use console.log
for output like that and view in most browser's debug window (like Chrome's F12 debugging tools).
This one wraps back to the first item from the last and also works on selects (the default behavior is blocked, so you can only use space to open or up/down to select options.
$('input,select').on('keypress', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
On the top-level div
, add onKeyDown={this.onKeyDown.bind(this)}
and add the following method (ES6) to the same class as the div
:
onKeyDown(event) {
if (event.keyCode === 13) {
event.preventDefault()
const inputs =
Array.prototype.slice.call(document.querySelectorAll("input"))
const index =
(inputs.indexOf(document.activeElement) + 1) % inputs.length
const input = inputs[index]
input.focus()
input.select()
}
}