[FIXED] Select Rows On PrimeNG Table With Keypress

Issue

I am working with a PrimeNG table, and am trying to select the row of a pSelectableRow by keypress.

I have a global search input that will filter all results of the table, and when the user is done searching, I would like them to be able to click a button on the keyboard and have the row selected from the filtered options.

Currently, if a user is searching and the input box has the focus, they can press tab , but they must press 5 times in order to get down to to first row (more if there are more columns).

Is it possible to select a row element within the app component via typescript or other method where on a keypress, the first row would be selected? Then of course, the user could press enter to actually select the row. The up and down arrows work once the rows are active, but you need to get to the rows first.

I have set up a hotkey function inside of my app so that the f1 key triggers an event:

this.addShortcut({ keys: 'f1' }).subscribe(() => {
  this.showMessage();
  console.log(this.table.value);
});

This is showing a message from the PrimeNG message service to make sure the hotkey is working, and it is also logging the value of the table to the console. I have looked through the table and there doesn’t seem to be any way of selecting a row. I have tried setting the this.table.selection = this.table.value[1] and this does store the [1] array item as the "selected value", but this does not actually select any item from the table.

Is there a better way of doing this?
For simplicity of the code required to make this reproducible in StackOverflow, I have included a stackblitz instead.
Here is a stackblitz.

Solution

If you add [(selection)]="selectedProduct" (onFilter)="onFilter($event, dt)" to your table declaration in your component, then you can manage your table selection every time the user makes a search this way:

onFilter(event, dt) {
    if (event.filteredValue.length > 0) {
      this.selectedProduct = event.filteredValue[0]; // set first visible row as selected
    }
  }

See StackBlitz

Is that what you are looking for?

Edit:

Ok, I hope I’ve understood your need. I added three HostListener to navigate along the filtered data and execute an action while pressing Enter key:

  @HostListener('keydown.ArrowUp', ['$event']) ArrowUp($event: KeyboardEvent) {
    if (this.cpt > 0) {
      this.cpt--;
    }
    this.selectedProduct = this.visibleProducts[this.cpt];
  }

  @HostListener('keydown.ArrowDown', ['$event']) ArrowDown(
    $event: KeyboardEvent
  ) {
    if (this.cpt < this.visibleProducts.length - 1) {
      this.cpt++;
    }
    this.selectedProduct = this.visibleProducts[this.cpt];
  }

  @HostListener('keydown.Enter', ['$event']) Enter($event: KeyboardEvent) {
    alert('opening product: ' + this.selectedProduct.name);
  }

And now, the onFilter method looks like:

  onFilter(event, dt) {
    this.cpt = 0;
    if (event.filteredValue.length > 0) {
      this.selectedProduct = event.filteredValue[0];
      this.visibleProducts = event.filteredValue;
    }
  }

Answered By – Antikhippe

Answer Checked By – Dawn Plyler (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published