I have a mat-table
that is viewed by 3 users of different roles.
The table has multiple columns; one of the columns is active
(a boolean value that controls the activation and deactivation of the account). I want to toggle that value with a switch within the same table (in another column), but only if the user is an admin.
I already achieved this using bootstrap table this way:
<table class="table table-striped">
<thead>
<tr>
<th *ngIf="isAdmin(currentUser)" (click)="sortByAccountStatus()">
<a>Deactivate/Activate</a>
<a class="sort-by"></a>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let chartOfAccounts of accountList.reverse();" [hidden]="currentUser.role !== '1'">
<td [hidden]="!chartOfAccounts.accountActive">
<a (click)="deactivateAccount(chartOfAccounts)" class="text-danger">Deactivate</a>
</td>
<td [hidden]="chartOfAccounts.accountActive">
<a (click)="activateAccount(chartOfAccounts)" class="text-danger">Activate</a>
</td>
</tr>
</tbody>
<tbody>
<tr *ngFor="let chartOfAccounts of accountList" [hidden]="currentUser.role === '1'">
<td>{{accountActiveStatus(chartOfAccounts.accountActive)}}</td>
</tr>
</tbody>
</table>
The code above will add a column to the table where the admin can click on activate or deactivate depending on the value of the boolean. The operations are implemented in the component.
Using mat-table
, I got the boolean active
column to work.
<ng-container matColumnDef="accountActive">
<mat-header-cell *matHeaderCellDef mat-sort-header>Active</mat-header-cell>
<mat-cell *matCellDef="let chartOfAccounts"> {{chartOfAccounts.accountActive}} </mat-cell>
</ng-container>
My goal is to create another column that holds the switch back and forth from true
to false
like this
<ng-container matColumnDef="activation">
<mat-header-cell *matHeaderCellDef mat-sort-header>Activate/Deactivate</mat-header-cell>
<mat-cell *matCellDef="let chartOfAccounts" [hidden]="!chartOfAccounts.accountActive">
<a (click)="deactivateAccount(chartOfAccounts)" class="text-danger">Deactivate</a>
</mat-cell>
<mat-cell *matCellDef="let chartOfAccounts" [hidden]="chartOfAccounts.accountActive">
<a (click)="activateAccount(chartOfAccounts)" class="text-danger">Deactivate</a>
</mat-cell>
</ng-container>
This is not working and produces a weird result where when the toggle is switched off it cannot be switched back on again, the link disappears, and the toggle column too. Here is a screenshot.
The boolean values are pushed to the right of the tables whenever they're switched to false
Here is a stackblitz example. The toggle does not work but basically when you click on toggle the value of active should switch between true
and false
depending on if the toggle is on or off.
The reason your code isn't working is that you can't use two mat-cell
in a mat-column
. The second one will be ignored completely. This is why your table gets all messed up because on some cells the hidden
is hiding the only cell
present in that column (since the second cell is out of the picture).
You shouldn't be using two separate cells for this. You want Activate
/Deactivate
to appear in the same cell. So instead of using hidden
on the mat-cell
, use ngIf
on the anchor tags to conditionally show Activate
/Deactivate
.
<ng-container matColumnDef="activation">
<mat-header-cell *matHeaderCellDef mat-sort-header>Activate/Deactivate</mat-header-cell>
<mat-cell *matCellDef="let chartOfAccounts">
<a *ngIf="chartOfAccounts.accountActive" (click)="deactivateAccount(chartOfAccounts)" class="text-danger">Deactivate</a>
<a *ngIf="!chartOfAccounts.accountActive" (click)="activateAccount(chartOfAccounts)" class="text-danger">Activate</a>
</mat-cell>
</ng-container>
Edit: (after comments)
If you don't want to show a particular column, just remove it from the displayed columns, this way it won't be rendered by mat-table
.
allColumns: string[] = ['position', 'name', 'weight', 'symbol', 'activate', 'toggle'];
checkIfAdmin() {
this.displayedColumns = this.isAdmin ? this.allColumns : this.allColumns.filter(column => column !== 'toggle');
}
Here is a working example on StackBlitz.