19

I'm trying to add rowSpan and colSpan in Angular material Table header. Can anyone help me to achieve it.

Below is the Attached Header I want to get using material table

enter image description here

D C
  • 708
  • 1
  • 6
  • 17

5 Answers5

26

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 Table row span

You can follow my link to know more: StackBlitz

Minh Thuận
  • 387
  • 2
  • 9
  • 2
    I have been looking to combine fixed column effect with colSpan. This helped a lot. However it only works with the older tag not tag.
    – Selam Getachew Jul 28 '19 at 20:12
  • I saw it also working with tag . Using mat-table it's not make sense with me. – Minh Thuận Jul 29 '19 at 07:37
  • for simple hard-coded stuff like `[attr.rowspan]="2"`, you can get away with just a simpler `rowspan="2"`, since it's static, and doesn't need to be dynamic – Jared Apr 05 '21 at 20:42
  • 1
    The same thing goes for the styling `style="display:none;"` will work fine for your hidden cell as well. – Jared Apr 05 '21 at 20:49
18

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.

Lolmewn
  • 1,491
  • 4
  • 17
  • 38
1

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

scipper
  • 2,944
  • 3
  • 22
  • 45
Lilian Bideau
  • 186
  • 2
  • 15
0

I just used [attr.colspan] and [attr.rowspan] on my material table

<table mat-table> 
 <ng-container matColumnDef="{{displayedColumns[0]}}">
    <th
      mat-header-cell
      class="text-center"
      *matHeaderCellDef>          
    </th>
    <td
      mat-cell
      class="text accent text-center"
      *matCellDef="let item">
    </td>
    <!-- usage example -->
    <td
      [attr.colspan]="displayedColumns.length"
      mat-footer-cell
      *matFooterCellDef>
    </td>
 </ng-container>
        .............
 <tbody>
   <tr
     mat-header-row
     class="mat-table-row-sm header-accent-separator"
     *matHeaderRowDef="displayedColumns; sticky: true"></tr>
   <tr
     mat-row
     class="mat-table-row-sm"
     *matRowDef="let row; columns: displayedColumns;"></tr>
   <tr
     mat-footer-row
     class="mat-table-row-sm position-relative"
     *matFooterRowDef="[displayedColumns[0]]; sticky: true">
    <!-- matFooterRowDef can be the count of columns -->
   </tr>
 </tbody>
</table>
Ashot Aleqsanyan
  • 4,252
  • 1
  • 15
  • 27
-1

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:

enter image description here

Ref: Serendipity CRM

Robinyo
  • 586
  • 4
  • 11