user3154990
user3154990

Reputation: 565

How to add sub columns in Mat table column of angular Material table

I am trying to create a mat table with sub columns using Angular Material Table like the link. Is there a way to do this with angular material table? Can I create sub columns from one the columns? Please check the table from the below link

https://datatables.net/examples/basic_init/complex_header.html

Upvotes: 3

Views: 10128

Answers (2)

EnthuCoder
EnthuCoder

Reputation: 107

enter image description here

I wanted a multi-header data table where the 2nd header is in the 2nd row of the data table field but didn't find any solutions related to Angular Material. 2nd header having ‘Area’, ‘City’, ‘State’ will be rendered below 'Address' header, thus using attr.colspan value = 3

Also, <tr mat-header-row *matHeaderRowDef="['stub', ‘area’ , ‘city’, ‘state’]"> is added for 2nd header to work

Here is the solution I have implemented in my code using colspan attribute. Please refer to the comments mentioned in the code

<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
    <ng-container matColumnDef="model">
        <th mat-header-cell *matHeaderCellDef class="header-font"> Model</th>
        <td mat-cell *matCellDef="let element"> {{element.model}} </td>
    </ng-container>
    <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef class="header-font"> Name </th>
        <td mat-cell *matCellDef="let element"> {{element.name}} </td>
    </ng-container>

    <ng-container matColumnDef="address">
        <th mat-header-cell [attr.colspan]="3" *matHeaderCellDef class="header-font"> Address </th>        
    </ng-container>
    
    <!--2nd Header-->
    <ng-container matColumnDef="stub">
        <th mat-header-cell style="background-color: white; border: none;" [attr.colspan]="2" *matHeaderCellDef> </th>
    <!--stub is necessary because 2nd header should not be placed below Model, Name-->
    </ng-container>

    <ng-container matColumnDef="area">
        <th mat-header-cell class="header-font" *matHeaderCellDef> Area </th>
    </ng-container>
    <ng-container matColumnDef="city">
        <th mat-header-cell class="header-font" *matHeaderCellDef> City </th>
    </ng-container>
    <ng-container matColumnDef="state">
        <th mat-header-cell class="header-font" *matHeaderCellDef> State </th>
    </ng-container> 
<!--add 1 more ng-container for Penetration % field-->

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
     <tr mat-header-row *matHeaderRowDef="['stub', ‘area’ , ‘city’, ‘state’]"></tr>  <!--Enable this for 2nd Header-->
   <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

</table>

Upvotes: 0

joerno
joerno

Reputation: 1101

Old question, but I had a similar problem and found this example. Angular Material version is 7.3.1. The complete project can be found here

table-basic-example.html

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <!--- 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="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element"> {{element.position}} </td>
  </ng-container>

  <!-- Name Column -->
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> Name </th>
    <td mat-cell *matCellDef="let element"> {{element.name}} </td>
  </ng-container>

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef> Weight </th>
    <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
  </ng-container>

  <!-- Symbol Column -->
  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef> Symbol </th>
    <td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
  </ng-container>

  <!-- Header row first group -->
  <ng-container matColumnDef="header-row-first-group">
    <th mat-header-cell *matHeaderCellDef 
        [style.text-align]="center"
        [attr.colspan]="2"> 
      First group 
    </th>
  </ng-container>

  <!-- Header row second group -->
  <ng-container matColumnDef="header-row-second-group">
    <th mat-header-cell *matHeaderCellDef [attr.colspan]="2"> Second group </th>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="['header-row-first-group', 'header-row-second-group']"></tr>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

table-basic-example.ts

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

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'},
];

/**
 * @title Basic use of `<table mat-table>`
 */
@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.css'],
  templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = ELEMENT_DATA;
}

table-basic-example.css

table {
  width: 100%;
}

th.mat-header-cell, td.mat-cell {
    text-align: center;
    border: 1px solid #CCC;
    padding: 0 !important;
}

Upvotes: 7

Related Questions