How to move focus on next field when enter is pressed? - javascript

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 Googled it, but this not working. Why doesn't my focus move on to the next field?
JSFiddle: http://jsfiddle.net/5WkVW/1/
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert("dd")
var index = $('.ui-dform-text').index(this) + 1;
$('.ui-dform-text').eq(index).focus();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<form id="testSuiteConfigurationform" name="testSuiteConfigurationform" method="post" class="ui-dform-form" novalidate="novalidate">
<label class="ui-dform-label">
<h3>Configuration Parameters</h3>
</label>
<div class="ui-dform-div inputDiv">
<fieldset class="ui-dform-fieldset">
<input type="text" id="totalRetryCount" name="totalRetryCount" tabindex="1" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRetryCount')" class="ui-dform-text valid">
<legend class="ui-dform-legend">Total Retry Count</legend>
<label for="totalRetryCount" class="checked">✔</label>
</fieldset>
<fieldset class="ui-dform-fieldset">
<input type="text" id="totalRepeatCount" name="totalRepeatCount" tabindex="2" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRepeatCount')" class="ui-dform-text">
<legend class="ui-dform-legend">Total Repeat Count</legend>
</fieldset>
<fieldset class="ui-dform-fieldset">
<select id="summaryReportRequired" name="summaryReportRequired" tabindex="3" onblur="validateElement('Configuration', 'testSuiteConfigurationform','summaryReportRequired')" class="ui-dform-select">
<option class="ui-dform-option" value="true">true</option>
<option class="ui-dform-option" value="false">false</option>
</select>
<legend class="ui-dform-legend">Summary Report Required</legend>
</fieldset>
<fieldset class="ui-dform-fieldset">
<select id="postConditionExecution" name="postConditionExecution" tabindex="4" onblur="validateElement('Configuration', 'testSuiteConfigurationform','postConditionExecution')" class="ui-dform-select">
<option class="ui-dform-option" value="ALWAYS">ALWAYS</option>
<option class="ui-dform-option" value="ON_SUCCESS">ON_SUCCESS</option>
</select>
<legend class="ui-dform-legend">Post Condition Execution</legend>
</fieldset>
</div>
</form>
*Note (from comments): It also needs to work on pages that do not have tabindex values set

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:
JSFiddle 1: http://jsfiddle.net/TrueBlueAussie/5WkVW/11/
JSFiddle 2: http://jsfiddle.net/TrueBlueAussie/5WkVW/12/
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):
e.g.
$(document).on('keydown', ':focusable', function (e) {
Example with link: http://jsfiddle.net/5WkVW/15/
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).
Old versions below:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5WkVW/3/
$(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).
Update: http://jsfiddle.net/TrueBlueAussie/5WkVW/4/
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();
}
});
Requested "document" version: http://jsfiddle.net/TrueBlueAussie/5WkVW/5/
$(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();
}
});

I've created a non-jQuery version. So only pure Javascript;
https://jsfiddle.net/mm0uctuv/2/
Javascript:
var inputs = document.querySelectorAll("input,select");
for (var i = 0 ; i < inputs.length; i++) {
inputs[i].addEventListener("keypress", function(e){
if (e.which == 13) {
e.preventDefault();
var nextInput = document.querySelectorAll('[tabIndex="' + (this.tabIndex + 1) + '"]');
if (nextInput.length === 0) {
nextInput = document.querySelectorAll('[tabIndex="1"]');
}
nextInput[0].focus();
}
})
}
HTML:
<form>
Field 1: <input type="text" tabindex="1"><br>
Field 3: <input type="text" tabindex="3"><br>
Field 2: <input type="text" tabindex="2">
</form>

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()
}
}

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

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();
}
});

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:
Select Elements, inputs, etc... (excluding disabled, hidden, etc...)
Using the spread syntax, convert array (NodeList) to an object (here it's NodeObject)
Loop through the Objects aka Elements aka Nodes
Each iteration will pass the current element (Node) and the next element (NextNode) to an arrow function.
Continue if NextNode is an element
Then add a keypress event to the current element
Inside the event:
Continue only if the enter key was pressed (using e.key NOT e.keyCode or e.which -- which are deprecated)
Stop the Form from being submitted
Focus the next element
If we can, Select the text in the next node
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 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():"");

