Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repeat the tabindex from 1 after it has gone to the last element with a tabindex?

Tags:

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?

like image 945
Lucas Avatar asked Jan 14 '13 07:01

Lucas


People also ask

How do I change my Tabindex order?

The only way to change this order is to reorder your HTML elements. tabindex itself can do 2 things: it sets the order of "focusable" elements. it makes element "focusable".

Can you add Tabindex to div?

DIV elements are not compatible with tabindex in HTML4). The following elements support the tabindex attribute: A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA. Essentially anything you would expect to be able to hold focus; form elements, links, etc.

Can I use Tabindex for Button?

The tabindex attribute specifies the tab order of an element (when the "tab" button is used for navigating). The tabindex attribute can be used on any HTML element (it will validate on any HTML element. However, it is not necessarily useful).

What does the Tabindex values reflect?

The tabIndex IDL attribute must reflect the value of the tabindex content attribute. Its default value is 0 for elements that are focusable and -1 for elements that are not focusable.


2 Answers

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;         }     }); }); 
like image 41
redexp Avatar answered Nov 18 '22 10:11

redexp


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 <a href="#" tabindex="0">content</a> 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).

like image 86
Dmitry Pashkevich Avatar answered Nov 18 '22 11:11

Dmitry Pashkevich