Reputation: 415
I am having trouble figuring out how to get my code to behave as needed.
As the demo shows I have a table that when the add button is clicked a new row is added. Once the table rows reach a certain height (say for example after adding 5 rows) I need a vertical scroll bar to display and at the same time I need to maintain a sticky header. Basically I need to set the table rows to a fixed height.
The attached screen shot shows where I would like the scroll bar to display. Apologies for the shaky highlight.
The HTML looks looks like this
<div class="table-container">
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="category">
<th mat-header-cell *matHeaderCellDef >Category</th>
<td mat-cell *matCellDef="let code" >
<mat-form-field class="code">
<mat-select>
<mat-option *ngFor=" let category of categories" [value]="category.code" class="dropdownpPopUp" (keydown.ArrowDown)="onDown()">{{category.code}}</mat-option>
</mat-select>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let code" >
<mat-form-field class="type">
<mat-select >
<mat-option *ngFor=" let type of types" [value]="type.code" class="dropdownpPopUp" (keydown.ArrowDown)="onDown()">{{type.code}}</mat-option>
</mat-select>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="additionalCode" class="parent" >
<th mat-header-cell *matHeaderCellDef>Additional Code</th>
<td mat-cell *matCellDef="let element" class="parent" >
<mat-form-field class="type">
<input matInput (keyup)="toggleLookup($event)" autocomplete="off" (keydown.ArrowDown)="onDown()">
</mat-form-field>
<div *ngIf="expanded" class="child">Yah it expanded
<button (click)="expanded = false">Close</button>
</div>
</td>
</ng-container>
<ng-container matColumnDef="ref">
<th mat-header-cell *matHeaderCellDef>Reference</th>
<td mat-cell *matCellDef="let element" >
<mat-form-field>
<input matInput [(ngModel)]="element.type" (keydown.ArrowDown)="onDown()" autocomplete="off">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="add">
<th mat-header-cell *matHeaderCellDef>
<button mat-icon-button (click)="addRow()" matTooltip="Add Row">
<mat-icon>add</mat-icon>
</button>
</th>
<td mat-cell *matCellDef="let code; let i = index;">
<button mat-icon-button (click)="removeAt(i)" matTooltip="Remove Row">
<mat-icon>clear</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columns"></tr>
<tr mat-row *matRowDef="let rows; columns: columns;"></tr>
</table>
<div *ngIf="dataSource.filteredData.length > 0" > <mat-paginator [pageSizeOptions]="[5]" showFirstLastButtons class="paginator"></mat-paginator></div>
</div>
Component Add Function
addRow() {
this.doAddRow();
this.expanded = false;
}
private doAddRow() {
ELEMENT_DATA.push({ code: '', type: '', reference: '' });
this.dataSource = new MatTableDataSource(ELEMENT_DATA);
}
Upvotes: 1
Views: 11622
Reputation: 42516
Actually, Angular Material documentation has covered that.
By using position: sticky styling, the table's rows and columns can be fixed so that they do not leave the viewport even when scrolled. The table provides inputs that will automatically apply the correct CSS styling so that the rows and columns become sticky.
You just need to make the following changes to your <tr>
tag with the mat-header-row
directive.
<tr mat-header-row *matHeaderRowDef="columns; sticky: true"></tr>
In addition, you will need to edit your container class around your table to include the following properties:
.table-container {
height: 400px;
overflow: auto;
/*
other CSS properties
*/
}
This will allow your material datatable to have a sticky header. Here is the demo provided by the official documentation.
Upvotes: 2
Reputation: 524
what you have to do is add a
div
outside of your table and provide amin-height
property.
app.component.css
.main-table{
max-height:42vh;
overflow-y:scroll;
overflow-x:hidden;
}
app.component.html
<ol>
<li>Select + to add rosw</li>
</ol>
<p>After 5 new rows added a vertical scroll bar should aprear and when srolling the header row should still be visible</p>
<div class="table-container">
<div class="main-table">
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="category">
<th mat-header-cell *matHeaderCellDef >Category</th>
<td mat-cell *matCellDef="let code" >
<mat-form-field class="code">
<mat-select>
<mat-option *ngFor=" let category of categories" [value]="category.code" class="dropdownpPopUp" (keydown.ArrowDown)="onDown()">{{category.code}}</mat-option>
</mat-select>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef>Type</th>
<td mat-cell *matCellDef="let code" >
<mat-form-field class="type">
<mat-select >
<mat-option *ngFor=" let type of types" [value]="type.code" class="dropdownpPopUp" (keydown.ArrowDown)="onDown()">{{type.code}}</mat-option>
</mat-select>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="additionalCode" class="parent" >
<th mat-header-cell *matHeaderCellDef>Additional Code</th>
<td mat-cell *matCellDef="let element" class="parent" >
<mat-form-field class="type">
<input matInput (keyup)="toggleLookup($event)" autocomplete="off" (keydown.ArrowDown)="onDown()">
</mat-form-field>
<div *ngIf="expanded" class="child">Yah it expanded
<button (click)="expanded = false">Close</button>
</div>
</td>
</ng-container>
<ng-container matColumnDef="ref">
<th mat-header-cell *matHeaderCellDef>Reference</th>
<td mat-cell *matCellDef="let element" >
<mat-form-field>
<input matInput [(ngModel)]="element.type" (keydown.ArrowDown)="onDown()" autocomplete="off">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="add">
<th mat-header-cell *matHeaderCellDef>
<button mat-icon-button (click)="addRow()" matTooltip="Add Row">
<mat-icon>add</mat-icon>
</button>
</th>
<td mat-cell *matCellDef="let code; let i = index;">
<button mat-icon-button (click)="removeAt(i)" matTooltip="Remove Row">
<mat-icon>clear</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columns"></tr>
<tr mat-row *matRowDef="let rows; columns: columns;"></tr>
</table>
</div>
<div *ngIf="dataSource.filteredData.length > 0" > <mat-paginator [pageSizeOptions]="[5]" showFirstLastButtons class="paginator"></mat-paginator></div>
</div>
Upvotes: 2