swimlane / ngx-datatable

✨ A feature-rich yet lightweight data-table crafted for Angular
http://swimlane.github.io/ngx-datatable/
MIT License
4.63k stars 1.68k forks source link

Scroll to newly inserted (selected) row (programmatic row focus) #872

Open ronnyek opened 7 years ago

ronnyek commented 7 years ago

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

[ ] bug report => search github for a similar issue or PR before submitting
[x ] feature request
[ ] support request => Please do not submit support request here, post on Stackoverflow or Gitter

Current behavior While there doesn't appear to be api's to insert a specific row, its easily accomplished by inserting rows into the dataset. What I'd ultimately like to be able to do is scroll to newly inserted rows... (and that could be as simple as just creating the row data, inserting, setting that as the selected item. (so no need to build functionality to specifically scroll to an inserted or selected record).

Expected behavior What I'd liked to be able to do is provide it a row, or index or something, and be able to scroll to that item. When the row item is displayed (virtual scrolling), I could technically get a reference to datatable-body-row.datatable-body-row.active, but naturally that dissapears as soon as that row is scrolled out of view.

What is the motivation / use case for changing the behavior? Current API lets you programatically select a row, but if that row happens to scrolled off the screen whilst selected element is set, its not clear there is a selection

Please tell us about your environment:

ronnyek commented 7 years ago

I just wrote a test... aside from from inserting etc, if you have a table that say loads up the company.json, and set that to virtual scroll with a height of say 300, set the selected record as the last loaded item... it does indeed select that record and show that as the selected record, but you may not know it because you'd have to scroll down to the end of the list to see it selected.

(I get that in multi-select situations it'd be anyone's guess about what the desired functionality would be, and in this situation, scrolling to selected record may not be everyone's desired functionality, but I'd think there would be a way to provide a setting for that)

amcdnl commented 7 years ago

A external API to jump to a row index might be the desired result here. Shouldn't be too hard to implement if you wanna PR that.

szpetny commented 6 years ago

Hi, what is a status of this? I would also be interested in something which lets jump to a selected row.

szpetny commented 6 years ago

So it looks like it is possible to do it like this: tableEl.bodyComponent.updateOffsetY(row.index/tableEl.bodyComponent.pageSize)

I'm using it with constant rowHeight and [scrollbarV]="true". If the rowHeight is not a const it doesn't work. And when there's no scrollbarV set, apparently there is no need to divide by pageSize see: https://github.com/swimlane/ngx-datatable/blob/570474875e9c57657ea94512ed283078d04e95dc/src/components/body/body.component.ts#L294 xD

Btw found it here (thx): https://github.com/swimlane/ngx-datatable/issues/440

jkon commented 6 years ago

I had this same need and I was satisfied using this line in the function I have to insert a new row (I insert my rows at the top): this._elRef.nativeElement.querySelector( '.datatable-body' ).scrollTop = 0;

I think if you insert rows via rows.push() (meaning they are added to the bottom), you just need to set scrollTop to scrollHeight value.

calamao commented 5 years ago

I had this same need and I was satisfied using this line in the function I have to insert a new row (I insert my rows at the top): this._elRef.nativeElement.querySelector( '.datatable-body' ).scrollTop = 0;

I think if you insert rows via rows.push() (meaning they are added to the bottom), you just need to set scrollTop to scrollHeight value.

Based on that I was able to move the scroll to a specific row doing like this: this.table.element.querySelector('.datatable-body').scrollTop = rowIndex * this.table.rowHeight;

Unfortunatelly "updateOffsetY" does not work for me, it always goes to the top of the scroll. I'm not using virtualization for this example by the way (all rows are loaded into the grid)

s-edlund commented 5 years ago

calamao

Thanks for reviving this old topic. Programmatic scrolling still doesn't work for me, even with your trick. Which version of the ngx-datatable are you using?

In my app I'm using the RouteReuseStrategy to attach an existing component with an ngx-datatable in it when the user navigates. The one thing that is not kept is the vertical scroll position the user was at last time on the page, so I'm trying to set that manually.

calamao commented 4 years ago

calamao

Thanks for reviving this old topic. Programmatic scrolling still doesn't work for me, even with your trick. Which version of the ngx-datatable are you using?

In my app I'm using the RouteReuseStrategy to attach an existing component with an ngx-datatable in it when the user navigates. The one thing that is not kept is the vertical scroll position the user was at last time on the page, so I'm trying to set that manually.

I'm sorry to hear that. The version we are using is: "@swimlane/ngx-datatable": "^16.0.2",

In fact the "scrollTop" should do something as it is the raw DOM method for the scroll element. Maybe something related with the "RouteReuseStrategy"? Are you sure the scroll element that you have stored is still attached to the DOM?

Sorry for the late answer, I suppose you will have found a way by this time.

vldmr-bus commented 2 years ago

calamao

Thanks for reviving this old topic. Programmatic scrolling still doesn't work for me, even with your trick. Which version of the ngx-datatable are you using?

In my app I'm using the RouteReuseStrategy to attach an existing component with an ngx-datatable in it when the user navigates. The one thing that is not kept is the vertical scroll position the user was at last time on the page, so I'm trying to set that manually.

I found the same issue with version 20.0.0. I managed to resolve it by creating interface Attachable { OnAttach?: ()=>void;}, implementing it in reusable component with datatable, calling OnAttach on the component from RouteReuseStrategy.retrieve, with the following code:

  OnAttach() {
    this.datatable.bodyComponent.updateOffsetY(this.datatable.offset);
  }