A common question I come across is how to
allow the user to navigate between rows in an HTML table using the arrow keys.
This was a requirement I had for a web based data entry application I was
working on several years ago. The solution I used worked well but I'll be the
first to admit it is not the only solution, it is one solution.
|
| Allowing focus on elements |
| The biggest issue with trying to tab key
through a table is that the table rows and cells cannot receive focus. Since
these elements cannot receive focus, they cannot receive key presses for the
arrow keys as well. My solution was to use an element that could receive focus.
In my case I used an input element of type text. I embedded a textbox into each
row of the table as the target of the focus. Since I didn't want this showing
in my grid I had to hide the textbox. Changing its type to hidden or setting
its display style to any non-visible style will prevent it from receiving
focus. My solution was to place this control in the first cell of the row with
a cell width of 0. This allowed it to receive focus and prevented the user from
seeing it. |
| The next step was capturing the key presses I
was interested in. These were the tab, arrow down, arrow up, back key and
enter. The enter key was used the same as the row click to make the selection.
The resultant HTML looked similar to the following for each row. |
<tr class="cell"
colorid="White" id="10273" onclick="selectRow(this)"> <td
width="0px"><input type="text" style="width:0px;" onfocus="Hilight(this)"
onblur="unHilight(this)" onkeydown="keyRow(this,'selectRow')" ID="Text1"
NAME="Text1"></td> <td width="150px">10273</td> <td
width="150px">08/05/1996</td> <td
width="150px">09/02/1996</td> <td
width="150px">08/12/1996</td> </tr>
|
| Client Script |
| Now that the framework was setup to get focus
on each row, I had to create the client function that would make this magic
happen.
|
| I started with the selectRow method as this
was the easiest. This was simply capturing te currently selected id and
submitting the form for processing.
|
function selectRow(oRow) { document.all.hdnOrderHeaderId.value = oRow.id; document.all.frmOrderInfo.submit(); }
|
| The next methods were the Hilight and
unHilight. Both of these methods had an argument of the textbox that fired
them. This was simply changing the background color of the newly selected row
and reverting the color of the previously selected row. |
function Hilight(oSrc)
{
oSrc.parentElement.parentElement.bgColor = "MediumSeaGreen";
oSrc.parentElement.parentElement.scrollIntoView(false);
}
function unHilight(oSrc)
{
oSrc.parentElement.parentElement.bgColor = oSrc.parentElement.parentElement.getAttribute("colorid");
}
|
| The last method that needed to be created was
to handle the key press. This method simply checked the key that was presses
and reacted to the keys of interest. It also took in the textbox that triggered
the event and the name of the method to execute on an enter. |
function keyRow(oSrc, oFn)
{
if(window.event.keyCode == 13)
{
eval(oFn + "(oSrc.parentElement.parentElement)");
}
if(window.event.keyCode == 40)
{
if(oSrc.parentElement.parentElement.rowIndex == oSrc.parentElement.parentElement.parentElement.rows.length - 1)
return;
else
{
oSrc.parentElement.parentElement.parentElement.rows[oSrc.parentElement.parentElement.rowIndex + 1].cells[0].children[0].focus();
return;
}
}
if(window.event.keyCode == 38)
{
if(oSrc.parentElement.parentElement.rowIndex == 0)
return;
else
{
oSrc.parentElement.parentElement.parentElement.rows[oSrc.parentElement.parentElement.rowIndex - 1].cells[0].children[0].focus();
return;
}
}
}
|
| Final Result |
| One last item that was needed was to set the
focus on the first row when the page loaded. If the user selected a row using a
click, the page would submit so this step is essential. The steps to perform
this was to create another method and attach it to the onload event. |
function pageLoad() { if (document.all.tblOrder.rows.length > 0) document.all.tblOrder.rows[0].cells[0].children[0].focus(); }
|
I've included a sample ASP.Net application
that uses the explained method. It uses the Northwind SQL database as a data
source. The connection string may have to be modified depending on your
particular data source.
Download the code sample that accompanies this article |