components icon indicating copy to clipboard operation
components copied to clipboard

virtual-scroll: support multiple items per row

Open mmalerba opened this issue 7 years ago • 36 comments
trafficstars

Allow the user to specify the number of items per row in the fixed size scrolling strategy

mmalerba avatar Feb 23 '18 22:02 mmalerba

@mmalerba any news about this?

filipemendes1994 avatar Jul 19 '19 17:07 filipemendes1994

Most of our effort is focused on integrating with MDC right now. When I have time to do more work on virtual scroll, finishing up the missing parts of the autosize strategy will be my top priority , so this one might have to wait a while

mmalerba avatar Jul 25 '19 00:07 mmalerba

Hi @mmalerba any updates on this? Is there at least prevision if this feature will be on the pipeline?

Thanks!

bebeto84 avatar Nov 25 '19 09:11 bebeto84

+1 this would be amazing

pl4yradam avatar Dec 04 '19 10:12 pl4yradam

Any news about this? it seems it's currently not possible to build a real world contentful app with angular. :/

SvenBudak avatar Dec 20 '19 01:12 SvenBudak

please give any update of possible

SurenAvagyanG avatar Dec 21 '19 20:12 SurenAvagyanG

In the meantime you can use display:grid by overriding the css

::ng-deep{
  .cdk-virtual-scroll-content-wrapper {
    display: grid;
    grid-template-columns: 50% 50%;
  }
}

tdhulster avatar Dec 30 '19 17:12 tdhulster

Any update on this?

hdadr avatar Feb 22 '20 13:02 hdadr

I got issues trying to use the display: grid technique above, it looked like it would work but then found it would randomly jump back to previously scrolled locations and was unusable. Official support for multi column would be amazing, +1

daniel-halldorsson avatar Feb 28 '20 11:02 daniel-halldorsson

We solve it with modulo operator...

SvenBudak avatar Feb 28 '20 14:02 SvenBudak

The team does plan to work on this (and other virtual scroll features), but it won't happen this quarter. Our current areas of focus are component harnesses, integration with MDC Web, and the date range picker

mmalerba avatar Feb 28 '20 18:02 mmalerba

Great news, in the mean time, i solved it by chunking my data and wrapping it in a row component with a fixed height. I used BreakpointObserver from cdk layout to determine the amount of chunking required (ie. 1 thumbnail per row on mobile, up to 8 on desktop, depending on width)

daniel-halldorsson avatar Feb 29 '20 19:02 daniel-halldorsson

We solve it with modulo operator...

can you give some more information on that?

daniel-halldorsson avatar Feb 29 '20 19:02 daniel-halldorsson

Up

Albertbol avatar Jul 02 '20 20:07 Albertbol

https://github.com/rintoj/ngx-virtual-scroller Has an implementation of multiple items per row, if anyone wants to look at how it's done (or get something working today.)

lincolnthree avatar Sep 16 '20 13:09 lincolnthree

I was able to "chunk" my array into rows with 4 items each. Then the cdkVirtualFor becomes your rows, your [itemSize] becomes the height of the row, and you loop over the "columns" inside the virtualfor.

      let i: number, j: number, temparray: Card[][] = [], chunk = 4;
      for (i = 0, j = r.length; i < j; i += chunk) {
        temparray.push(r.slice(i, i + chunk));
      }
      this.all = temparray;
        <cdk-virtual-scroll-viewport class="h-100" [itemSize]="130">
            <div class="row no-gutters" *cdkVirtualFor="let row of all">
                <div class="col-3" *ngFor="let card of row">
                    <card-image [card]="card"></card-image>
                </div>
            </div>
        </cdk-virtual-scroll-viewport>

enesien avatar Oct 06 '20 03:10 enesien

Is there any workaround to have multiple items per row when having *cdkVirtualFor working with DataSource<T>?

michele-bergia avatar Dec 04 '20 13:12 michele-bergia

Any Update on this?

joharzmn avatar Jan 05 '21 15:01 joharzmn

?

timsar2 avatar Jan 27 '21 03:01 timsar2

That would be a really helpful feature. Trying to build a responsive resizable css grid gallery with virtual scroll. Thanks!

laurent67100 avatar Jan 28 '21 00:01 laurent67100

@mmalerba would you accept any PRs on this issue?

samhoseinkhani avatar Feb 15 '21 12:02 samhoseinkhani

Yes, I'd be happy to accept a community PR for this. Before you get to far though, it would be good to agree on what the API will look like

mmalerba avatar Feb 16 '21 20:02 mmalerba

I was able to "chunk" my array into rows with 4 items each. Then the cdkVirtualFor becomes your rows, your [itemSize] becomes the height of the row, and you loop over the "columns" inside the virtualfor.

      let i: number, j: number, temparray: Card[][] = [], chunk = 4;
      for (i = 0, j = r.length; i < j; i += chunk) {
        temparray.push(r.slice(i, i + chunk));
      }
      this.all = temparray;
        <cdk-virtual-scroll-viewport class="h-100" [itemSize]="130">
            <div class="row no-gutters" *cdkVirtualFor="let row of all">
                <div class="col-3" *ngFor="let card of row">
                    <card-image [card]="card"></card-image>
                </div>
            </div>
        </cdk-virtual-scroll-viewport>

@enesien This is a good alternative for the time being, thanks for posting this.

tayambamwanza avatar Mar 07 '21 16:03 tayambamwanza

