'angular2 material table hide column
I have the following angular2 material table
<mat-table #table [dataSource]="dataSource" >
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="selected">
<mat-header-cell *matHeaderCellDef>
<mat-checkbox [(ngModel)]="selectAll"></mat-checkbox>
</mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-checkbox [(ngModel)]="element.selected" [checked]="selectAll"></mat-checkbox>
</mat-cell>
</ng-container>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef> Id</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.id}}</mat-cell>
</ng-container>
<ng-container matColumnDef="requested_status">
<mat-header-cell *matHeaderCellDef> Status</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.requested_status}}</mat-cell>
</ng-container>
......
I need to hide a column in the table by some boolean condition. Is it possible without changing columns map in my component?
displayedColumns = ['selected', 'id', ...];
I tried to use *ngIf but it doesn't work. How to do that?
Solution 1:[1]
no need of any directives.
just use
[hidden] it will work ex:[hidden]="show" in html and set show to boolean in ts file.
my html code:
<ng-container matColumnDef="department" >
<mat-header-cell [hidden]="show" *matHeaderCellDef>
Department
</mat-header-cell>
<mat-cell [hidden]="show" *matCellDef="let element">
{{element.department}}
</mat-cell>
</ng-container>
Solution 2:[2]
The angular way to do this is to update the columns passed to your row template:
HTML:
<mat-row *matRowDef="let row; columns: getDisplayedColumns();"></mat-row>
TS:
const columnDefinitions = [
{ def: 'col1', showMobile: true },
{ def: 'col2', showMobile: false },
];
getDisplayedColumns(): string[] {
const isMobile = this.currentDisplay === 'mobile';
return this.columnDefinitions
.filter(cd => !isMobile || cd.showMobile)
.map(cd => cd.def);
}
Solution 3:[3]
To the column you want to hide, add this:
[style.display]="'none'"
You should add to both the mat-heather-cell and the mat-cell.
Solution 4:[4]
I'm using Angular Flex Responsive API (https://github.com/angular/flex-layout/wiki/Responsive-API). Example:
<ng-container matColumnDef="date">
<th
*matHeaderCellDef
mat-header-cell
mat-sort-header
fxShow
fxHide.lt-sm
>
Data
</th>
<td *matCellDef="let element" mat-cell fxShow fxHide.lt-sm>
{{ element.date | date: "dd/MM/yyyy" }}
</td>
<td *matFooterCellDef mat-footer-cell fxShow fxHide.lt-sm>Total</td>
</ng-container>
In this case, will hide in screen less than small (lt-sm).
Solution 5:[5]
The only possible solution seems to change displayed columns in the component class
displayedColumns = ['selected', 'id', ...];
Solution 6:[6]
Finally i found a way to hide column without changing columns map. We need to create an attribute directive, through this directive we can set the display property of an element.
ShowColumnDirective:
import {Component, Directive, ElementRef, Input, AfterViewInit} from '@angular/core';
@Directive({
selector: '[showCoulmn]'
})
export class ShowColumnDirective implements AfterViewInit{
@Input() showInput: string;
constructor(private elRef: ElementRef) {
}
ngAfterViewInit(): void {
this.elRef.nativeElement.style.display = this.showInput;
}
}
Declare this directive in AppModule or any other module:
import {TableBasicExample} from './table-basic-example';
import {ShowColumnDirective} from './table-basic-example';
@NgModule({
imports: [
..........
],
declarations: [TableBasicExample, ShowColumnDirective],
bootstrap: [TableBasicExample],
providers: []
})
export class AppModule {}
Now we can use the directive inside our table's html Component:
<ng-container matColumnDef="position">
<mat-header-cell showCoulmn showInput="none" *matHeaderCellDef> No. </mat-header-cell>
<mat-cell showCoulmn showInput="none" *matCellDef="let element"> {{element.position}} </mat-cell>
</ng-container>
Here is working template: https://plnkr.co/edit/Woyrb9Yx8b9KU3hv4RsZ?p=preview
Solution 7:[7]
If you are going to hide a row by some changeable condition I suggest following way:
// css
.hidden-row {
display: none;
}
// html
<ng-container matColumnDef="importDate">
<mat-header-cell *matHeaderCellDef [ngClass]="showColumn()">
Date
</mat-header-cell>
<mat-cell *matCellDef="let element" [ngClass]="showColumn()">
{{element?.importDate}}
</mat-cell>
</ng-container>
// ts
showColumn(): string {
return this.someService.hasAccess() ? null : 'hidden-row';
}
Solution 8:[8]
The proposed solution @John Smith didn't work form me. Instead I used this adjustment:
// css
.hidden-item {
display: none;
}
// html
<ng-container matColumnDef="importDate">
<mat-header-cell *matHeaderCellDef [ngClass]="{'hidden-item': showColumn()}"> Date
</mat-header-cell>
<mat-cell *matCellDef="let element" [ngClass]="{'hidden-item': showColumn()}"> {{element?.importDate}}
</mat-cell>
</ng-container>
// ts
showColumn(): boolean {
return this.someService.hasAccess();
}
Solution 9:[9]
It's possible as explained in this wrong issue: https://github.com/angular/material2/issues/8944
View:
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
class:
displayedColumns = ['tab1', 'tab2', 'tab3'];
but in constructor:
if (this.removeOneColumn) this.displayedColumns = ['tab1', 'tab3'];
Solution 10:[10]
I had the same problem, where the user can display or hide columns through a checkbox. I solve my problem through a pipe, like this:
@Component({
selector: "app-dynamic-table",
template: `
<mat-checkbox *ngFor="let column of columns" [(ngModel)]="column.show">{{column.name | titlecase}}</mat-checkbox>
<mat-table #table [dataSource]="dataSource">
....
<mat-header-row *matHeaderRowDef="displayedColumns | toggleColumns:columns;"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns | toggleColumns:columns;"></mat-row>
</mat-table>
`
})
export class DynamicTableComponent {
private _columns = [
{
name: "date",
show: true
}, {
name: "selected",
show: true
}, {
name: "id",
show: true
}, {
name: "location",
show: true
}
];
get columns() { return this._columns; }
get displayedColumns(): string[] { return this._columns.map(c => c.name); }
}
@Pipe({
name: "toggleColumns"
})
export class ToggleColumnsPipe implements PipeTransform {
transform(displayedColumns: string[], columns): string[] {
displayedColumns = columns.filter(c => !!c.show).map(c => c.name);
return displayedColumns;
}
}
Now you just need to manage to change the show attribute of the column from true <=> false so the column will be disappear if show: false and it will be displayed when show: true. I do that as you see with mat-checkbox.
Solution 11:[11]
There's a way which is writing some dirty code for both html and css codes, say, specify each column with an identifier then set a rule (like display: none;) to hide them when necessary. Considering that a table will produced row by row, not column by column.
But the correct way is the common & easiest way which is changing column map in component (for example, when an event fires).
Solution 12:[12]
For my case, the below css code is not working.
display:none
Thanks to Rod Astrada, I try add the below code into mat-header-cell then working, then it works!
[style.display]="'none'"
like the following example:
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef [style.display]="'none'">Id</mat-header-cell>
<mat-cell *matCellDef="let element" [style.display]="'none'"> {{element.id}} </mat-cell>
</ng-container>
Solution 13:[13]
For Example:
In HTML:
<button mat-raised-button color="primary" (click)="show_hide_details()">
<span *ngIf="showHideDetails== true">Hide Details</span>
<span *ngIf="showHideDetails== false">Show Details</span>
</button>
<ng-container matColumnDef="Cost">
<th mat-header-cell *matHeaderCellDef mat-sort-header
[ngStyle]="{display: showHideDetails === true? 'table-cell' : 'none'}">{{'Cost' | translate}}</th>
<td mat-cell *matCellDef="let element" [ngStyle]="{display: showHideDetails === true?
'table-cell' : 'none'}">{{element.cost}} </td>
</ng-container>
In TS:
showHideDetails: boolean = false;
show_hide_details() {
this.showHideDetails= !this.showHideDetails;
}
Solution 14:[14]
You can use this method For delete Or add column in mat-table.
columnsToDisplay: string[] = ['id', 'vcName', 'vcFamily', 'Phone']
addOrRemoveTableColumn(colName: string, index: number) {
if ( this.columnsToDisplay.filter(q => q.valueOf() == colName).length > 0) {
this.columnsToDisplay = this.columnsToDisplay.filter(q => q.valueOf() != colName);
}
else if (this.columnsToDisplay.filter(q => q.valueOf() == colName).length == 0) {
this.columnsToDisplay.splice(index, 0, colName);
}
}
For Example:
this.addOrRemoveTableColumn("id",6);
Solution 15:[15]
The responsiv way:
hope it still helps :)
in TS:
styleUrls: ['style.component.scss'],
in style.component.scss:
/* language=SCSS */
.hidden {
display: none;
}
@media (min-width: 1280px) {
.lg\:block {
display: table-cell !important;
}
}
in HTML:
<table mat-table
[dataSource]="dataSource">
<th class="hidden lg:block"
mat-header-cell
*matHeaderCellDef>HEADER
</th>
<td class="hidden lg:block"
mat-cell
*matCellDef="let item">{{ item.data }} </td>
</table>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
