Angular Material 2 Table Mat Row Click event also called with button click in Mat Cell
Asked Answered
P

2

32

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 open **Dialog box** and action buttons are hidden

It should actually open only menu

only action, dialog box disabled

Peptide answered 1/11, 2017 at 9:11 Comment(6)
Try adding $event.stopPropagation() to one of the deeper click handlers (like on the cell).Acropolis
@Brian, did you solve? I would like to know how you solved it. Please share your solution if possible.Salmonberry
@IsakLaFleur I am just one of the editors; I have not solved or answered this problem, I only copy edited it.Token
@Nasiruddin, did you solve it? Can you share?Salmonberry
i have done it using a flag variable and closed other dropdownPeptide
if dropdown-1 is clicked then closed dropdown-2 else closed dropdown-1Peptide
D
86

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.

Diplostemonous answered 26/2, 2018 at 15:26 Comment(5)
thanks this will help someone.. my solution was little complicated its includes various callsPeptide
Thanks, <mat-cell (click)="$event.stopPropagation()"> worked perfectly.Muriel
click event is not working when I am using mat-button on button element, also when I am not using mat-button I am not receiving first click event but I am receiving all click events after that. Could you think of some issues I am facing ? @DiplostemonousSanchez
(click)="$event.stopPropagation()" Works perfecty fine! ThanksTinker
(click)="$event.stopPropagation() worked perfectly from opening expansion on clicking on row but is there any way to make the row open when I click on a button of each row. As I've a EDIT button which I want to be clicked to open the expansion partFregger
T
9

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
});

}

Trussell answered 15/2, 2019 at 21:58 Comment(4)
Yes i already did that coz in mine case state and service need to be called.Peptide
Which part of the row is unclickable?Braynard
@Braynard depends on the html of the cell, but in some cases the button would not fill the whole cell. the rest of that cell would not propagate events to the row, so it appears non-clickable in the empty parts of the cell with the button. (but you probably found out by now)Savior
No! Mine is working fine. I implemented lordchancellor code.Godlike

© 2022 - 2024 — McMap. All rights reserved.