I was able to "chunk" my array into rows with 4 items each. Then the cdkVirtualFor becomes your rows, your [itemSize] becomes the height of the row, and you loop over the "columns" inside the virtualfor.

      let i: number, j: number, temparray: Card[][] = [], chunk = 4;
      for (i = 0, j = r.length; i < j; i += chunk) {
        temparray.push(r.slice(i, i + chunk));
      }
      this.all = temparray;
        <cdk-virtual-scroll-viewport class="h-100" [itemSize]="130">
            <div class="row no-gutters" *cdkVirtualFor="let row of all">
                <div class="col-3" *ngFor="let card of row">
                    <card-image [card]="card"></card-image>
                </div>
            </div>
        </cdk-virtual-scroll-viewport>

Thank you for this.

I had to add inline-block to <div class="col-3" *ngFor="let card of row"> get it work.

Baluditor avatar Mar 22 '21 09:03 Baluditor

In the meantime you can use display:grid by overriding the css

::ng-deep{
  .cdk-virtual-scroll-content-wrapper {
    display: grid;
    grid-template-columns: 50% 50%;
  }
}

@tdhulster, @mmalerba This is a good solution, I think

Particularly, we should set itemSize <cdk-virtual-scroll-viewport [itemSize]="itemSize">

If you want 2 columns per row then itemSize = half value of size (in pixels) For the responsiveness, we can use cdk BreakpointObserver, and then we can set itemSize dynamically.

::ng-deep{
    .cdk-virtual-scroll-content-wrapper {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;

        @media (max-width: 991.98px) {
            grid-template-columns: 1fr 1fr;
        }
        @media (max-width: 575.98px) {
            grid-template-columns: 1fr;
        }
    }
}
constructor() {
    const layoutChanges = breakpointObserver.observe([
                '(max-width: 991.98px) and (min-width: 576px)',
                '(max-width: 575.98px)'
            ]);
    layoutChanges.pipe(takeUntil(this.destroy$))
    .subscribe(res => {
        this.tabletScreen = breakpointObserver.isMatched('(max-width: 991.98px) and (min-width: 576px)');
        this.mobileScreen = breakpointObserver.isMatched('(max-width: 575.98px)');
        this.itemSize = 360 / 3;    // grid-template-columns: 1fr 1fr 1fr; --------- 360px  = item height 
        if (this.tabletScreen) {
            this.itemSize = 360 / 2;   //  grid-template-columns: 1fr 1fr;
        }
        if (this.mobileScreen) {
            this.itemSize = 360;      //  grid-template-columns: 1fr;
        }
    });
}

nerd-cs avatar Mar 24 '21 17:03 nerd-cs

In the meantime you can use display:grid by overriding the css

::ng-deep{
  .cdk-virtual-scroll-content-wrapper {
    display: grid;
    grid-template-columns: 50% 50%;
  }
}

@tdhulster, @mmalerba This is a good solution, I think

Particularly, we should set itemSize <cdk-virtual-scroll-viewport [itemSize]="itemSize"> If you want 2 columns per row then itemSize = half value of size (in pixels) For the responsiveness, we can use cdk BreakpointObserver, and then we can set itemSize dynamically.

::ng-deep{
    .cdk-virtual-scroll-content-wrapper {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;

        @media (max-width: 991.98px) {
            grid-template-columns: 1fr 1fr;
        }
        @media (max-width: 575.98px) {
            grid-template-columns: 1fr;
        }
    }
}
constructor() {
    const layoutChanges = breakpointObserver.observe([
                '(max-width: 991.98px) and (min-width: 576px)',
                '(max-width: 575.98px)'
            ]);
    layoutChanges.pipe(takeWhile(() => this.alive))
    .subscribe(res => {
        this.tabletScreen = breakpointObserver.isMatched('(max-width: 991.98px) and (min-width: 576px)');
        this.mobileScreen = breakpointObserver.isMatched('(max-width: 575.98px)');
        this.itemSize = 360 / 3;    // grid-template-columns: 1fr 1fr 1fr; --------- 360px  = item height 
        if (this.tabletScreen) {
            this.itemSize = 360 / 2;   //  grid-template-columns: 1fr 1fr;
        }
        if (this.mobileScreen) {
            this.itemSize = 360;      //  grid-template-columns: 1fr;
        }
    });
}

I found it does not quite work, as while scroll past the itemSize, the component will unload one item of the viewport from the start, thus breaking the grid flow.

@enesien chunks solution works best, as it would remove a complete row at once.

coldiary avatar Sep 23 '21 03:09 coldiary

Hi, is there any progress on this issue ?

dtomaszewski avatar Dec 01 '21 09:12 dtomaszewski

Yes, we must really need this feature with the Angular Virtual scroller component. At this moment Angular doesn't have any such 2 column grid system scroller. This is a huge issue, especially for large data sets with mobile devices. All other/3rd party component providers also heavily or only depend on Angular Virtual scroller. So we need this from Google Angular team. Any news about progress on this in 2022, please?

Sampath-Lokuge avatar Feb 17 '22 15:02 Sampath-Lokuge

Hi,, any update on above??

Lexa950609 avatar Jun 28 '22 08:06 Lexa950609

Bump. Any news? Waiting for grid support. Btw found new lib solving this issue: https://github.com/lVlyke/lithium-ngx-virtual-scroll

zip-fa avatar Aug 23 '22 08:08 zip-fa