// This will work; add this code in your on ready function and define your parent element which includes child elements to be focused.
const mainDiv = document.getElementById(`auto-focuser`); //here your parent element you need to focus
const keyDownEvent = (event) => {
if (event.key === "Enter") {
if (event.target.tagName === "TEXTAREA" && (event.target.innerHTML !== "" && event.target.innerHTML.substr(-1) !== "\n"))
return;
if (event.target.attributes.tabindex) {
const nextElm = mainDiv.querySelectorAll(`[tabindex='${parseInt(event.target.attributes.tabindex.value) + 1}']`).item(0)
if (nextElm) {
nextElm.focus()
if (nextElm.tagName === "INPUT" || nextElm.tagName === "TEXTAREA") {
nextElm.select()
nextElm.selectionStart = nextElm.selectionEnd = nextElm.value.length;
}
event.preventDefault()
}
}
}
}
mainDiv?.addEventListener('keydown', keyDownEvent);

1.first = you should put 'textbox' on your class name in input
2.second = put specific id for each input
then write this code for select that element and go to next element.
I select each element by each id and put next() function on keypress of every input.
function next(event,elem){
if ( event.keyCode == 13)
{
var list = document.getElementsByClassName("textbox");
for (var i=0 ; i<list.length ; i++)
{
if (elem.id == list[i].id)
{
var index = i + 1;
list[index].focus();
}
}
}
}
event args use for keybord press//
elem args use for element that we press eneter

Related

How to detect focus on link elements and form input fields when activated with Tab key?

I want to detect when user focuses a link or input field by pressing the Tab key. Does anyone know of a way to do this? I have tried using the onFocus event, but it does not seem to work.
(I am not using jQuery, and I want to detect focus on links as well, so the similar question 16144611 is not the same as this one.)
By combining keyUp and document.activeElement we can see if an element is currently focused.
We then need to look for the Tab key on keyup and you have a reasonable start at a solution.
const els = document.querySelectorAll('a, input');
window.addEventListener('keyup', function(e){
// check the key code
const code = (e.keyCode ? e.keyCode : e.which);
if(code == 9 && els.length){
checkFocus();
}
});
function checkFocus(){
// loop all elements (within our selector at the start) and see if they match the document.activeElement
for (const el of els) {
if(document.activeElement == el){
console.log("focused tag:" + el.tagName);
}
}
}
<button>Click me for focus, I am not checked</button>
Focused Link
<label for="input1">I am also reported</label>
<input id="input1">
<button>Another button not announced</button>
Note that if you only ever want to check for links and inputs only a more efficient way to check would be:
const els = ['A', 'INPUT'];
window.addEventListener('keyup', function(e){
// check the key code
const code = (e.keyCode ? e.keyCode : e.which);
if(code == 9 && els.length){
checkFocus();
}
});
function checkFocus(){
// by checking the tagName we only have to do 2 loops no matter how many links or inputs there are on a page, which is far more efficient. The downside is it will check **every** link and input on the page. You would access the element with document.activeElelemnt instead if you need to know which item was focused.
for (const el of els) {
if(document.activeElement.tagName == el){
console.log("focused tag:" + document.activeElement.tagName);
}
}
}
<button>Click me for focus, I am not checked</button>
Focused Link
<label for="input1">I am also reported</label>
<input id="input1">
<button>Another button not announced</button>

How to remove/disable submit on appendTo Elements?

