'Blazor NET6 Use arrow Key to move from cell to cell in Table

I wish to use the Arrow key Up and Down to move one cell up or one cell down in a Table with input boxes. If I am in one cell I can use the Tab key to move to the next cell, I wish to be able to do the same with arrow up and down. I have looked around but not been able to find any solution (at least any solution that I understand).

and this html code:

@namespace MasterData.V2.Client.Pages.Operation.StoreCollection.StoreEditCollection

<h3>TestTableNavigate</h3>

<table>
    <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>

    <tbody>
        <tr>
            <th><input type="text" value="1"/></th>
            <th><input type="text" value="2"/></th>
            <th><input type="text" value="3"/></th>
        </tr>
        <tr>
            <th><input type="text" value="4"/></th>
            <th><input type="text" value="5"/></th>
            <th><input type="text" value="6"/></th>
        </tr>
        <tr>
            <th><input type="text" value="7"/></th>
            <th><input type="text" value="8"/></th>
            <th><input type="text" value="9"/></th>
        </tr>
    </tbody>
</table>

@code {

}

Any hint on how to progress?

Peter Schwennesen



Solution 1:[1]

This how you can achieve keyboard movement in table cells

This is your razor page

<h3>TestTableNavigate</h3>

@inject IJSRuntime JS

<table id="myTable" @ref=@myTable @onkeydown="@keydown">
    <thead>
        <tr>
            <th>Col1</th>
            <th>Col2</th>
            <th>Col3</th>
        </tr>
    </thead>

    <tbody>
        <tr>
            <td><input type="text" value="1"/></td>
            <td><input type="text" value="2"/></td>
            <td><input type="text" value="3"/></td>
        </tr>
        <tr>
            <td><input type="text" value="4"/></td>
            <td><input type="text" value="5"/></td>
            <td><input type="text" value="6"/></td>
        </tr>
        <tr>
            <td><input type="text" value="7"/></td>
            <td><input type="text" value="8"/></td>
            <td><input type="text" value="9"/></td>
        </tr>
    </tbody>
</table>

@code {
    private ElementReference myTable;
    private Cell cell = new();

    public async Task keydown(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args)
    {
        cell =  await JS.InvokeAsync<Cell>("navigateTable", myTable , cell, args.Key);
    }

    public class Cell{
        public int CurrentRow { get; set; } = 0;
        public int CurrentColumn { get; set; } = 0;
    }
}

This is the JavaScript function, which handles cell movement

function navigateTable(myTable, cell, key) {
    //  get all rows in table
    var mytablebody = myTable.getElementsByTagName("tbody")[0];

    //  count number of rows in table body
    var rowCount = mytablebody.getElementsByTagName("tr").length;
    
    //  check whick key is pressed
    if (key == "ArrowUp") {
        cell.currentRow = cell.currentRow - 1;
        cell.currentRow = (cell.currentRow < 0) ? 0 : cell.currentRow;
    }
    else if (key == "ArrowDown") {
        cell.currentRow = cell.currentRow + 1;
        cell.currentRow = (cell.currentRow > rowCount - 1) ? rowCount - 1 : cell.currentRow;
    }
    else if (key == "ArrowLeft") {
        cell.currentColumn = cell.currentColumn - 1;
    }
    else if (key == "ArrowRight") {
        cell.currentColumn = cell.currentColumn + 1;
    }

    var myrow;
    
    //  get current row
    myrow= mytablebody.getElementsByTagName("tr")[cell.currentRow];

    //  get number of cells in current row
    var cellCount = myrow.getElementsByTagName("td").length;

    //  Take care of first cell in row
    if (cell.currentColumn < 0) {
        if (cell.currentRow > 0) {
            cell.currentRow = cell.currentRow - 1;
            cell.currentColumn = cellCount - 1;
            myrow = mytablebody.getElementsByTagName("tr")[cell.currentRow];
        }
        else {
            cell.currentColumn = 0;
        }
    }
   
    //  take care of last cell in row
    if (cell.currentColumn > cellCount - 1) {
        if (cell.currentRow < rowCount-1) {
            cell.currentRow = cell.currentRow + 1;
            cell.currentColumn = 0;
            myrow = mytablebody.getElementsByTagName("tr")[cell.currentRow];
        }
        else {
            cell.currentColumn = cellCount - 1;
        }
    }
        
    //  get current cell
    var mycel = myrow.getElementsByTagName("td")[cell.currentColumn];
  
    //  focus to new cell location
    var txt = mycel.children[0];
    txt.focus();

    //  return current row and column to code behind
    return cell;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Surinder Singh