GreatWebGuy Self-proclaimed greatness is a hard thing to prove.

18Dec/0821

Setting your tabindex on your html forms automatically with jQuery

The tabindex is absolutely necessary for controlling the tab order through a really long form, from a usability and accessibility standpoint. This is probably not the preferred way to do this, you should be setting the tabindex attribute on all of your input elements in your html. Now if you work with lazy developers, that often forget to set the tabindex, you may find this to be an acceptable solution.

Quick walk through:

  1. The outside function is your document ready function in jQuery (explaining for those new to jQuery)
  2. The tabindex variable is there to keep track of the index across multiple forms on the page (another reason you may want to use something like this, if your view code is modular and split into a bunch of snippets or includes)
  3. The select grabs all the input and select elements on the page we then exclude the hidden input boxes
  4. We then set the tabindex and increment the variable
$(function(){
	var tabindex = 1;
	$('input,select').each(function() {
		if (this.type != "hidden") {
			var $input = $(this);
			$input.attr("tabindex", tabindex);
			tabindex++;
		}
	});
});
Comments (21) Trackbacks (0)
  1. can u explain your code a little bit more?

    1. why does the variable “$input” starts with an $ ?
    2. why do u need the variable “tabname” ?
    3. what is the variabel “index” for?
    it must not be called “tabindex = tabnum;”

  2. 1) I typically put a $ in front of variables I’ve stored a jQuery object in just to remind me it’s a jQuery object.

    2) I don’t, looks like a piece of debug code I had laying around, when developing I had console.log statements to the console in firebug

    3) Absolutely, looks like a typo, as a side note allowing static indexing in the page has gotten me in trouble as a developer can really throw off your index by statically applying an index

    I’ve modified the script to fix the index variable

  3. i think you could you simplify this to:

    var tabindex = 1;

    $(“form input”).not(‘input[type=hidden]‘).each(function() {
    $(this).attr(“tabindex”, tabindex);
    tabindex++;
    });

    However, it doesn’t seem to work really reliably to add tabindex through the DOM.

  4. This makes it more usable I think … it finds textarea tags, and it will not tabindex anything that is not visible (including hidden items, or just items inside divs that are hidden etc).

    function reassignTabOrders(){
    var tabindex = 1;
    $(‘input,select,textarea’).each(function() {
    var $input = $(this);
    if ($input.is(‘:visible’)) {
    $input.attr(“tabindex”, tabindex);
    tabindex++;
    }
    });
    }

  5. This is what I was able to get working (the quotes in the Alon’s comment got changed to the non-ascii chars):

    $(document).ready(function(){
    $(‘form’).each(function() {
    var tabindex = 1;

    $(‘input,select,textarea’).each(function() {
    var $input = $(this);
    if ($input.is(‘:visible’)) {
    $input.attr(“tabindex”, tabindex);
    tabindex++;
    }
    });
    });
    });//document.ready

  6. $(‘input,select’).each(function(i,e){ e.attr(‘tabindex’,i) });

    =)

  7. [UPDATE]

    // all needed visible elements at once in one line

    $(‘:input:visible, :radio:visible, :checkbox:visible’).each(function(i,e){ e.attr(‘tabindex’,i) });

    // ‘:input’ – selects all input, textarea, select and buttons
    // ‘:radio’ – selects all radios
    // ‘:checkbox’ – selects all checks
    // ‘:visible’ – selects only visible elements

    source: http://docs.jquery.com/Selectors

  8. [UPDATE 2]

    $(‘:enabled:visible’).each(function(i,e){ $(e).attr(‘tabindex’,i) });

  9. @Fellipe Cicconi , $(’:enabled:visible’).each(function(i,e){ $(e).attr(’tabindex’,i) }); —-> this put tabindex to br ,span , div tags

  10. This would probably not happen in many cases, but when I used this for the sign-in form on my website, I got an error from the input type password.

    I solved it like this:

    $j(document).ready(function() {
    var tabindex = 0; // FYI: Tabindexes starts with 0.
    $j(“:input[type=text]:visible :radio:visible, :checkbox:visible”).each(function(i,e){
    $j(e).attr(‘tabindex’,i) ;
    });
    });

  11. $(‘:input[type=text]:visible, :input[type=submit]:visible, :input[type=reset]:visible, :radio:visible, :checkbox:visible, select:visible, textarea:visible’)
    .each(function(i){ $(this).attr(‘tabindex’,i+1) });

  12. according to the jQuery docs “The :input selector basically selects all form controls.”

    so it’s as easy as $(‘:input:visible’).each(i,e){ $(e).attr(‘tabindex’, i) });

  13. Will this set the tabindex when the page loads or on the fly with cloned fields?

  14. Just document ready when the page loads.

  15. anyone know how i would make it set the tabindexes only within a certain form ?

  16. This is totally advisable! You don’t have to set the tabindex as it’s done automatically by the browser in the code’s logical order. You may set the tabindex order if your markup / design is such that demands so. Setting the tabindex on page load/ ready, is’t absolutely redundant and in the examples above, it will probably mess the page readability all together since these doesn’t include anchors!!! which are also focusable elements!

  17. Neil is correct this script is useless as the browser already handels this.

    For more info why this is a bad idea see http://www.lessfussdesign.com/blog/2009/04/skiplinks-tabindex/

    • Dave,

      So you read the disclaimer in the article and then just put in your useless 2 cents anyway. Not all forms flow the same, usability aside. Besides, do you often comment on a 2 year old article with a 2 year old link. Nicely done. This was meant to demonstrate the technique, not recommend it.

  18. I using for reorder the all tabindexs after create the dinamic elements witch jquery.

    function reassignTabOrders(){
    var tabindex = 1;
    $(‘input,select,button’).each(function () {
    if (this.type != ‘hidden’) {
    var $input = $(this);
    $input.attr(“tabindex”, tabindex);
    tabindex++;
    }
    });
    }
    reassignTabOrders();

    Thanks brother Alon and post author.

  19. I have set the tab index and it works fine.

    However when i try to select shift+tab to move backwards, it causes a problem. This happens with respect to the frames I have in that page. When I tend to navigate between each frame backwards, I get this problem.

    Can anyone clarify me on this as to what actually happens?

  20. I took a different approach. I wrote a jQuery function that sets the tab index attribute to -1 for all elements if a tab index attribute was not explicitly set in the html.

    Taking this approach, NOTHING gets a default tab index and all elements are actually removed from the tab index ordering UNLESS a developer specifically set the tab index on the element in the html.


Leave a comment

No trackbacks yet.