Search code examples
angularangular-materialng-classmat-table

Angular Material Navigate rows using up and down arrow key


I added a custom ngclass to my mat-table to to make the rows clickable. but now I would like the user to be able to navigate using the up and down arrow keys. using this git hub as a reference(https://github.com/angular/components/issues/14861) I was able to get it to work on the first try by using the tabindex to capture the keydown event. But I have not been able to find out why it only works on the first try; Here is the stack blitz: https://stackblitz.com/edit/arrownavigation?file=app%2Ftable-basic-example.html

.HTML

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;  let i= index"
    [ngClass]="{'highlight': selectedRowIndex == row.position}"
    (click)="highlight(row, i)"
    tabindex="999"
    (keydown.arrowdown)="arrowDownEvent(row, i)"
    (keydown.arrowup)="arrowUpEvent(row, i)"></tr>
</table>

.TS

highlight(row: any){
    this.selectedRowIndex = row.position;
    console.log(row);
  }

   arrowUpEvent(row: object, index: number){
    var nextrow = this.dataSource[index - 1];
    this.highlight(nextrow);
  }

  arrowDownEvent(row: object, index: number){
    var nextrow = this.dataSource[index + 1];
     this.highlight(nextrow);
    console.log(index);
  }

.CSS

.highlight{
  background: yellow;
}

tr:focus{
      outline: none;
  }

Solution

  • I've fixed the issues and now it's working. See this:

    https://stackblitz.com/edit/arrownavigation-9qz7d5?file=app/table-basic-example.html

    The major problem was, you were passing 'i' in arrowDownEvent and arrowUpEvent where you should've passed selectedRowIndex.Then, your defined array is 0-indexed, but index 'i' in *matRowDef was 1-indexed. So I had to change some logic in arrowDownEvent and arrowUpEvent to solve this problem