Fel
Fel

Reputation: 4818

How to scroll to last row on a PrimeNG TurboTable component

I'm using a PrimeNG TurboTable component on an Angular 7 application and there's a button to add new rows to it. The problem is that, when a new row is added, the user has to scroll down to the bottom of the table to start editing it. How could I scroll to it?

This is how I define the table in the template:

<p-table [value]="gridOptions" [scrollable]="true" scrollHeight="13em" 
selectionMode="single" [(selection)]="selectedOption" 
(onEditComplete)="onDataChanged($event)"
(onRowReorder)="onDataChanged($event)">
  [ ... ]

</p-table>

And this is the 'Add option' handler:

onAddOption() {
  // This adds a new option to the TurboTable
  this.gridOptions.push({ name: "", arg: "", comment: "", scope: this.scope });

  // I expected that selecting an option would scroll to it, but it doesn't work
  this.selectedOption = this.gridOptions[this.gridOptions.length-1];
}

Any ideas? Thanks!

Upvotes: 2

Views: 10997

Answers (3)

Oussama Adrouj
Oussama Adrouj

Reputation: 1

There is a lot of methods to achieve this with jquery, vanilla javascript or typescript. The logic is simple, we have to target the scrollable container in our case in a Primeng table it's ".p-datatable-scrollable-body".

Method 1 : Using ViewChild

@ViewChild('myTable') myTable: Table;
this.myTable.scrollTo({bottom: 0});

Method 2 : Using Javascript

let body = table.containerViewChild.nativeElement.getElementsByClassName("p- 
datatable-scrollable-body")[0];
body.scrollTop = body.scrollHeight;

WARNING If you are trying to scroll to bottom immediately after a new row is created then the async behavior of Javascript will make the code scroll to bottom before the DOM is getting updated with the new row. To resolve this issue, wrap the scrollTop updating block inside a basic setTimeout

So the new code will be :

  setTimeout(() => {
    let body = table.containerViewChild.nativeElement.getElementsByClassName("p- 
    datatable-scrollable-body")[0];
    body.scrollTop = body.scrollHeight;
  }, 0) 

** Working Stackblitz Example **

https://stackblitz.com/edit/primeng-tablevirtualscroll-demo-guesgg?file=src/app/app.component.html

Upvotes: 0

sunitkatkar
sunitkatkar

Reputation: 2086

I am quite late to this thread, but I came here as I was wondering how to scroll down to the last record in a PrimeNg table. I should have read the entire documentation carefully. Well, I found the solution in the documentation itself.

I am using Angular 11 with PrimeNg 11. I used the following for scrolling to the bottom/last row of the table. The requirement was to scroll down to the last record when a new record was added to the table (by a reactive form submitting the record to the backend and then getting the latest added record back as a result of the record creation.)

I found the API call scrollTo() works well. Here is a pre-loaded (non-lazy loaded) table with a scrollable area

Snippet of the template

<div class="page-content" style="height: calc(100vh - 100px);">
<p-table [value]="someDataArray" [rows]="lazyCaseComments.length"
           #vsTable [virtualScroll]="true"
           [scrollable]="true" 
           [totalRecords]="totalRecords" 
           scrollHeight="flex">
  ...
  ...
  </p-table>
  </div>

Snippet of the component .ts file

  1. Get a handle to the table using @ViewChild()

    @ViewChild('vsTable') vsTable:Table;

  2. In an event handler or in a method which adds a record to the table and you want to scroll to the bottom of this table to view the latest added record, use the following code

    this.vsTable.scrollTo({bottom: 0, behavior:'smooth'});

In your event handler like a button

Upvotes: 1

phucnh
phucnh

Reputation: 1090

UPDATE: add demo

You only need to use javascript

$('.ui-table-scrollable-body').scrollTop($('.ui-table-scrollable-body')[0].scrollHeight);

or animated:

$(".ui-table-scrollable-body").animate({ scrollTop: $('.ui-table-scrollable-body').prop("scrollHeight")}, 200

Without jquery:

TS:

scroll(table: Table) {
    let body = table.containerViewChild.nativeElement.getElementsByClassName("ui-table-scrollable-body")[0];
    body.scrollTop = body.scrollHeight;
  }

HTML:

<p-table #table [columns]="cols" [value]="sales" [scrollable]="true" scrollHeight="200px"> ... </p-table>
<button (click)="scroll(table)">Scroll</button>

Upvotes: 6

Related Questions