Angular Material 2 Table Mat Row Click event also called with button click in Mat Cell
Solution 1
I've just had the same issue and have solved it using Will's comment to the original post, adding a click handler with $event.stopPropagation
to the cell as the direct parent to the button. I'll add it here as a solution in case anyone else comes here looking for the same answer.
I have a Material data table where the row has a click event to take you through to an edit mode and the last column contains a button with a delete action. Obviously you don't want to be triggering delete and edit at the same time!
Here's the structure I've used that resolves the issue:
Snippet
// Row definition containing a click event
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onEdit(row.id)"></mat-row>
// Definition for the cell containing the button
<ng-container matColumnDef="buttons">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let group" (click)="$event.stopPropagation()">
<button mat-button (click)="onDelete(group.id)">
<mat-icon>delete</mat-icon>
</button>
</mat-cell>
</ng-container>
Full Table Code
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let group">{{ group.name }}</mat-cell>
</ng-container>
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
<mat-cell *matCellDef="let group">{{ group.description }}</mat-cell>
</ng-container>
<ng-container matColumnDef="buttons">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let group" (click)="$event.stopPropagation()">
<button mat-button (click)="onDelete(group.id)">
<mat-icon>delete</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onEdit(row.id)"></mat-row>
</mat-table>
Again, full credit to Will Howell for this solution.
Solution 2
The current accepted answer has a flaw in my opinion. The above solution keeps part of the row unclickable. In order to keep the whole row clickable you can pass the $event to the component in html and call stoppropogation from the component:
html:
<mat-cell *matCellDef="let element" class="rightalign">
<button mat-raised-button color="primary" (click)="openDialog(element, $event)"><mat-icon>edit</mat-icon> Breyta</button>
</mat-cell>
Component:
openDialog(data, event): void {
event.stopPropagation();
const editDialogRef = this.dialog.open(EditClientComponent, {
data: data
});
}
Nasiruddin Saiyed
BY DAY: Slapping the keyboard until something good happens.
Updated on February 02, 2020Comments
-
Nasiruddin Saiyed over 4 years
I am new to material 2 and I have implemented mat table and in which I have click event on row to open dialog and there is also a menu button in last column "Action" but on clicking on button it also open dialog box instead of opening menu.
Table
<mat-table #table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)"> <ng-container matColumnDef="id"> <mat-header-cell *matHeaderCellDef > No. </mat-header-cell> <mat-cell *matCellDef="let element"> <mat-checkbox checked='true'></mat-checkbox> </mat-cell> </ng-container> <ng-container matColumnDef="unit_num"> <mat-header-cell *matHeaderCellDef mat-sort-header="unit_num"> Unit No. </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.unit_num}} </mat-cell> </ng-container> <ng-container matColumnDef="unit_type"> <mat-header-cell *matHeaderCellDef mat-sort-header="unit_type"> Unit Type </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.unit_type}} </mat-cell> </ng-container> <ng-container matColumnDef="shares"> <mat-header-cell *matHeaderCellDef mat-sort-header="shares"> Shares </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.shares}} </mat-cell> </ng-container> <ng-container matColumnDef="sections"> <mat-header-cell *matHeaderCellDef>Section </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.sections.section_type}} </mat-cell> </ng-container> <ng-container matColumnDef="buildings"> <mat-header-cell *matHeaderCellDef >Building </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.buildings.buildingname}} </mat-cell> </ng-container> <ng-container matColumnDef="_id"> <mat-header-cell *matHeaderCellDef> Action </mat-header-cell> <mat-cell *matCellDef="let element"> <button mat-button [matMenuTriggerFor]="menu"><mat-icon>more_vert</mat-icon> </button> <mat-menu #menu="matMenu"> <button mat-menu-item (click)="edit(element._id)">Edit</button> <button mat-menu-item (click)="gotoFamily(element)">Go to current family</button> <button mat-menu-item (click)="createNewFam(element)">Create new family</button> <button mat-menu-item (click)="openDeleteDialog(element._id)">Delete</button> </mat-menu> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns; let index=index;" mat-ripple style="position:relative;" (click)="edit(row._id,$event)"></mat-row> </mat-table> <mat-paginator [length]="count" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" (page)="pageSide($event)"> </mat-paginator>
It should actually open only menu