I am assigning tabindex for my input type text, and which are not disabled/hidden. The following is what I tried, and it works. However, The order of indexes are horizontally assigned in the table. I would need the order of tabindex in column wise rather than horizontal. Any suggestions how to achieve that ? I want the order to be as follow This Q is a follow up to this enter key to follow the tabindex (in scenario where enter key is changed to behave as tab).
col1 col2 col3
1 3 7
2 4 8
5 9
6 10
(":input:not([disabled]):not(:hidden)").not($(":submit")).not($(":reset")).each(function (i) { $(this).attr('tabindex', i + 1); })
Another related tactic is to use the tabindex attribute. A tabindex of -1 (tabindex="-1") will remove an element from the tab order. A tabindex of 0 (tabindex="0") will add an element to the focus order. It is highly recommended to avoid positive tabindex values and to structure your DOM in the correct order.
tabindex="1" (or any number greater than 1) defines an explicit tab or keyboard navigation order. This must always be avoided. tabindex="0" allows elements besides links and form elements to receive keyboard focus.
Tab order can be set in the Properties window of the designer using the TabIndex property. The TabIndex property of a control determines where it's positioned in the tab order. By default, the first control added to the designer has a TabIndex value of 0, the second has a TabIndex of 1, and so on.
This example will help you set the tabindex
based on the columns:
function fixVerticalTabindex(selector) {
if (typeof selector == 'undefined') {
selector = '.reset-tabindex';
}
var tabindex = 1;
$(selector).each(function(i, tbl) {
$(tbl).find('tr').first().find('td').each(function(clmn, el) {
$(tbl).find('tr td:nth-child(' + (clmn + 1) + ') input').each(function(j, input) {
$(input).attr('placeholder', tabindex);
$(input).attr('tabindex', tabindex++);
});
});
});
}
$(function() {
$('#btn-fix').click(function() {
fixVerticalTabindex('.reset-tabindex');
});
});
table {
border: 1px solid red;
}
input {
border: 1px solid black;
width: 75px;
height: 65px;
font-size: 25px;
text-align: center;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<table class="reset-tabindex">
<tr>
<td><input /></td>
<td>no input</td>
<td>no input</td>
</tr>
<tr>
<td>no input</td>
<td><input /></td>
<td><input /></td>
</tr>
<tr>
<td><input /></td>
<td>no input</td>
<td><input /></td>
</tr>
</table>
<br /><br />
<table class="reset-tabindex">
<tr>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
</tr>
<tr>
<td>no input</td>
<td>no input</td>
<td>no input</td>
<td>no input</td>
<td><input /></td>
</tr>
<tr>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
</tr>
<tr>
<td>no input</td>
<td>no input</td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
</tr>
<tr>
<td>no input</td>
<td>no input</td>
<td><input /></td>
<td><input /></td>
<td><input /></td>
</tr>
</table>
<br /><br />
<button id="btn-fix">Click to fix vertical tabindex</button>
The function will "fix" every table on it's own (will not mix between columns of different tables).
I didn't check the function for tables with
colspan
/rowspan
, but my guess is that it will not work correctly.
The line $(input).attr('placeholder', tabindex);
is there only for preview and debugging, you can remove on production.
Based on this solution for arrow keys I modified the code to work also with enter key and the tab key with specified column-wise mode.
I don't think that it is the best idea to specify tabindex attributes for such case. You would have to recaltulate them on every change in number of columns or rows. Also it would change the flow of focusable elements on page (table first then its surrounding).
/*!
* based on formNavigation https://github.com/omichelsen/FormNavigation
*/
(function ($) {
$.fn.formNavigation = function () {
$(this).each(function () {
// Events triggered on keyup
$(this).find('input').on('keyup', function(e) {
switch (e.which) {
// arrow right
case 39:
$(this).closest('td').next().find('input').focus();
break;
// arrow left
case 37:
$(this).closest('td').prev().find('input').focus();
break;
// arrow bottom
case 40:
$(this).closest('tr').next().children().eq($(this).closest('td').index()).find('input').focus();
break;
// arrow top
case 38:
$(this).closest('tr').prev().children().eq($(this).closest('td').index()).find('input').focus();
break;
// enter
case 13:
if ($(this).closest('td').next().find('input').length>0) {
// when there is another column on right
$(this).closest('td').next().find('input').focus();
} else {
// when last column reached
$(this).closest('tr').next().children().eq(1).find('input').focus();
}
break;
}
});
// Events triggered on keydown (repeatable when holding the key)
$(this).find('input').on('keydown', function(e) {
// Vertical navigation using tab as OP wanted
if (e.which === 9 && !e.shiftKey) {
// navigate forward
if ($(this).closest('tr').next().find('input').length>0) {
// when there is another row below
e.preventDefault();
$(this).closest('tr').next().children().eq($(this).closest('td').index()).find('input').focus();
} else if ($(this).closest('tbody').find('tr:first').children().eq($(this).closest('td').index()+1).find('input').length>0) {
// when last row reached
e.preventDefault();
$(this).closest('tbody').find('tr:first').children().eq($(this).closest('td').index()+1).find('input').focus();
}
} else if (e.which === 9 && e.shiftKey) {
// navigate backward
if ($(this).closest('tr').prev().find('input').length>0) {
// when there is another row above
e.preventDefault();
$(this).closest('tr').prev().children().eq($(this).closest('td').index()).find('input').focus();
} else if ($(this).closest('tbody').find('tr:last').children().eq($(this).closest('td').index()-1).find('input').length>0) {
// when first row reached
e.preventDefault();
$(this).closest('tbody').find('tr:last').children().eq($(this).closest('td').index()-1).find('input').focus();
}
}
});
});
};
})(jQuery);
// usage
$('.gridexample').formNavigation();
/* For demonstration only */
.gridexample {
font-size: 1.1em;
}
.gridexample th {
padding: .15em .5em;
}
.gridexample td {
padding: .1em;
width: 5em;
}
.gridexample input[type="text"] {
width: 100%;
line-height: 2;
box-sizing: border-box;
}
<p>
Sample <a href="#">links</a> around the table (to simulate <a href="#">focus</a> outside the table).
</p>
<table class="gridexample">
<thead>
<tr>
<th></th>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
</tr>
<tr>
<th>2</th>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
</tr>
<tr>
<th>3</th>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
</tr>
<tr>
<th>4</th>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
<td><input type="text"></td>
</tr>
</tbody>
</table>
<p>
Sample <a href="#">links</a> around the table (to simulate <a href="#">focus</a> outside the table).
</p>
<!-- jQuery needed for this solution -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With