Is there a nice way to set a desktop-like tab order in a form with jquery? the form has four text inputs and two buttons; after the last button loses focus, I want the first text input to get focus and start tab order from the beginning (to 2nd tb, to 3rd tb...). I did this:
$('body').delegate('#second_button', 'blur', function() {
$('#first_input_text').focus();
});
but it only works in Opera. Chrome IE9, And Firefox do set focus on first text input but when user press tab again it goes to address bar instead of the second text input. I could set above binding to all elements in cycle but is there a more elegant solution?
You need to add a tabindex attribute to each form element - example :
<FORM action="..." method="post">
<P>
<INPUT tabindex="1" type="text" name="field1">
<INPUT tabindex="2" type="text" name="field2">
<INPUT tabindex="3" type="submit" name="submit">
</P>
</FORM>
Documentation here
Related
Whenever the tabkey is pressed without an active/focussed element, the first focussable element is selected (this is the general behaviour of the tab key. However, I dont want this in my application, since I want to focus on another element (not the first one).
I have tried setting event listeners for the tab key, but this only works if some element is already selected and not when no element is active.
Is there any way to listen to this 'initial tab event' when there are no active elements? In de code snippet you can see that the tab event only listens to the second tab, while it selects the first field after the first tab.
document.getElementById("form").addEventListener("keydown", function(e){
if(e.keyCode===9){
document.getElementById("demo").innerHTML = "Tab";
}
}
)
<div id="form">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
</div>
<p id="demo"></p>
I would go with TabIndex:
Adding tabindex="0" to an element, you can then access it with your keyboard key. Adding tabindex="-1" does not give access to that alement keyboard-based (however, you can access it to gain focus programmatically - with .focus() or with a click for example).
So if your keyboard-based behavior doesn't work because nothing is selected, force you application to select an element on init (for example you element with a tabindex of -1):
// By using a tabindex of -1, the element won't be focusable via keyboard
// but, we can programmatically focus it.
.attr( "tabindex", "-1" )
.focus()
You know how when you open a new tab, you can start typing without having to select the search bar? I've got a text input box in HTML, and I'd like to be able to open my webpage and have that text input box immediately typeable, for lack of a better term. Say my input box looks like this:
<input type="text" class="myInput" value="add an item"></input>
I'm using HTML, CSS and JavaScript/jQuery right now. What code can I add to make sure the text input box is immediately typeable?
Use autofocus:
<input type="text" class="myInput" value="add an item" autofocus/>
From the input documentation on MDN:
This Boolean attribute lets you specify that a form control should have input focus when the page loads, unless the user overrides it (e.g. by typing in a different control). Only one form element in a document can have the autofocus attribute, which is a Boolean. It cannot be applied if the type attribute is set to hidden (that is, you cannot automatically set focus to a hidden control). Note that the focusing of the control may occur before the firing of the DOMContentLoaded event.
<input type="text" class="myInput" value="add an item" autofocus>
https://www.w3schools.com/TAgs/att_input_autofocus.asp
in html use autofocus, in jquery use $('.myInput').focus()
I have 3 inputs for every div container (e.g. first-section, second-section ...), and I have several such div containers on my page, similar to this:
...
<div id="first-section">
<fieldset>
<legend>First Section</legend>
<input type="number" placeholder="000" id="input1" min="0" max="255" autofocus maxlength="3" required>
...
</fieldset>
</div>
<div id="second-section">
<fieldset>
<legend>Second Section</legend>
<input type="number" placeholder="000" id="input2" autofocus min="0" max="255" maxlength="3" required>
...
how can I use jQuery to move from input1 to input2 to input3 (not shown) to input4 (not shown) only after the user has entered the maxlength of input which is set to 3? My jQuery below does not work because when I move onto the third input (not shown), it keeps resetting the focus back to input 2.
$(':input').keyup(function(e){
if($(this).val().length==$(this).attr('maxlength')){
$(this).nextAll(':input').first().focus();
if($('#input1').val().length==$('#input1').attr('maxlength')){
$('#input2').focus();
}
}
})
You can find the div that contains the current input, then find the next sibling of the div and the input inside the next div element and set the focus to that.
$(this).closest('div').next().find(':input').first().focus();
Demo: Fiddle
The above one has following issues:
unable to move to previous tab once its filled.
skips the text box which is already filled.
makes things worst if you have JS validations on any input fields.
Use the below jQuery plug-in its easy to configure and use:
Developer Site: http://www.mathachew.com/sandbox/jquery-autotab/
Documentation: https://github.com/Mathachew/jquery-autotab/blob/master/README.md
Includes both Angular and React examples
Cheers...
So, for example, here's a script:
<!-- Random content above this comment -->
<input type="text" tabindex="1" />
<input type="text" tabindex="2" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<!-- Nothing underneath this comment -->
So, when the user presses tab and goes through the six textboxes, reaches the last one and then presses tab, it would go to the content above the first comment, right? Well, how do I make it start from tabindex="1" again?
Unfortunately, you can't do that without javascript. You can listen to a TAB (and make sure it's not SHIFT+TAB) key press on your last element and manually set the focus to your first element inside the handler. However, binding this logic to keyboard events (i.e. specific input method) is not universal and may not work when using:
A mobile browser
Some other entertainment device (smart tv, gaming console, etc. - they typically use a D-Pad for jumping between focusable elements)
An accessibility service
I suggest a more universal approach which is agnostic of how the focus is changed.
The idea is that you surround your form elements (where you want to create a "tabindex loop") with special "focus guard" elements that are focusable too (they have a tabindex assigned). Here is your modified HTML:
<p>Some sample content here...</p>
<p>Like, another <input type="text" value="input" /> element or a <button>button</button>...</p>
<!-- Random content above this comment -->
<!-- Special "focus guard" elements around your
if you manually set tabindex for your form elements, you should set tabindex for the focus guards as well -->
<div class="focusguard" id="focusguard-1" tabindex="1"></div>
<input id="firstInput" type="text" tabindex="2" class="autofocus" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<input id="lastInput" type="text" tabindex="7" />
<!-- focus guard in the end of the form -->
<div class="focusguard" id="focusguard-2" tabindex="8"></div>
<!-- Nothing underneath this comment -->
Now you just listen to focus events on those guard elements and manually change focus to the appropriate field (jQuery used for the sake of simplicity):
$('#focusguard-2').on('focus', function() {
// "last" focus guard got focus: set focus to the first field
$('#firstInput').focus();
});
$('#focusguard-1').on('focus', function() {
// "first" focus guard got focus: set focus to the last field
$('#lastInput').focus();
});
As you see, I also made sure that we snap back to the last input when the focus moves backwards from the first input (e.g. SHIFT+TAB on the first input). Live example
Note that the focus guards are assigned a tabindex value too to make sure they are focused immediately before/after your input fields. If you don't manually set tabindex to your inputs, then both focus guards can just have tabindex="0" assigned.
Of course you can make this all work in a dynamic environment as well, when your form is generated dynamically. Just figure out your focusable elements (less trivial task) and surround them with the same focus guards.
Hope that helps, let me know if you have any issues.
UPDATE
As nbro pointed out, the above implementation has the unwanted effect of selecting the last element if one hits TAB after the page loads (as this would focus the first focusable element which is #focusguard-1, and that would trigger focusing the last input. To mitigate that, you can specify which element you want initially focused and focus it with another little piece of JavaScript:
$(function() { // can replace the onload function with any other even like showing of a dialog
$('.autofocus').focus();
})
With this, just set the autofocus class on whatever element you want, and it'll be focused on page load (or any other event you listen to).
Here my solution where you no need any other elements. As you can see elements will be looping inside <form> elements.
$('form').each(function(){
var list = $(this).find('*[tabindex]').sort(function(a,b){ return a.tabIndex < b.tabIndex ? -1 : 1; }),
first = list.first();
list.last().on('keydown', function(e){
if( e.keyCode === 9 ) {
first.focus();
return false;
}
});
});
Here is my solution, considering the first input has the "autofocus" attribute set:
Add this after your form element (with HTML5 it can be any tag):
<div tabindex="6" onFocus="document.querySelector('[autofocus]').focus()"></div>
Yes, after tabbing through the inputs it will jump on suitable elements that do not have a tab order specified. But also, after tabbing all "tabbable" elements, the focus will jump "outside" your page content, onto the browser's UI elements (tabs, menus, bookmarks, etc)
I think the easiest way is to handle the keyup event on the last input and intercept TAB usage (and SHIFT+TAB for that matter)
I wd suggest you to increase your tabindex ie. >100
and also give the tabIndex to your "content" container div
please note that your content container must have tabindex less than input boxes for ex.99 .
when you press tab on last input box manually set focus on your content div using javascript (you can use keypress handlers for tab key)
document.getElementById("content").focus();
you must giv tabindex to your "content" to set focus to it.
now if you press tab focus will automatically shift to first input box.
hope this will help.
Thank you
I have a form like this:
<form name="mine">
<input type=text name=one>
<input type=text name=two>
<input type=text name=three>
</form>
When user types a value in 'one', I sometimes want to skip the field 'two', depending on what he typed. For example, if user types '123' and uses Tab to move to next field, I want to skip it and go to field three.
I tried to use OnBlur and OnEnter, without success.
Try 1:
<form name="mine">
<input type=text name=one onBlur="if (document.mine.one.value='123') document.three.focus();>
<input type=text name=two>
<input type=text name=three>
</form>
Try 2:
<form name="mine">
<input type=text name=one>
<input type=text name=two onEnter="if (document.mine.one.value='123') document.three.focus();>
<input type=text name=three>
</form>
but none of these works. Looks like the browser doesn't allow you to mess with focus while the focus is changing.
BTW, all this tried with Firefox on Linux.
Try to attach tabindex attribute to your elements and then programmaticaly (in javaScript change it):
<INPUT tabindex="3" type="submit" name="mySubmit">
You could use the onfocus event on field two, which will be called when it receives focus. At that point, field 1's value should be updated and you can perform your check then.
If you used the method you describe, and they worked, the focus would also change when the user clicks on the field, instead of tabbing to it. I can guarantee you that this would result in a frustrated user. (Why exactly it doesn't work is beyond me.)
Instead, as said before, change the tabindex of the appropriate fields as soon as the content of field one changes.
<form name="mine">
<input type="text" name="one" onkeypress="if (mine.one.value == '123') mine.three.focus();" />
<input type="text" name="two">
<input type="text" name="three">
</form>
Try onkeypress instead of onblur. Also, on the onfocus of field two is where you should be sending to three. I'm assuming you don't want them typing in two if one is 123 so you can just check that on two's onfocus and send on to three.