I am using Angular and Angular Material 8.0.1. In the application, I had a slot of tables using mat-table. I want the headers and one column to be frozen, so I have been using the sticky keyword. This had been working up until recently for most users but unexpectedly stopped. I believe the sticky headers and columns stopped working around the same time I started using Angular Material's sidenav.
I've read different documentation and haven't found anything that sticks out to me.
One thing that I found that makes the sticky headers work sort of is putting the table inside a div with a set height and auto overflow. The odd thing about this is the sticky headers only work when using that table's scrollbar, not the browser's. I also don't want to set the height of tables since there are multiple on pages and want them to take as much room as they need. And if I set height to 100%, the sticky headers stop working; I'm thinking because the table's scrollbar is now gone.
Here are suggestions that I used to no avail:
https://stackoverflow.com/a/52707760/11665680 https://stackoverflow.com/a/52474361/11665680
export class TeamLeaderboardComponent {
columnsToDisplay = ['player', 'gamesPlayed', 'gamesWon', 'gamesLost', 'winningPercentage', 'kills','deaths','assists'];
sort: MatSort;
dataSource: PlayerServiceRecordDataSource;
@Input('dataSource')
set setDataSource(playerServiceRecords: PlayerServiceRecord[]) {
this.dataSource = new PlayerServiceRecordDataSource(playerServiceRecords);
if (this.sort) {
this.dataSource.sort = this.sort;
}
}
@ViewChild(MatSort, {static: true})
set setSort(sort: MatSort) {
this.sort = sort;
}
}
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<ng-container matColumnDef="player" sticky>
<th class="text" scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>Player</th>
<td class="text" mat-cell *matCellDef="let playerServiceRecord"><a routerLink="/players/{{playerServiceRecord.player.id}}"><img class="small" src="{{playerServiceRecord.player.emblemUrl}}">{{playerServiceRecord.player.gamertag}}</a></td>
</ng-container>
<ng-container matColumnDef="gamesPlayed">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>GP</th>
<td mat-cell *matCellDef="let playerServiceRecord">{{playerServiceRecord.serviceRecord.gamesPlayed}}</td>
</ng-container>
<ng-container matColumnDef="gamesWon">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>W</th>
<td mat-cell *matCellDef="let playerServiceRecord">{{playerServiceRecord.serviceRecord.gamesWon}}</td>
</ng-container>
<ng-container matColumnDef="gamesLost">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>L</th>
<td mat-cell *matCellDef="let playerServiceRecord"> {{playerServiceRecord.serviceRecord.gamesLost}}</td>
</ng-container>
<ng-container matColumnDef="winningPercentage">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>W%</th>
<td mat-cell *matCellDef="let playerServiceRecord"> {{playerServiceRecord.serviceRecord.winningPercentage | percent: '1.1-1'}}</td>
</ng-container>
<ng-container matColumnDef="kills">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>Kills</th>
<td mat-cell *matCellDef="let playerServiceRecord"> {{playerServiceRecord.serviceRecord.kills}}</td>
</ng-container>
<ng-container matColumnDef="deaths">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>Deaths</th>
<td mat-cell *matCellDef="let playerServiceRecord"> {{playerServiceRecord.serviceRecord.deaths}}</td>
</ng-container>
<ng-container matColumnDef="assists">
<th scope="col" mat-header-cell *matHeaderCellDef mat-sort-header>Assists</th>
<td mat-cell *matCellDef="let playerServiceRecord"> {{playerServiceRecord.serviceRecord.assists}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay; sticky: true"></tr>
<tr mat-row *matRowDef="let rowData; columns: columnsToDisplay"></tr>
</table>
<div class="main-container">
<mat-toolbar class="topnav">
<mat-toolbar-row>
<button fxShow="false" fxShow.xs="true" mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
<mat-nav-list fxLayout="row">
<a mat-list-item routerLink="/">Website Title</a>
<a mat-list-item fxShow="true" fxShow.xs="false" routerLink="/lans">LANs</a>
<a mat-list-item fxShow="true" fxShow.xs="false" routerLink="/players">Players</a>
<a mat-list-item fxShow="true" fxShow.xs="false" routerLink="/leaderboards">Leaderboards</a>
</mat-nav-list>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="sidenav-container">
<mat-sidenav #sidenav fixedInViewport fixedTopGap="56">
<mat-nav-list>
<a mat-list-item routerLink="/lans">LANs</a>
<a mat-list-item routerLink="/players">Players</a>
<a mat-list-item routerLink="/leaderboards">Leaderboards</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<section>
<router-outlet></router-outlet>
</section>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
.main-container {
display: flex;
flex-direction: column;
flex: 1 0 auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.sidenav-container {
flex: 1 0 auto;
}
I expect the headers and first column to be sticky but they are not.