Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ag-grid scroll stick to the bottom #3089

Closed
inorganik opened this issue Apr 19, 2019 · 7 comments
Closed

Make ag-grid scroll stick to the bottom #3089

inorganik opened this issue Apr 19, 2019 · 7 comments

Comments

@inorganik
Copy link

inorganik commented Apr 19, 2019

I'm submitting a ... (check one with "x")

[x] bug report => see 'Providing a Reproducible Scenario'
[] feature request => do not use Github for feature requests, see 'Customers of ag-Grid'
[] support request => see 'Requesting Community Support'

Providing a Reproducible Scenario / Current behavior
I am attempting to configure ag-grid so that scrolling sticks to the bottom, for instance like Slack. I'm building a log view which streams logs and the client wants the logs to appear at the bottom, with scrolling stuck to the bottom.

I've been able to do that by calling ensureVisibleIndex() in the handler for rowDataChanged, but there are several issues:

  • ensureVisibleIndex() seems to animate the scroll, so each time a new log is added, the table shows the state of the row added but not scrolled, then scrolled (it's not instant)
  • We need to be able to guard against programmatic scrolling when the user is not scrolled to the bottom, so that you don't scroll what they're reading out of view. To do that we need to know if the user is scrolled to the bottom. While we can get the current scroll position, there's no way to know if the value is the bottom because there's no scrollHeight exposed.

Here you can see it in action:
https://stackblitz.com/edit/angular-ag-grid-stuck-to-bottom

Expected behavior
Ideally, I would like ensureVisibleIndex() to instantly scroll without animation, so there is no "in-between state.

In addition, I'd like to get the scrollHeight of the table so that I can tell if the user has scrolled up, so that I can guard against scrolling away from the log they are reading

Please tell us about your environment:
Angular 7.x

  • ag-Grid version: 18.0.1

  • Browser:
    Chrome

  • Language:
    Typescript 3.1.1

@gportela85
Copy link
Member

You probably need to add this to your gridOptions (suppressScrollOnNewData: true - https://www.ag-grid.com/javascript-grid-properties/)

Also I would not use the grid api to do this, see: https://stackoverflow.com/questions/18614301/keep-overflow-div-scrolled-to-bottom-unless-user-scrolls-up

This way you can stop the scroll if the user scrolls up a bit and restart if the user scrolls all the way down, like any logger would.

Since this question is not related to ag-Grid itself and more of generic app question. I'll close this one.

@inorganik
Copy link
Author

Thanks for the tips. To be honest I didn't even consider querying the DOM inside ag-grid since it exposes so much functionality and data about the grid itself, such as the bodyScroll event. When I approach manipulating ag-grid, I always look to the api first, since it's already querying and manipulating the DOM.

Getting more of this data exposed without querying the DOM inside ag-grid would be nice, even if it was just via a reference to a DOM element.

@inorganik
Copy link
Author

@gportela85 Can you suggest how to get a DOM reference on the grid element in Angular? There doesn't appear to be a straightforward way. I tried:

markup:

<ag-grid-angular #logGrid (bodyScroll)="handleScroll($event)"></ag-grid-angular>

ts:

@ViewChild('logGrid') logGrid: AgGridNg2;

AgGridNg2 does not have a nativeElement or ElementRef property:

I also tried:

@ViewChild('logGrid') logGrid: ElementRef;

It doesn't have nativeElement property because its type is AgGridNg2 not ElementRef.

@gportela85
Copy link
Member

document.querySelector('.ag-body-viewport') should work, right?

@inorganik
Copy link
Author

Thanks. You guys might consider exposing nativeElement inside AgGridNg2 - it's considered bad practice in Angular to query and manipulate the DOM directly.

@ariamdev6
Copy link

@inorganik do you mind elaborating on your last comment??

im trying to stick the scroll to the bottom and scroll automatically as new data comes in; but when the user scrolls up a bit, stop auto scrolling. I am also using the infinite scroll since the data that im working with can be quite large.

@inorganik
Copy link
Author

inorganik commented Apr 26, 2019

@ariamdev6 Here's how I did it - check out the handleScroll() method.
https://stackblitz.com/edit/angular-ag-grid-stuck-to-bottom

  handleRowDataChanged(event) {
    const index = this.messages.length - 1;
    if (this.stayScrolledToEnd) {
      this.gridOptions.api.ensureIndexVisible(index, 'bottom');
    }
  }

  handleScroll(event) {
    const grid = document.getElementById('logGrid');
    if (grid) {
      const gridBody = grid.querySelector('.ag-body-viewport') as any;
      const scrollPos = gridBody.offsetHeight + event.top;
      const scrollDiff = gridBody.scrollHeight - scrollPos;
      
      this.stayScrolledToEnd = (scrollDiff <= 3);
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants