4

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?

gh0st
  • 1,653
  • 3
  • 27
  • 59

3 Answers3

3

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.

nwolf
  • 31
  • 5
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>
ruth
  • 29,535
  • 4
  • 30
  • 57
  • That definitely works, I'll use it for now but I was really hoping I could repeat this logic in something that was more re-usable like throwing it in a directive that I could attach to multiple elements. – gh0st Jun 13 '20 at 23:36
  • I am not exactly sure since the condition is dynamic that depends on something like a button click. – ruth Jun 14 '20 at 06:04
0

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);
}
metodribic
  • 1,561
  • 17
  • 27