I\'m trying to add rowSpan and colSpan
in Angular material Table header
. Can anyone help me to achieve it.
If you want to use native-table features such as colspan and rowspan you will need to use:
<table mat-table>
...
</table>
Ref: Native table element tags
For example:
Ref: Serendipity CRM
I ran into the same issue and, using some inspiration from previous answers, found the following to work perfectly.
To achieve the example provided in the question, you will need two table headers. The first will contain the State
, Utilities company
and Summer Period
columns, while the second will contain the data1
, data2
& data3
columns. To do this, start with the following:
<table mat-table [dataSource]="dataSource" class="my-table">
<tr mat-header-row *matHeaderRowDef="['state', 'company', 'summer']"></tr>
<tr mat-header-row *matHeaderRowDef="['data1', 'data2', 'data3']"></tr>
<tr mat-row *matRowDef="let row; columns: ['state', 'company', 'data1', 'data2', 'data3']"></tr>
</table>
This piece of code creates a table with two table header rows and, for each data point in your dataSource, one row with 5 cells which use the columns provided.
To properly style these header rows, we need to use rowSpan
and colSpan
. For each column, we create our ng-container
:
<ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">State</th>
<td mat-cell *matCellDef="let data">State name here (e.g. {{data.state}})</td>
</ng-container>
<ng-container matColumnDef="company">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">Utilities company</th>
<td mat-cell *matCellDef="let data">Utilities company here</td>
</ng-container>
<ng-container matColumnDef="summer">
<th mat-header-cell *matHeaderCellDef [attr.colspan]="3">Summer</th>
<!-- This column doesn't generate <td> items, so no need to add a definition for them -->
</ng-container>
<ng-container matColumnDef="data1">
<th mat-header-cell *matHeaderCellDef>Data 1</th>
<td mat-cell *matCellDef="let data">{{data.yourFirstDataPoint}}</td>
</ng-container>
<ng-container matColumnDef="data2">
<th mat-header-cell *matHeaderCellDef>Data 2</th>
<td mat-cell *matCellDef="let data">{{data.yourSecondDataPoint}}</td>
</ng-container>
<ng-container matColumnDef="data3">
<th mat-header-cell *matHeaderCellDef>Data 3</th>
<td mat-cell *matCellDef="let data">{{data.yourThirdDataPoint}}</td>
</ng-container>
This creates the desired result for you. If you want, you can add mat-sort
definitions to your columns, as well. I hope this makes sense, if not, let me know and I'll try to expand my answer.
I have the sample task like you. I just easy to display none with second header.
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}"> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- first stage header -->
<ng-container matColumnDef="No">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">No</th>
</ng-container>
Here is my result
You can follow my link to know more: StackBlitz
For your exemple try this
<table mat-table [dataSource]="dataSource" multiTemplateDataRows>
<ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef rowspan="2">state</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" >alabama</td>
</ng-container>
<ng-container matColumnDef="utility">
<th mat-header-cell *matHeaderCellDef rowspan="2">utility company</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" >company1</td>
</ng-container>
<ng-container matColumnDef="data1">
<th mat-header-cell *matHeaderCellDef>{{'data1' | translate}}</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" >3.45</td>
</ng-container>
<ng-container matColumnDef="data2">
<th mat-header-cell *matHeaderCellDef>{{'data2' | translate}}</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" >1.73</td>
</ng-container>
<ng-container matColumnDef="data3">
<th mat-header-cell *matHeaderCellDef>{{'data3' | translate}}</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" >0.58</td>
</ng-container>
<ng-container matColumnDef="summer">
<th mat-header-cell *matHeaderCellDef colspan="3">{{'summer period' | translate}}</th>
<td mat-cell *matCellDef="let company;let i = dataIndex" ></td>
</ng-container>
<tr mat-row *matHeaderRowDef="['state','utility','data1','data2','data3']"></tr>
<tr mat-row *matHeaderRowDef="['summer']"></tr>
<tr mat-row *matRowDef="let element; columns:['state','utility','data1','data2','data3']"></tr>
</table>
I just reverse the order of the summer row because seem to not work this way