I am maintaining an advanced eform application with in-mixed legacy freetext HTML which I cannot easily alter. There have previously been no use of tabindex, it has relied on character stream order.
In the middle of the page, I need to introduce a table containing inputs with custom tabbing order, such as:
|-----|-----|-----| | 1 | 3 | 5 | |-----|-----|-----| | 2 | 4 | 6 | |-----------------|
The way that legacy/previously added inputs are rendered on the page, I can actually dynamically/centrally alter them so that they do output tabindexes in order. Such as:
[Input, tabindex: 1] |-----|-----|-----| | 2 | 4 | 6 | |-----|-----|-----| | 3 | 5 | 7 | |-----------------| [Input, tabindex: 8]
But the problem appears when freetext HTML anchors start to show up, which are not rendered dynamically (so cannot easily add tabindex to them, unless I added quite a bit of regex logic). So then the tabbing becomes this:
[Input, tabindex: 1] |-----|-----|-----| | 2 | 4 | 6 | |-----|-----|-----| | 3 | 5 | 7 | |-----------------| [anchor link] [Input, tabindex: 8]
Which makes the link unable to be tabbed to. There may be even worse, more advanced cases of this... but I think the issue is understandable?
So my question is this... is it possible to somehow assign somekind of tabindex groups in the sense of:
[tabgroup1] [Input] [/tabgroup1] [tabgroup2] |-----|-----|-----| | 1 | 3 | 5 | |-----|-----|-----| | 2 | 4 | 6 | |-----------------| [/tabgroup2] [tabgroup3] [anchor link] [Input] [/tabgroup3]
So that I can have tabbing work just as before, jumping in the order of the character stream, from input to the closest anchor, to the next input, et cetera... but while inside [tabgroup2] it will go in the order of the tabindexes there, but then to continue into [tabgroup2] and tab on as if all elements had tabindex="0"
What I am looking for is some magic HTML solution (which is unlikely) or a relatively simple javascript library which might have implemented something like this.
Or, if this does not really exist, it would be interesting to hear some alternative ideas, or thoughts of possible caveats if I try to implement it, myself.
Okay, I solved this with some code of my own. The resulting javascript looks like this:
function updateTabIndex() {
$('a, area, button, input, object, select, textarea').each(function(i, e) {
var element = $(e);
var tabIndex = i;
if (element.attr('data-tabindexoffset')) {
var tabgroup = $(element.closest('[data-tabgroup]'));
if (!tabgroup.attr('data-tabindexstart')) {
tabgroup.attr('data-tabindexstart', tabIndex);
}
var tabIndexStart = parseInt(tabgroup.attr('data-tabindexstart'));
tabIndex = tabIndexStart + parseInt(element.attr('data-tabindexoffset'));
}
$(e).attr('tabindex', tabIndex);
});
}
$(function() {
updateTabIndex();
});
Which enables me to use no tabindexes, except an offset inside a known group of elements where the tabindex will not follow regular character stream order. It seems to be working pretty well, since the tabindexes after the group are always the same; just the ones between which are reordered.
The only issue with a solution like this is if there are elements added and removed from AJAX calls, so all indexes will need to be recalculated, then. But it should be fairly fast.
Example HTML is:
<table data-tabgroup="1">
<tr>
<td><input type="text" name="b" data-tabindexoffset="0" value="1" /></td>
<td><input type="text" name="c" data-tabindexoffset="2" value="3" /></td>
</tr>
<tr>
<td><input type="text" name="d" data-tabindexoffset="1" value="2" /></td>
<td><input type="text" name="e" data-tabindexoffset="3" value="4" /></td>
</tr>
</table>
<a href="#">A link</a>
<input type="text" name="f" />