Reputation: 3256
I have a html
table in which I can write anything and tabs work. But I am trying to make up and down arrow work as well. I tried few scripts online but not able to make any of those work as those are for particular scenarios. like:
$(document).keydown(function(e){
switch(e.which){
case 37: // left arrow
$(e.target).closest('td').nextAll('td.editable:first').find('div');
break;
case 39: // right arrow
$(e.target).closest('td').nextAll('td.editable:first').find('div');
break;
default: // exit for other keys
return;
}
e.preventDefault(); // prevent default action
});
table{
border: 1px solid black;
table-layout: fixed;
}
tr {
height: 28px;
width: 30px;
}
td{
border:1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table style="width: 600px;border: 1px solid black;">
<tbody>
<tr style="height: 16px;">
<td colspan="6" style="text-align: center; height: 16px; border: 1px solid black;">
<p><strong>Groups</strong></p>
</td>
</tr>
<tr style="border: 1px; border-color: red;">
<td><p style="text-align: left;"><em><strong>Areas</strong></em></p></td>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
</tr>
<tr>
<td style="border-color: red;border: 1px solid red;"><div class="editable"></div></td>
<td><div class="editable"></div></td>
<td><div class="editable"></div></td>
<td><div class="editable"></div></td>
<td><div class="editable"></div></td>
<td><div class="editable"></div></td>
</tr>
</tbody>
</table>
Is there a simple script that will make arrows usable in this table?
Upvotes: 1
Views: 1636
Reputation: 43920
Wouldn't it better to use all 4 arrow keys?
Use .next()
for down ↓ and right → arrow keys.
Use .prev()
for up ↑ and left ← arrow keys.
Keep track of your position with .index()
Use .parent()
to find the <td>
and <tr>
(or .closest()
if from e.target
to <tr>
).
Use .eq()
and the return index number of .index()
to find the same positioned <td>
in a neighboring <tr>
.
Confused? ...me too just take a look at the Demo.
Details commented in comments
/* Don't know if you already made the divs contenteditable but
|| if you haven't yet, here's a simple way of doing it.
*/
$('.editable').attr('contenteditable', true);
// Delegate the keydown event to Document Object
$(document).on('keydown', function(e) {
// Prevent default action
e.preventDefault();
/* Establish references to all elements that could possibly be
|| involved.
*/
// Reference the <div> being typed into
var start = $(e.target);
// Reference the <td> that the <div> is the child of
var cell = start.parent('td');
// Reference the <tr> that the <td> is child of
var row = cell.parent('tr');
// Determine the index position of the <td>
var idx = row.find('td').index(cell);
//console.log(idx);
switch (e.which) {
// Up
case 38:
/* Find the <tr> that's above the current <tr>
|| Find the <td> in the same position as current <td>
|| Find the <div> in that <td>
*/
row.prev('tr').find('td').eq(idx).find('.editable').focus();
break;
// Left
case 37:
/* Find the <td> that's to the left of current <td>
|| Find the <div> within that <td>
*/
cell.prev('td').find('.editable').focus();
break;
// Right
case 39:
/* Find the <td> that's to the right of current <td>
|| Find the <div> within that <td>
*/
cell.next('td').find('.editable').focus();
break;
// Down
case 40:
/* Find the <tr> that's below the current <tr>
|| Find the <td> in the same position as current <td>
|| Find the <div> in that <td>
*/
row.next('tr').find('td').eq(idx).find('.editable').focus();
break;
// Ignore other keys
default:
return;
}
// Stop event bubbling
e.stopPropagation();
});
table {
border: 1px solid black;
table-layout: fixed;
}
tr {
height: 28px;
width: 30px;
}
td {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table style="width: 600px;border: 1px solid black;">
<tbody>
<tr style="height: 16px;">
<td colspan="6" style="text-align: center; height: 16px; border: 1px solid black;">
<p><strong>Groups</strong></p>
</td>
</tr>
<tr style="border: 1px; border-color: red;">
<td>
<p style="text-align: left;"><em><strong>Areas</strong></em></p>
</td>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
</tr>
<tr>
<td style="border-color: red;border: 1px solid red;">
<div class="editable"></div>
</td>
<td>
<div class="editable"></div>
</td>
<td>
<div class="editable"></div>
</td>
<td>
<div class="editable"></div>
</td>
<td>
<div class="editable"></div>
</td>
<td>
<div class="editable"></div>
</td>
</tr>
</tbody>
</table>
Upvotes: 0
Reputation: 1128
This would be considerably easier with class names for the <td>
or <div>
elements, but in their absence, here is a solution. See https://api.jquery.com/category/traversing/tree-traversal/ for more info.
Also, use .focus()
to focus the field:
$(document).keydown(function(e) {
switch (e.which) {
case 37: // left arrow
$(e.target).parent().prev().find('div').focus()
break;
case 39: // right arrow
$(e.target).parent().next().find('div').focus()
break;
case 40: // down
$(e.target).parent().parent().next().children().eq($(e.target).parent().index()).find('div').focus()
break;
case 38: // up
$(e.target).parent().parent().prev().children().eq($(e.target).parent().index()).find('div').focus()
break;
default: // exit for other keys
return;
}
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<table style="width: 1400px;border: 1px solid black;">
<tbody>
<tr style="height: 16px;">
<td colspan="6" style="text-align: center; width: 979px; height: 16px; border: 1px solid black;">
<p><strong>Groups</strong></p>
</td>
</tr>
<tr border: 1px; border-color: red; ">
<td><p style="text-align: left; "><em><strong>Areas</strong></em></p></td>
<td style="border-color: red;border: 1px solid red; "><div contenteditable>fgjhdfjdg</div></td>
<td style="border-color: red;border: 1px solid red; "><div contenteditable><sadffsf</div></td>
<td style="border-color: red;border: 1px solid red; "><div contenteditable>zxcvxzcv</div></td>
<td style="border-color: red;border: 1px solid red; "><div contenteditable>cvbnvbn</div></td>
<td style="border-color: red;border: 1px solid red; "><div contenteditable>REQZX</div></td>
</tr>
<tr>
<td style="border-color: red;border: 1px solid red; "><div contenteditable>CVBXCB</td>
<td><div contenteditable>HJM,HJ</td>
<td><div contenteditable>ASDFAS</td>
<td><div contenteditable>NBCN</td>
<td><div contenteditable>RTWETB</td>
<td><div contenteditable>XCVBXCB</td>
</tr>
</tbody>
</table>
<style>
table{
border: 1px solid black;
table-layout: fixed;
}
tr {
height: 28px;
width: 100px;
}
td{
border:1px solid #000;
}
</style>
Upvotes: 2