I have a mat-table using the code below with sortable headers. However I also want to put a menu in the header for custom filtering. The problem is that because the whole header clickable and changes the 'sort' of the column, when i click on the menu it also sorts because the menu button is within the header.
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="Borrower1">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<div class="header">
Borrower1
<button mat-button [matMenuTriggerFor]="menu" #matMenuTrigger="matMenuTrigger" >
<mat-icon>filter_list</mat-icon>
</button>
</div>
<mat-menu #menu="matMenu" >
<div (mouseleave)="matMenuTrigger.closeMenu()">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
<button mat-menu-item>Item 3</button>
<button mat-menu-item>Item 4</button>
<button mat-menu-item>Item 5</button>
</div>
</mat-menu>
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.Borrower1}} </mat-cell>
</ng-container>
<ng-container matColumnDef="_id">
<mat-header-cell *matHeaderCellDef mat-sort-header>
_id
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element._id}} </mat-cell>
</ng-container>
<ng-container matColumnDef="edit">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<a (click)="editDialog(element._id)" type="button">
<mat-icon class="icon">edit</mat-icon>
</a>
</mat-cell>
</ng-container>
<ng-container matColumnDef="delete">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<a (click)="deletePost(element._id)" type="button">
<mat-icon class="icon">delete</mat-icon>
</a>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
Is there a way to get around this
I have a mat-table using the code below with sortable headers. However I also want to put a menu in the header for custom filtering. The problem is that because the whole header clickable and changes the 'sort' of the column, when i click on the menu it also sorts because the menu button is within the header.
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="Borrower1">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<div class="header">
Borrower1
<button mat-button [matMenuTriggerFor]="menu" #matMenuTrigger="matMenuTrigger" >
<mat-icon>filter_list</mat-icon>
</button>
</div>
<mat-menu #menu="matMenu" >
<div (mouseleave)="matMenuTrigger.closeMenu()">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
<button mat-menu-item>Item 3</button>
<button mat-menu-item>Item 4</button>
<button mat-menu-item>Item 5</button>
</div>
</mat-menu>
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.Borrower1}} </mat-cell>
</ng-container>
<ng-container matColumnDef="_id">
<mat-header-cell *matHeaderCellDef mat-sort-header>
_id
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element._id}} </mat-cell>
</ng-container>
<ng-container matColumnDef="edit">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<a (click)="editDialog(element._id)" type="button">
<mat-icon class="icon">edit</mat-icon>
</a>
</mat-cell>
</ng-container>
<ng-container matColumnDef="delete">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<a (click)="deletePost(element._id)" type="button">
<mat-icon class="icon">delete</mat-icon>
</a>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
Is there a way to get around this
Share Improve this question asked Oct 30, 2018 at 21:34 Arthur Le CalvezArthur Le Calvez 4332 gold badges7 silver badges18 bronze badges 05 Answers
Reset to default 2Try taking everything in the header that you don't want triggering a sort, wrap it in a div, and put a click handler on it that calls $event.stopPropagation().
Late to the party, but seems that it is possible to set the mat-sort-header
directive on a child element. So this seems to work:
<mat-header-cell *matHeaderCellDef>
<div class="header">
<div class="sort-only-on-this" mat-sort-header>
Borrower1
</div>
<button />
...
</div>
</mat-header-cell>
Simply remove mat-sort-header directive from header you don't want to be clickable (SORTABLE):
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="_id">
<mat-header-cell *matHeaderCellDef>
Id // NOT SORTABLE
</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.Id}} </mat-cell>
</ng-container>
<ng-container matColumnDef="edit">
<mat-header-cell *matHeaderCellDef mat-sort-header>
Number // SORTABLE
</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.Number}}</mat-cell>
</ng-container>
</mat-table>
Put your menu inside a div and add (click)="$event.stopPropagation()" to your div like
<div (click)="$event.stopPropagation()">
your menu....
</div>
Hope it solve your issue.
You can examine this (this is not according to your code but can help) :
<ng-container matColumnDef="test" formGroupName="yourFormGroupName">
<mat-header-cell *matHeaderCellDef >
<span [matMenuTriggerFor]="appMenu" class="cursor-pointer">Text</span>
<span mat-sort-header arrowPosition="after"></span>
</mat-header-cell>
<mat-menu #appMenu="matMenu">
<!--some html-->
</mat-menu>
<mat-cell *matCellDef="let row; let rowIndex = index">text</mat-cell>
<mat-footer-cell *matFooterCellDef></mat-footer-cell>
</ng-container>
Actually the above html is not the html I am using (so I am not sure about it). The html I used is:
<ng-container matColumnDef="test" formGroupName="yourFormGroupName">
<th *matHeaderCellDef mat-header-cell mat-sort-header class="cursor-pointer">
<span [matMenuTriggerFor]="appMenu" (click)="$event.stopPropagation()" class="cursor-pointer">Text</span>
<span arrowPosition="after"></span>
<mat-menu #appMenu="matMenu">
<!--some html-->
</mat-menu>
</th>
<td *matCellDef="let row; let rowIndex = index" mat-cell>text</td>
<td *matFooterCellDef mat-footer-cell></td>
</ng-container>