How to programmatically scroll to item with angular's material virtual scroll?
Asked Answered
N

1

18

I have a list that has many items and each item can be selected. For this I use Angular Material Virtual Scroll. When an item is selected, the selected item is highlighted and then is saved on the server. When I refresh the page, the selected item comes from the server and is again highlighted.

My code looks like

<cdk-virtual-scroll-viewport itemSize="40" class="wrapper">
  <div *cdkVirtualFor="let item of list"
       [class.selected]="item.id === selectedItem.id">
  </div>
</cdk-virtual-scroll-viewport>

The problem is that if a select an item that is down in the list, it is highlighted, but I have to scroll down to the list to see it. I want to programmatically scroll down to it when that item comes from the server.

I the docs there is a scrollToIndex method. Where I can find an instance of FixedSizeVirtualScrollStrategy, so I can call this method?

Nader answered 6/2, 2019 at 10:19 Comment(0)
M
33

Sure, you will need to get a reference to the CdkVirtualScrollViewport instance.

@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;

scrollToMiddle(){
  this.viewPort.scrollToIndex(list.length/2, "smooth");
}

An example can be found in this stackblitz

For the requirement of scrolling to the index of the selected element in the list, you could do the following:

ngAfterViewInit(){
  const selectedIndex = this.list.findIndex(elem => elem.id === this.selectedItem.id);
   if(selectedIndex > -1){
     this.viewPort.scrollToIndex(selectedIndex);
   }
}

Note: this assumes that the list is already loaded during the ngAfterViewInit lifehook. As you havent provided more information about how the list value is set, this is the best that I can provide.

Misdo answered 6/2, 2019 at 10:29 Comment(5)
Thanks! Just one short question: what if I have two lists? (Duplicate the list in the template in the stackblitz example) How can I scroll the second one?Nader
You will need to bind either through a specific child reference as explained here blog.angular-university.io/angular-viewchild section Using @ViewChild to inject a reference to the DOM element of a componentMisdo
And by the way... Why did you called the method on a CdkVirtualScrollViewport object? It supposed to be called on a FixedSizeVirtualScrollStrategy objectNader
AFAIK the FixedSizeVirtualScrollStrategy is an implementation detail and you cant directly access it in this case. The closest that you could get to it would by by binding the viewport with the CdkFixedSizeVirtualScroll instead of CdkVirtualScrollViewport, but I dont see any advantage from it in this use case.Misdo
@Misdo How to scroll to a particular element like HTML elements inside cdk scroll instead of list?Sexcentenary

© 2022 - 2024 — McMap. All rights reserved.