'How can I prevent navigation when a button is clicked within a table row that has a routerLink?
I have an angular material table that has the following structure.
<table mat-table [dataSource]="myTable" matSort>
<ng-container matColumnDef="column1">
<th mat-header-cell *matHeaderCellDef>My Column</th>
<td mat-cell *matCellDef="let row">{{ row.element1 }}</td>
</ng-container>
<ng-container matColumnDef="emailButton">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row">
<button mat-mini-fab color="primary" type="button"
(click)="sendReminder(row)">
<mat-icon>email</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="['../edit-data-row', row.dataId]"></tr>
</table>
I want it so that any row in the table is clickable and the user is routed to the route defined in the routerLink directive and that works just as expected.
However, I have a button inside the row that when clicked, I do not want the user to be routed to the router link. I simply want the (click) event to fire. I've tried using (click)="$event.preventDefault(); $event.stopPropogation(); sendReminder(row)"
on my button as mentioned in research I've conducted already but that doesn't seem to work.
I've also seen a mention of a directive I could add that would prevent router navigation. Thoughts on this?
Lastly, I've also seen an instance of adding a click handler to the table row. But I imagine I would run into the same problem. Thoughts?
Solution 1:[1]
You could try to use a boolean flag to control the router end-point. And route to []
if you don't wish to redirect anywhere. It doesn't change the end-point.
Controller
disableRoute = false;
Template
<table mat-table [dataSource]="myTable" matSort>
<ng-container matColumnDef="column1">
<th mat-header-cell *matHeaderCellDef>My Column</th>
<td mat-cell *matCellDef="let row">{{ row.element1 }}</td>
</ng-container>
<ng-container matColumnDef="emailButton">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row">
<button mat-mini-fab color="primary" type="button"
(click)="sendReminder(row); disableRoute = true"> <!-- set boolean here -->
<mat-icon>email</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="disableRoute ? [] : ['../edit-data-row', row.dataId]"></tr>
</table>
Solution 2:[2]
Or simplified: Just try to put the $event.stopPropogation()
on the <td>
tag - like:
<ng-container matColumnDef="emailButton">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
<button mat-mini-fab color="primary" type="button"
(click)="sendReminder(row)">
<mat-icon>email</mat-icon>
</button>
</td>
Worked for me.
Solution 3:[3]
Try stopImmediatePropagation
, it worked for me.
<table mat-table [dataSource]="myTable" matSort>
<ng-container matColumnDef="column1">
<th mat-header-cell *matHeaderCellDef>My Column</th>
<td mat-cell *matCellDef="let row">{{ row.element1 }}</td>
</ng-container>
<ng-container matColumnDef="emailButton">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row">
<button mat-mini-fab color="primary" type="button"
(click)="sendReminder($event, row)">
<mat-icon>email</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="['../edit-data-row', row.dataId]"></tr>
</table>
sendReminder(e: MouseEvent, row) {
e.stopImmediatePropagation();
console.log(row);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | ruth |
Solution 2 | nwolf |
Solution 3 | metodribic |