Reputation: 4294
I'm using angular6 with Angular material design templates. currently, my result is as follows,
Currently, I have sticky header and footer but the scrolling dataset is not user-friendly.
issue-data-html
is my HTML file,
<div class="mainDiv">
<div class="mat-elevation-z8 issueDataCard">
<div style="position: relative; z-index: 1; " class="app-list-header" fxLayout="row" fxLayoutAlign="start baseline"
fxLayoutGap="8px" fxLayoutGap.gt-xs="24px">
<div fxLayout="column" fxLayoutAlign="start baseline" fxLayoutGap="24px" fxFlex="grow" fxLayout.gt-xs="row">
<div class="app-list-name">
<h3>
Issue Statuses
</h3>
</div>
<div class="vl"></div>
<!--Search-->
<mat-form-field class="app-filter-input" floatPlaceholder="never" fxFlex>
<mat-icon class="app-filter-input-icon" matPrefix>search</mat-icon>
<input matInput #filter placeholder="Search…" (keyup)="applyFilter($event.target.value)">
</mat-form-field>
</div>
<div fxFlex="none">
<button mat-mini-fab style="background-color: #281c7b;" *ngIf="showAddIssueDataIcon"
(click)="addIssueData(null)" matTooltip="Add Issue Data">
<mat-icon>add</mat-icon>
</button>
</div>
<button class="app-column-filter" type="button" mat-icon-button [matMenuTriggerFor]="columnFilter">
<mat-icon style="font-size: 130%; color:#929292" matTooltip="Configure Table">settings</mat-icon>
</button>
<mat-menu #columnFilter="matMenu" yPosition="below" xPosition="before">
<button class="checkbox-item mat-menu-item" *ngFor="let column of displayedColumns"
(click)="toggleColumnVisibility(column, $event)">
<mat-checkbox [(ngModel)]="column.visible" (change)="columnFilterCheckboxClick($event)" class="checkbox"
#checkbox (click)="$event.stopPropagation()">
{{ column.name }}
</mat-checkbox>
</button>
</mat-menu>
<ng-content select=".actions"></ng-content>
</div>
<!--table-->
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- issueStatus Column -->
<ng-container matColumnDef="issueStatus">
<th mat-sort-header="name" mat-header-cell *matHeaderCellDef>ISSUE STATUS</th>
<td mat-cell *matCellDef="let element">
{{element.name}}
</td>
</ng-container>
<!-- showInBacklog Column -->
<ng-container matColumnDef="showInBacklog">
<th mat-sort-header="backlog" mat-header-cell *matHeaderCellDef>SHOW IN BACKLOG</th>
<td mat-cell *matCellDef="let element" style="text-transform: uppercase">
{{element.backlog}}
</td>
</ng-container>
<!-- Status Column -->
<ng-container matColumnDef="status">
<th mat-sort-header="status" mat-header-cell *matHeaderCellDef>STATUS</th>
<td mat-cell *matCellDef="let element" style="text-transform: uppercase">
{{element.status}}
</td>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef class="action-cell" style="padding-right: 40px">ACTIONS</th>
<td mat-cell *matCellDef="let element; let i = index" class="action-cell">
<button mat-icon-button *ngIf="showAddIssueDataIcon" (click)="editIssueData(element)">
<mat-icon class="iconStyle" matTooltip="Edit Issue Data">edit</mat-icon>
</button>
<!-- -->
<a style="cursor: pointer" *ngIf="showEditIssue">
<i class="material-icons" style="color:#757575" [matMenuTriggerFor]="selectMenu"
matTooltip="More actions">more_vert</i></a>
<mat-menu #selectMenu="matMenu">
<button mat-menu-item *ngIf="element.status === 'INACTIVE'"
(click)="onClickEditStatus(element , true,i)">Make Active</button>
<button mat-menu-item *ngIf="element.status === 'ACTIVE'"
(click)="onClickEditStatus(element , false,i)">Make Inactive</button>
<button mat-menu-item (click)="deleteIssueData(element,i)">Delete</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="visibleColumns"></tr>
<tr mat-row *matRowDef="let row; columns: visibleColumns;"
[ngClass]="{ hovered: row.hovered, highlighted: row.highlighted }" (click)="row.highlighted = !row.highlighted"
(mouseover)="row.hovered = true" (mouseout)="row.hovered = false"></tr>
</table>
<mat-paginator [pageSize]="savedPageSize" (page)="columnFilterCheckboxClick($event)"
[pageSizeOptions]="[5, 10, 20, 100]" showFirstLastButtons></mat-paginator>
</div>
</div>
My css file is as follows,
.issueDataCard{
margin: 20px;
}
/* Structure */
table {
width: 100%;
}
.mat-sort-header-container {
align-items: center;
}
.mat-form-field {
font-size: 14px;
width: 98%;
margin: 10px;
}
@import "var";
.app-list-name {
color: $color;
border-right: 1px solid $theme-divider;
font-size: 20px;
line-height: 0px;
font-weight: 500;
padding-right: $spacing;
padding-left: $spacing;
@include media-xs {
border-right: none;
}
}
.iconStyle{
color:#281c7b;
cursor: pointer;
}
.slideToggleStyle{
display: flex;
flex-direction: column;
align-items: flex-end;
}
.divMarginStyle{
margin-bottom: 20px;
margin-right: 20px;
}
.dataStyle{
text-align: center;
}
.dateStyle{
color:#5D6C7F;
font-size: 10px;
}
.actions{
padding-right: 30px;
}
.action-cell{
text-align: right;
}
.mat-cell{
align-items: center;
}
.mat-elevation-z8 {
display: flex;
flex-direction: column;
max-height: 500px;
width: 100%;
margin-bottom: 1.5%;
overflow: auto;
}
I have no idea how to change these CSS classes according to my need, Any help will be greatly accepted.
Upvotes: 4
Views: 18259
Reputation: 2937
Or you can just use sticky to the tr mat-header-row. For example:
<tr
mat-header-row
*matHeaderRowDef="columnsToDisplay; sticky:true"
>
</tr>
Upvotes: 17
Reputation: 4294
Finally hours of coding and changing CSS I found an answer to my question and I thought to post here because this will be helpful for someone in the future.
If I look at the above question I have used pure <table></table>
tag for creating the table and for rows and columns I have used <th></th>
and <td></td>
tags. In Angular Material, there are specific tags for creating a table and assign rows and columns and furthermore to add sticky header and footer. If we won't use those tags there can be some misalignments. So finally I changed my code as below,
issue-data-component.html
file is as follows,
<div class="mainDiv">
<div class="example-container mat-elevation-z8" style="background-color: white"
(click)="columnFilterCheckboxClick($event)">
<div>
<div class="app-list-header" fxLayout="row" fxLayoutAlign="start baseline" fxLayoutGap="8px"
fxLayoutGap.gt-xs="24px">
<div fxLayout="column" fxLayoutAlign="start baseline" fxLayoutGap="24px" fxFlex="grow" fxLayout.gt-xs="row">
<div class="app-list-name">
<h3> Issue Statuses</h3>
</div>
<div class="vl"></div>
<mat-form-field class="app-filter-input" floatPlaceholder="never" fxFlex>
<mat-icon style=" color: #999999;" class="app-filter-input-icon" matPrefix>search</mat-icon>
<input matInput #filter placeholder="Search…" (keyup)="applyFilter($event.target.value)">
</mat-form-field>
</div>
<div class="actions">
<button mat-fab style="background-color: #281c7b;" (click)="addIssueData(null)" matTooltip="Add Issue Data"
*ngIf="showAddIssueDataIcon">
<mat-icon>add</mat-icon>
</button>
</div>
<button class="app-column-filter" type="button" mat-icon-button [matMenuTriggerFor]="columnFilter">
<mat-icon style="font-size: 130%; color: #929292 " matTooltip="Configure Table">settings</mat-icon>
</button>
<ng-content select=".actions"></ng-content>
</div>
<mat-menu #columnFilter="matMenu" yPosition="below" xPosition="before">
<button class="checkbox-item mat-menu-item" *ngFor="let column of displayedColumns"
(click)="toggleColumnVisibility(column, $event)">
<mat-checkbox [(ngModel)]="column.visible" (change)="columnFilterCheckboxClick($event)" class="checkbox"
#checkbox (click)="$event.stopPropagation();">
{{ column.name }}
</mat-checkbox>
</button>
</mat-menu>
<ng-content></ng-content>
</div>
<mat-divider></mat-divider>
<mat-table #table [dataSource]="dataSource" matSort class="tableStyle">
<!-- issueStatus Column -->
<ng-container matColumnDef="issueStatus">
<mat-header-cell *matHeaderCellDef mat-sort-header="name" style="max-width: 35%; min-width: 35%;"> STATUS
</mat-header-cell>
<mat-cell *matCellDef="let element" style="max-width: 35%; min-width: 35%;">
{{element.name}}
</mat-cell>
</ng-container>
<!-- showInBacklog Column -->
<ng-container matColumnDef="showInBacklog">
<mat-header-cell *matHeaderCellDef mat-sort-header="backlog" style="max-width: 25%; min-width: 25%;">ISSUE
STATUS
</mat-header-cell>
<mat-cell *matCellDef="let element" style="text-transform: uppercase; max-width: 25%; min-width: 25%;">
{{element.backlog}}
</mat-cell>
</ng-container>
<!-- Status Column -->
<ng-container matColumnDef="status">
<mat-header-cell *matHeaderCellDef mat-sort-header="status" style="max-width: 30%; min-width: 30%;"> SHOW IN
BACKLOG </mat-header-cell>
<mat-cell *matCellDef="let element" style="text-transform: uppercase; max-width: 30%; min-width: 30%;">
{{element.status}}</mat-cell>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="action">
<mat-header-cell class="action-cell" *matHeaderCellDef style="max-width: 5%; min-width: 5%;">ACTION
</mat-header-cell>
<mat-cell class="action-cell" *matCellDef="let element; let i = index" style="max-width: 5%; min-width: 5%;">
<button mat-icon-button *ngIf="showAddIssueDataIcon" (click)="editIssueData(element)">
<mat-icon class="iconStyle" matTooltip="Edit Issue Data">edit</mat-icon>
</button>
<!-- -->
<a style="cursor: pointer" *ngIf="showEditIssue">
<i class="material-icons" style="color:#757575" [matMenuTriggerFor]="selectMenu"
matTooltip="More actions">more_vert</i></a>
<mat-menu #selectMenu="matMenu">
<button mat-menu-item *ngIf="element.status === 'INACTIVE'"
(click)="onClickEditStatus(element , true,i)">Make Active</button>
<button mat-menu-item *ngIf="element.status === 'ACTIVE'"
(click)="onClickEditStatus(element , false,i)">Make Inactive</button>
<button mat-menu-item (click)="deleteIssueData(element,i)">Delete</button>
</mat-menu>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="visibleColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: visibleColumns;" class="clickable"></mat-row>
</mat-table>
<mat-paginator [pageSize]="savedPageSize" (page)="columnFilterCheckboxClick($event)"
[pageSizeOptions]="[5, 10, 20, 100]" showFirstLastButtons></mat-paginator>
</div>
</div>
And I have added following CSS fields additionally to my CSS file,
.mat-elevation-z8 {
display: flex;
flex-direction: column;
max-height: 500px;
width: 95%;
margin: 3% 3% 3% 3%;
overflow: auto;
}
.tableStyle{
max-height: 500px;
overflow: auto;
}
mat-header-cell, mat-header-row{
position: sticky;
top:0;
background: white;
}
Now the sticky header and footer workes fine and the alignments are well aligned,
Upvotes: 2
Reputation: 4912
I think this will work if not please generate stackblitz of your code
table {
width: 100%;
}
Upvotes: 1