diprokon / ng-table-virtual-scroll

Virtual Scroll for Angular Material Table
https://diprokon.github.io/ng-table-virtual-scroll
MIT License
134 stars 42 forks source link

Scrolling with Sticky Header #42

Closed belLen30 closed 3 years ago

belLen30 commented 3 years ago

When scrolling a table with complex rows having a sticky header, the header scrolls with the content. If i set the bufferMultiplier to something very high then this does not happen. Can you suggest how to go about this issue please. thanks a lot

MatanShushan commented 3 years ago

Same Issue happening to me.

kevinya commented 3 years ago

Do you have many sticky headers ? It seems like there is a bug when there are more than 1 sticky header. I created a PR to correct that : #44

belLen30 commented 3 years ago

Do you have many sticky headers ? It seems like there is a bug when there are more than 1 sticky header. I created a PR to correct that : #44

I only have one sticky header i'm afraid. will this fix work with one sticky header too please? thanks a lot

diprokon commented 3 years ago

Please, check new version 1.3.4 with #44 in it

hakimio commented 3 years ago

@diprokon I also have this issue and v1.3.4 doesn't fix it. Only one sticky header in my case as well. And like @belLen30 already mentioned, increasing buffer size helps, but doesn't solve the issue entirely - the header just disappears later.

MatanShushan commented 3 years ago

Also didn't fix it here. I increase the buffer size for now and it's not happening anymore.

hakimio commented 3 years ago

@diprokon I found out the reason for this bug. Sticky header doesn't work when using mat-table, mat-header-row, mat-row components instead of directives. So the following causes an issue with sticky header:

<mat-table [dataSource]="dataSource">
    <mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
    <mat-row mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>

    <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef>No.</mat-header-cell>
        <mat-cell *matCellDef="let element">{{element.id}}</mat-cell>
    </ng-container>

    <ng-container matColumnDef="name">
        <mat-header-cell mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
        <mat-cell mat-cell *matCellDef="let element">{{element.name}}</mat-cell>
    </ng-container>
</mat-table>

but the following works as expected:

<table mat-table [dataSource]="dataSource">
    <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
    <tr mat-row mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef>No.</th>
        <td mat-cell *matCellDef="let element">{{element.id}}</td>
    </ng-container>

    <ng-container matColumnDef="name">
        <th mat-header-cell mat-header-cell *matHeaderCellDef>Name</th>
        <td mat-cell mat-cell *matCellDef="let element">{{element.name}}</td>
    </ng-container>
</table>

It seems that row height is also different when using components instead of directives. Row height with tr directive is 48px while when using mat-row component it's 49px. Stackblitz reproduction of the bug.

If you would mention in the README, that we should use directives instead of components, I think, you could close this issue.

More info on directive vs component usage

traviscollins commented 3 years ago

Noting that this issue appears in the demo page too. See the "Sticky header" example. Just scroll it a bit quickly, and the header scrolls up.

https://diprokon.github.io/ng-table-virtual-scroll/#/examples

TobiDimmel commented 3 years ago

The problem appears only on iOS/Safari (iPad and iPhone) for me.

It seems mat-table sets the CSS property top directly on the <tr> elements of a sticky header. And this value is negative after you scroll a bit, which renders the header outside the viewport.

Not sure how ng-table-virtual-scroll is interacting with mat-table in this regard. But if you implement it without virtual scrolling it works correctly.

JoeyLi-1 commented 3 years ago

@diprokon I found that if set const start = 0; //Math.max(0, index - buffer); in FixedSizeTableVirtualScrollStrategy::updateContent(). Then the sticky header issue solved. No matter it the header is sticky or not. Is this the right solution? Thank you!