Better tabindex Handling with Razor

I've recently been working on an ASP.NET MVC project with plenty of views that are highly form-centric. That is, the main section of those pages is made up of a big form with lots of input fields.

When a user visits one of these pages, I want them to quickly be able to start entering form data. Because of that, I've added the tabindex="1" attribute to the first <input> tag. Now, when the user presses the TAB key, the first input field is focused right away.

However, there's a usability issue here. When the user presses the TAB key again while the first input field is still focused, the second input field does not receive focus. This is because every element without a tabindex attribute is being tabbed through in source order, the order in which the elements are defined within the HMTL of the page.

Here's what MDN says about tabindex:

An element with a 0 value, an invalid value, or no tabindex value should be placed after elements with a positive tabindex in the sequential keyboard navigation order.

Therefore, if the first input field has the tabindex attribute set, so should every consecutive input field. Otherwise, users will very likely perceive the tab order as implausible if they suddenly see the cursor jump around (seemingly) randomly.

The easy fix for this issue would be to add the tabindex attribute to all input fields and manually increment its value, as is shown below:

<input type="text" tabindex="1" />

<!-- ... -->

<input type="text" tabindex="2" />

<!-- ... -->

<input type="text" tabindex="3" />

<!-- ... -->

This approach has a small downside, though, because it's a little cumbersome to maintain input fields enumerated this way. If you ever want to change the order of the form elements, you will have to manually re-enumerate the tab indices.

If the source order of the input fields matches their desired tab order, which should usually be the case, you can simplify your life a litte bit by using a variable to keep track of the current index value:

@{
    int tabindex = 0;
}

<input type="text" tabindex="@(++tabindex)" />

<!-- ... -->

<input type="text" tabindex="@(++tabindex)" />

<!-- ... -->

<input type="text" tabindex="@(++tabindex)" />

<!-- ... -->

You can now freely reorder the input fields without having to worry about messing up the proper tab order. It's a simple trick, really, but if you apply it, there's one less thing to keep track of, even if it's just a simple increment.

Use the coupon code LAUNCHDAY for $10 off!

Learn React

4 Comments

Wouter

Does it work with partials, editortemplates etc?

sam

i use a bit of script to set the focus on the first element for form pages. if I have jquery its $('#content input, #content select').first().focus(); most of the time my form is in order so this works okay

sam

there is also an 'autofocus' attribute if all form elements are in order

KAR

On another note, something I had to hack into was using your ++VAR on the base and VAR++ on any subsequential elements when using razer with a few foreach loops in my page.