Reusable Material Data Table as a component

A new component is created with the name of table

ng g c table

table.component.ts

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {

  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
  @Input() displayedColumns: string[];
  @Input() columnHeader: string[];
  @Input() dataSource;
  @Input() itemsPerPage: number;
  @Input() columnWidth: number[];
  pageSizeOptions: [number];
  public customeCss = [];
  constructor() { }

  ngOnInit() {
    this.dataSource.paginator = this.paginator;
    this.pageSizeOptions = [this.itemsPerPage];
    this.calculateCustomeCss();
  }
  calculateCustomeCss(){
    for (const width of this.columnWidth) {
      this.customeCss.push({
        flex: '0 0 ' + width + 'px'
      });
    }
  }
}

table.component.html


<mat-grid-list cols="3" rowHeight="9:1" style="background:rgb(192, 143, 143); border: solid 2px #000;">
  <mat-grid-tile style="background-color: royalblue;">Logo</mat-grid-tile>
  <mat-grid-tile colspan="2"></mat-grid-tile>
  <mat-grid-tile colspan="3">
    <div class="mat-display-1" style="margin-bottom: 0px;"><u>Periodic Table</u></div>
  </mat-grid-tile>
  <mat-grid-tile colspan="3" rowspan="2">
    <div class="mat-body-1">
    Detail 1 : Text1<br/>
    Detail 1 : Text1<br/>
    Detail 1 : Text1<br/>
  </div>
  </mat-grid-tile>
</mat-grid-list>
<mat-card>
  <mat-card-content>
  <mat-table [dataSource]="dataSource" class="mat-elevation-z8">
    <ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col">
      <mat-header-cell
        *matHeaderCellDef
        mat-sort-header [innerHTML]="columnHeader[i]"
        [ngStyle]="customeCss[i]"
        ></mat-header-cell>
      <mat-cell *matCellDef="let element"
        [ngStyle]="customeCss[i]"
       > {{ element[col] }} </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
</mat-card-content>
  <mat-card-footer>
    <mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons></mat-paginator>
  </mat-card-footer>
</mat-card>

table.component.css

table {
  width: 100%;
}

app.component.ts

import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material';

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

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  columnHeader: string[] = ['No', 'Name', 'Weight', 'Symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);
  itemsPerPage = 5;
  columnWidth = [80, 180, 180, 100];
}

app.component.html

<app-table
  [displayedColumns]="displayedColumns"
  [columnHeader]="columnHeader"
  [columnWidth]="columnWidth"
  [dataSource]="dataSource"
  [itemsPerPage]="itemsPerPage">
</app-table>

material.module.ts (A new module is created for material)

import { NgModule } from '@angular/core';
import { MatButtonModule,
  MatDividerModule,
  MatGridListModule,
  MatFormFieldModule,
  MatInputModule,
  MatTableModule,
  MatCardModule
  } from '@angular/material';
import { MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import { MatBadgeModule } from '@angular/material/badge';
import { MatButtonToggleModule} from '@angular/material/button-toggle';
import { MatIconModule} from '@angular/material/icon';
import { MatToolbarModule} from '@angular/material/toolbar';
import { MatSidenavModule} from '@angular/material/sidenav';
import { MatMenuModule} from '@angular/material/menu';
import { MatListModule } from '@angular/material/list';
import { MatPaginatorModule } from '@angular/material/paginator';


const MaterialComponent = [
  MatButtonModule,
  MatButtonToggleModule,
  MatIconModule,
  MatBadgeModule,
  MatProgressSpinnerModule,
  MatToolbarModule,
  MatSidenavModule,
  MatMenuModule,
  MatListModule,
  MatDividerModule,
  MatGridListModule,
  MatFormFieldModule,
  MatInputModule,
  MatTableModule,
  MatPaginatorModule,
  MatCardModule
];

@NgModule({
  imports: [
    MaterialComponent,
  ],
  exports: [
    MaterialComponent
  ]
})
export class MaterialModule { }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MaterialModule } from './material/material.module';
import { FormsModule } from '@angular/forms';
import { TableComponent } from './table/table.component';


@NgModule({
  declarations: [
    AppComponent,
    TableComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MaterialModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]

Output :

Leave a Comment