Unable to get show and hide columns button to work for angular material table

Discussão em 'Angular' iniciado por developer8492, Agosto 4, 2025.

  1. I am trying to add a show/hide button to show/hidden columns in an angular material table. I can't get the button to function properly. When clicking on the button it does show the columns in the table I want to show/hide. I'm also trying to get the button to be placed as the last column header of the table after the 'position' column header on the right or whatever column is the last column. Also want the column names for the button to show vertically instead of horizontally bunched together like they are now.

    html

    <button mat-button [matMenuTriggerFor]="menu" class="table-config-menu">
    <mat-icon aria-hidden="false" aria-label="Example home icon">settings</mat-icon>
    <mat-menu #menu="matMenu">
    <span class="table-config-menu-label">Edit Columns</span>
    <div class="table-config-menu-options">
    <mat-checkbox
    *ngFor="let cd of columnDefinitions; let i = index"
    (click)="$event.stopPropagation()"
    [(ngModel)]="cd.visible">
    {{cd.label}}
    </mat-checkbox>
    </div>
    </mat-menu>
    </button>
    <table
    mat-table
    [dataSource]="dataSource"
    multiTemplateDataRows
    class="mat-elevation-z8"
    >
    <ng-container
    matColumnDef="{{column}}"
    *ngFor="let column of columnsToDisplay"
    >
    <ng-container *ngIf="column !== 'action'; else action">
    <th mat-header-cell *matHeaderCellDef>{{column}}</th>
    <td mat-cell *matCellDef="let element">{{element[column]}}</td>
    </ng-container>
    <ng-template #action>
    <th mat-header-cell *matHeaderCellDef>Actions</th>
    <td mat-cell *matCellDef="let element" class="checkbox-spacing">
    <mat-icon
    (click)="expandedElement = expandedElement === element ? null : element"
    >{{expandedElement === element ? 'expand_less' :
    'expand_more'}}</mat-icon
    >
    </td>
    </ng-template>
    </ng-container>
    <ng-container matColumnDef="select">
    <th mat-header-cell *matHeaderCellDef>
    <mat-checkbox
    (change)="$event ? toggleAllRows() : null"
    [checked]="selection.hasValue() && isAllSelected()"
    [indeterminate]="selection.hasValue() && !isAllSelected()"
    [aria-label]="checkboxLabel()"
    >
    </mat-checkbox>
    </th>
    <td mat-cell *matCellDef="let row">
    <mat-checkbox
    (click)="$event.stopPropagation()"
    (change)="$event ? selection.toggle(row) : null"
    [checked]="selection.isSelected(row)"
    [aria-label]="checkboxLabel(row)"
    >
    </mat-checkbox>
    </td>

    </ng-container>

    <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
    <ng-container matColumnDef="expandedDetail">
    <td
    mat-cell
    *matCellDef="let element"
    [attr.colspan]="columnsToDisplay.length"
    >
    <div
    class="example-element-detail"
    [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'"
    >
    <div class="example-element-diagram">
    <div class="example-element-position">{{element.position}}</div>
    <div class="example-element-symbol">{{element.symbol}}</div>
    <div class="example-element-name">{{element.name}}</div>
    <div class="example-element-weight">{{element.weight}}</div>
    </div>
    <div class="example-element-description">
    {{element.description}}
    <span class="example-element-description-attribution">
    -- Wikipedia
    </span>
    </div>
    </div>
    </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
    <tr
    mat-row
    *matRowDef="let element; columns: columnsToDisplayWithExpand;"
    class="example-element-row"
    [class.example-expanded-row]="expandedElement === element"
    ></tr>
    <tr
    mat-row
    *matRowDef="let row; columns: ['expandedDetail']"
    class="example-detail-row"
    ></tr>
    <!-- <tr mat-header-row *matHeaderRowDef="getDisplayedColumns()">
    </tr>
    <tr mat-row *matRowDef="let row; columns: getDisplayedColumns()"></tr> -->
    </table>


    ts

    import { SelectionModel } from '@angular/cdk/collections';
    import { MatTableDataSource } from '@angular/material/table';
    import { Component } from '@angular/core';
    import { MatCheckboxModule } from '@angular/material/checkbox';
    import {
    animate,
    state,
    style,
    transition,
    trigger,
    } from '@angular/animations';

    /**
    * @title Table with expandable rows
    */
    @Component({
    selector: 'table-expandable-rows-example',
    styleUrls: ['table-expandable-rows-example.css'],
    templateUrl: 'table-expandable-rows-example.html',
    imports: [MatCheckboxModule],
    animations: [
    trigger('detailExpand', [
    state('collapsed', style({ height: '0px', minHeight: '0' })),
    state('expanded', style({ height: '*' })),
    transition(
    'expanded <=> collapsed',
    animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
    ),
    ]),
    ],
    })
    export class TableExpandableRowsExample {
    columnsToDisplay: string[] = [
    'action',
    'Name',
    'weight',
    'symbol',
    'position',
    ];
    columnsToDisplayWithExpand = ['select', ...this.columnsToDisplay];

    dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
    expandedElement: PeriodicElement | null;
    selection = new SelectionModel<PeriodicElement>(true, []);

    /** Whether the number of selected elements matches the total number of rows. */
    isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
    }

    /** Selects all rows if they are not all selected; otherwise clear selection. */
    toggleAllRows() {
    if (this.isAllSelected()) {
    this.selection.clear();
    return;
    }

    this.selection.select(...this.dataSource.data);
    }

    /** The label for the checkbox on the passed row */
    checkboxLabel(row?: PeriodicElement): string {
    if (!row) {
    return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${
    row.position + 1
    }`;
    }
    columnDefinitions = [
    { def: 'name', label: 'Name', visible: true },
    {
    def: 'weight',
    label: 'Weight',
    visible: true,
    },
    {
    def: 'symbol',
    label: 'Symbol',
    visible: true,
    },
    {
    def: 'position',
    label: 'Position',
    visible: true,
    },
    ];

    getDisplayedColumns(): string[] {
    return this.columnDefinitions
    .filter((cd) => cd.visible)
    .map((cd) => cd.def);
    }
    }

    export interface PeriodicElement {
    Name: string;
    position: number;
    weight: number;
    symbol: string;
    description: string;
    }

    const ELEMENT_DATA: PeriodicElement[] = [
    {
    position: 1,
    Name: 'Hydrogen',
    weight: 1.0079,
    symbol: 'H',
    description: `Hydrogen is a chemical element with symbol H and atomic number 1. With a standard
    atomic weight of 1.008, hydrogen is the lightest element on the periodic table.`,
    },
    {
    position: 2,
    Name: 'Helium',
    weight: 4.0026,
    symbol: 'He',
    description: `Helium is a chemical element with symbol He and atomic number 2. It is a
    colorless, odorless, tasteless, non-toxic, inert, monatomic gas, the first in the noble gas
    group in the periodic table. Its boiling point is the lowest among all the elements.`,
    },
    {
    position: 3,
    Name: 'Lithium',
    weight: 6.941,
    symbol: 'Li',
    description: `Lithium is a chemical element with symbol Li and atomic number 3. It is a soft,
    silvery-white alkali metal. Under standard conditions, it is the lightest metal and the
    lightest solid element.`,
    },

    ];
    /**
    * Control column ordering and which columns are displayed.
    */


    Demo code is on StackBlitz. I have commented out the getDisplayedColumns in the html so the rest of the table is still functioning properly. When I uncomment them the columns on the table disappear

    Continue reading...

Compartilhe esta Página