0

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.

One Eye
  • 101
  • 2

1 Answers1

0

Do you set some flex styles to the sidenav containers? or just use the default ones? try to add some flex definitions to the content wrapper to see if that provides the required markup for the Sticky headers.

I would study the source code too, to know their approach better and search for known conflicts or requirements in the browser-side

Mateo Tibaquira
  • 2,059
  • 22
  • 23
  • Yes, I'm using flex styles in the sidenav. You can see that in the post's code snippets. I've played around with them and had no success. I also removed the sidenav completely and the headers still didn't stick. So it seems like the sidenav may not be the issue. I'm wondering if this regression happened when I introduced flex-layout. – One Eye Jul 08 '19 at 15:34