I've created a function to focus the next input with the enter key and disabled the submit on the form. It works fine but when I add an input field with the appendTo function it will reactivate the submit function on my form. I want to focus the input fields with the enter key and not with tab key.
Here is my function:
$('input').keydown(function (e) {
if (e.which === 13) {
var index = $('input').index(this) + 1;
$('input').eq(index).focus().val("");
return false;
}
});
And my appendTo function
var inputs = $('<input type="text" name="inputBasic[]" value="" class="form-control" />');
inputs.appendTo($("#dc_step_inputs"));
How can I remove the submit function when I add dynamical input field?
Thanks you for an answer!
You are binding your keydown event handler to a static set of elements (which does not include any elements added dynamically after your event handler has been attached), use delegation to bind to any elements that show up under your form:
$('#parent-form-id').on('keydown', 'input', function(e){
if (e.which === 13) {
var index = $('input').index(this) + 1;
$('input').eq(index).focus().val("");
return false;
}
});
$('input') only affects the elements that exist at the time this function runs.
You need to run the same script on the inserted element(s) too:
var inputs = $('<input type="text" name="inputBasic[]" value="" class="form-control" />');
inputs.appendTo($("#dc_step_inputs"));
inputs.keydown(function (e) {
if (e.which === 13) {
var index = $('input').index(this) + 1;
$('input').eq(index).focus().val("");
return false;
}
});
you can name your key down function
$('input').keydown(keydown);
function keydown(){
if (e.which === 13) {
var index = $('input').index(this) + 1;
$('input').eq(index).focus().val("");
return false;
}
and when you create a new input, give it an id, like this:
var inputs = $('<input id="newInput" type="text" name="inputBasic[]" value="" class="form-control" />');
inputs.appendTo($("#dc_step_inputs"));
and then
$('#newInput').keyDown(keyDown);
As has already been mentioned, when you add an event listener to a DOM element in JavaScript, you set it again the element itself, rather than a selector, or a given collection of elements.
One way around this, is to add an event listener to a common parent of all the elements for which you wish your event to be triggered against. This process is called Event Delegation. Fortunately, in jQuery this is very simple, using the following syntax:
$(<parent_selector>).on(<event>, <child_selector>, <fn>);
From the example you provided this might look something like (presuming you only want to target inputs within #dc_step_inputs):
$("#dc_step_inputs").on("keydown", ":input", function(e) {
if (e.which === 13) {
var index = $('input').index(this) + 1;
$('input').eq(index).focus().val("");
e.preventDefault(); // Note, this is preferred to return False
}
});

How to stay DRY - multiple inputs that trigger the same function on keypress?

This is the code that is working (but repetitive). I tried to replace the "getElementById" part with "getElementsByClassName", adding a class to the elements - but that didn't do it for me. Right now I have this anonymous function repeated once for each ID:
document.getElementById("gasCost").onkeypress = function(e) {
if(e.keyCode == 13) {
goButton();
}
}
HTML:
<input placeholder="How far are you going? (miles)" id="distance">
<input placeholder="How many MPG does your car get?" id="mileage">
<input placeholder="What's the average cost of gas?" id="gasCost">
Is it possible to define the function prior & call it to each ID? Is it possible to do it differently with classes? I'm open to all suggestions, but I'd prefer not to be using jQuery.
If you wanted to use classes you could do something like this:
function keyHandler(e) {
if(e.keyCode == 13) {
goButton();
}
}
var elements = document.getElementsByClassName("yourclasshere");
for (var i = 0; i < elements.length; i++)
elements[i].onkeypress = keyHandler;
(getElementsByClassName() returns a list, so you have to loop over each element in the list and bind a handler to them individually.)
Alternatively you could bind a single handler to a parent element that contains all of your inputs (perhaps to a form element?):
document.getElementById("someContainer").onkeypress = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
if (e.keyCode === 13 && e.target.tagName === "INPUT") {
goButton();
}
};
Demo: http://jsfiddle.net/9U9nn/
This works because the key events "bubble up" from the source element (your input) through all containers until they reach the document. (So, worst case, you could bind the handler directly to the document.) You can tell which element the event originated with by checking the event.target (or event.srcElement for older IE).
function submitOnEnter(e) {
if(e.keyCode == 13) {
goButton();
}
}
document.getElementById("gasCost").onkeypress = submitOnEnter;
document.getElementById("mileage").onkeypress = submitOnEnter;
Note that this is already the default behavior in HTML forms: pressing enter submits the form.

select multiple rows using control and shift key

Demo
<table id="tableStudent" border="1">
<thead>
<tr><th>ID</th><th>Name</th> <th>Class</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>John</td><td>4th</td></tr>
<tr><td>2</td><td>Jack</td><td>5th</td></tr>
<tr><td>3</td><td>Michel</td><td>6th</td></tr>
<tr><td>4</td><td>Mike</td><td>7th</td></tr>
<tr><td>5</td><td>Yke</td><td>8th</td></tr>
<tr><td>6</td><td>4ke</td><td>9th</td></tr>
<tr><td>7</td><td>7ke</td><td>10th</td></tr>
</tbody>
</table>
$('tr').on('click',function(e)
{
var objTR=$(this);
});
I have to select multiple rows using control key.
And then store Student ID in array.
How should i do using jquery Click event.
If you only want the cells to light up when the control key is pressed, this code does the trick:
var studendIds = [];
$(window).on('keydown',(function()
{
var target = $('tr'),
root = $(window),
clickCb = function(e)
{
if (!$(this).hasClass('ui-selected'))
{
$(this).addClass('ui-selected');
//add id to array
studentIds.push(+(this.cells[0].innerHTML))
}
else
{
$(this).removeClass('ui-selected');
for(var i=0;i<studentIds.length;i++)
{
if (studentIds[i] === +(this.cells[0].innerHTML))
{//remove id from array
delete studentIds[i];
break;
}
}
}
},
upCb = function(e)
{
target.off('click',clickCb);
root.on('keydown',downCb);
root.off('keyup',upCb);
},
downCb = function(e)
{
if (e.which === 17 || e.which === 16)
{//17 is ctrl, 16 is shift
root.off('keydown',downCb);
root.on('keyup',upCb);
target.on('click',clickCb);
}
};
return downCb;
}()));
Fiddle demo.
What this code does, essentially, is listen for a keydown event. If that key is the ctrl key (code 17), a click listener is attached, that will set/unset the ui-selected class if a particular row is clicked. The handler also detaches the keydown listener itself and attaches a keyup listener that sets up the event listeners back to their original states once the ctrl key is released.
Meanwhile, another listener is attached, that picks up on the keyup event. If the key (ctrl) is released, the click listener is removed, and the keydown event listener is restored.
As I said in the comments, though the code above does keep track of which ids are selected, I'd personally not do that.
Whenever you need those ids (probably on form submission, or to perform an ajax request), seeing as you have those rows marked usign a class, I'd just do this:
function assumingAjaxFunction()
{
var data = {some: 'boring', stuff: 'you might send', ids: []};
$('.ui-selected > td:first').each(function()
{
data.ids.push($(this).text());
});
console.log(data.ids);//array of ids
}
VanillaJS fiddle with shift-select support
and the code to go with it:
window.addEventListener('load',function load()
{
'use strict';
var tbl = document.getElementById('tableStudent');
window.addEventListener('keydown',(function()
{
var expr = /\bui\-selected\b/i,
key, prev,
clickCb = function(e)
{
e = e || window.event;
var i, target = (function(elem)
{//get the row element, in case user clicked on cell
if (elem.tagName.toLowerCase() === 'th')
{//head shouldn't be clickable
return elem;
}
while(elem !== tbl)
{//if elem is tbl, we can't determine which row was clicked anyway
if (elem.tagName.toLowerCase() === 'tr')
{//row found, break
break;
}
elem = elem.parentNode;//if td clicked, goto parent (ie tr)
}
return elem;
}(e.target || e.srcElement));
if (target.tagName.toLowerCase() !== 'tr')
{//either head, table or something else was clicked
return e;//stop handler
}
if (expr.test(target.className))
{//if row WAS selected, unselect it
target.className = target.className.replace(expr, '');
}
else
{//target was not selected
target.className += ' ui-selected';//set class
}
if (key === 17)
{//ctrl-key was pressed, so end handler here
return e;
}
//key === 16 here, handle shift event
if (prev === undefined)
{//first click, set previous and return
prev = target;
return e;
}
for(i=1;i<tbl.rows.length;i++)
{//start at 1, because head is ignored
if (tbl.rows[i] === target)
{//select from bottom to top
break;
}
if (tbl.rows[i] === prev)
{//top to bottom
prev = target;//prev is bottom row to select
break;
}
}
for(i;i<tbl.rows.length;i++)
{
if (!expr.test(tbl.rows[i].className))
{//if cel is not selected yet, select it
tbl.rows[i].className += 'ui-selected';
}
if (tbl.rows[i] === prev)
{//we've reached the previous cell, we're done
break;
}
}
},
upCb = function(e)
{
prev = undefined;//clear prev reference, if set
window.addEventListener('keydown',downCb,false);//restore keydown listener
tbl.removeEventListener('click',clickCb, false);//remove click
window.removeEventListener('keyup',upCb,false);//and keyup listeners
},
downCb = function(e)
{//this is the actual event handler
e= e || window.event;
key = e.which || e.keyCode;//which key was pressed
if (key === 16 || key === 17)
{//ctrl or shift:
window.removeEventListener('keydown',downCb,false);//ignore other keydown events
tbl.addEventListener('click',clickCb,false);//listen for clicks
window.addEventListener('keyup', upCb, false);//register when key is released
}
};
return downCb;//return handled
}()), false);
window.removeEventListener('load',load,false);
}, false);
This code is close to copy-paste ready, so please, at least give it a chance. Check the fiddle, it works fine for me. It passes JSlint in with fairly strict settings, too (/*jslint browser: true, white: true */), so it's safe to say this code isn't that bad. Yes it may look somewhat complicated. But a quick read-up about how event delegation works will soon turn out that delegating an event is easier than you think
This code also heavily uses closures, a powerful concept which, in essence isn't really that hard to understand either, this linked answer uses images that came from this article: JavaScript closures explained. It's a fairly easy read, but it does a great job. After you've read this, you'll see closures as essential, easy, powerful and undervalued constructs, promise
First of all, define some classes which will indicate that you have selected a table row:
tr.selected, tr.selected td {
background: #ffc; /* light-red variant */
}
Then write this jQuery event handler:
$('table#tableStudent').on('click', 'tr', function() {
if($(this).hasClass('selected')) {
// this accours during the second click - unselecting the row
$(this).removeClass('selected');
} else {
// here you are selecting a row, adding a new class "selected" into <tr> element.
// you can reverse the IF condition to get this one up above, and the unselecting case down.
$(this).addClass('selected');
}
});
In this way you have the expirence that you have selected a row. If you have a column which contains a checkbox, or something similar, you might want to do that logic inside the event listener I provided you above.
This might help DEMO:
function bindMultipleSelect(element){
var self = this;
var isCtrlDown = false;
element.on('click', 'tr', function(){
var tr = $(this);
if(!isCtrlDown)
return;
tr.toggleClass('ui-selected')
})
$(document).on('keydown', function(e){
isCtrlDown = (e.which === 17)
});
$(document).on('keyup', function(e){
isCtrlDown = !(e.which === 17)
});
self.getSelectedRows = function(){
var arr = [];
element.find('.ui-selected').each(function(){
arr.push($(this).find('td').eq(0).text())
})
return arr;
}
return self;
}
window.myElement = bindMultipleSelect($('#tableStudent'))

prepare to focus first active element in a container

I have a container on a page that should be prepared for focusing, i.e. when user pressed TAB button, the first active element in the container must be focused.
The simplest way I have thought so far is to find the last active element before the container, focus it and then blur it. Will it work? Is there a simpler way? How to find the last active element before the container (cross-browser)?
I do not want to change tabbed elements order, I just want to define the next element that will be selected.
Please use raw javascript, not frameworks.
The only thing I can think of is looping over the container child nodes and try focusing them until you succeed:
<script type="text/javascript">
document.onkeyup = function (e) {
if (!e)
e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
FocusFirst(document.getElementById("MyContainer"));
}
}
function FocusFirst(element) {
try {
element.focus();
}
catch(ex) {}
if (document.activeElement == element)
return true;
for (var i = 0; i < element.childNodes.length; i++) {
var oChild = element.childNodes[i];
if (FocusFirst(oChild))
return true;
}
return false;
}
</script>
Sample HTML tested with: (IE, Chrome)
<div id="MyContainer">
<div>hello</div>
<div><span><input type="text" /></span></div>
<div><input type="text" /></div>
</div>
This will focus the first input box of the container upon tab click.
Add a listener to the document and change focus onKeyUp. Remove the listener once tab has been pressed:
document.onkeyup = onKeyEvent;
function onKeyEvent (e) {
if (e.keyCode == 9) {
document.onkeyup = null;
document.getElementById ('whatever').focus();
}
}
Here is the solution that I've used finally.
I just create fake empty link in the beginnig of the container and focus it. The link will be removed when it lose focus.
function prefocusElement(node)
{
var fake = document.createElement("a");
fake.setAttribute("href", "#");
node.insertBefore(fake, node.firstChild);
fake.focus();
fake.addEventListener("blur", function(e) { node.removeChild(fake); }, false);
};

Categories