Skip to content

Instantly share code, notes, and snippets.

@rakia
Last active January 17, 2024 12:07
Show Gist options
  • Save rakia/ea7906e00d0e19bc4a3c4fb9e3486d3d to your computer and use it in GitHub Desktop.
Save rakia/ea7906e00d0e19bc4a3c4fb9e3486d3d to your computer and use it in GitHub Desktop.
Material Dynamic Table Angular component - typescript part
/**
* Table component that accepts column and row definitions in its content to be registered to the table.
*/
@Component({
selector: 'mat-dynamic-table',
templateUrl: './mat-dynamic-table.component.html',
styleUrls: ['./mat-dynamic-table.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MatDynamicTableComponent<T> implements OnInit, OnChanges, AfterContentInit {
@Input() showFooter: boolean;
@Input() highlightRowIndex: number;
@Input() displayedColumns: string[];
@Input() displayColumnDefs: ColumnDefinition[];
@Input() dataList: T[];
@Output() rowSelected = new EventEmitter<T>();
dataSource = new MatTableDataSource<T>([]);
selection: SelectionModel<T>;
@ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList<MatHeaderRowDef>;
@ContentChildren(MatRowDef) rowDefs: QueryList<MatRowDef<T>>;
@ContentChildren(MatHeaderRowDef) footerRowDefs: QueryList<MatFooterRowDef>;
@ContentChildren(MatColumnDef) columnDefs: QueryList<MatColumnDef>;
@ContentChild(MatNoDataRow) noDataRow: MatNoDataRow;
@ViewChild(MatTable, {static: true}) table: MatTable<T>;
@ViewChildren('matrow', { read: ViewContainerRef }) rows: QueryList<ViewContainerRef>;
constructor() {}
ngAfterContentInit(): void {
this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef));
this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef));
this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef));
if (this.showFooter) {
this.footerRowDefs.forEach(footerRowDef => this.table.addFooterRowDef(footerRowDef));
} else {
this.footerRowDefs.forEach(footerRowDef => this.table.removeFooterRowDef(footerRowDef));
}
// init grid state
this.selection = new SelectionModel<T>(true, []);
this.table.setNoDataRow(this.noDataRow);
}
ngOnInit(): void {
if (!this.displayedColumns) {
this.displayedColumns = this.displayColumnDefs.map(col => col.key);
this.displayColumnDefs.forEach((col, index) => col.index = index);
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.dataList && changes.dataList.currentValue) {
this.dataSource = new MatTableDataSource<T>(this.dataList);
}
}
selectRow(row: T): void {
this.rowSelected.emit(row);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment