2

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!

Fel
  • 4,428
  • 9
  • 43
  • 94

3 Answers3

6

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>
phucnh
  • 1,020
  • 6
  • 14
  • Hi! I was trying to avoid using jQuery or accessing the DOM directly, but thanks for your suggestion! – Fel Jan 08 '19 at 16:01
  • This solution accesses the DOM directly but it's acceptable because I see that the component hasn't any method to perform this operation. Thanks! – Fel Jan 08 '19 at 16:27
  • The only issue I ran into using this with Angular is the scrollTop was being called before the UI was updated with a new row. Once I wrapped scrollTop in a `setTimeout(() => {...}, 0)` it fixed the race condition. – Jacob Roberts Mar 20 '20 at 14:25
1

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

sunitkatkar
  • 1,958
  • 1
  • 14
  • 12
  • Hi! The problem is that we were using PrimeNG 8 and the `scrollTo` method wasn't available yet in its table component. On other projects using PrimeNG from version 9, I realized about the `scrollTo` and `scrollToVirtualIndex` methods and I'm using them since. – Fel Sep 13 '21 at 07:07
0

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