locked
Angular Mat-Table adding parent header to two columns which has their own subheaders RRS feed

  • Question

  • User956626884 posted

    UPDATE: I found the answer at this following link

    https://stackblitz.com/edit/angular-bklajw?file=app%2Ftable-basic-example.css

    Hello,

    I am trying to figure out how to add a parent header to a ng-container that contains two columns. I want the mat- table with a headers and the grouped columns to look like the following

    |            Bank Balances              |

    |   Prior              | Afterwards     |

    |   $1123.00       |   $2344.99       |

    |   $2134.99       |    $234.33        |

    I was able to get the Sub-headers to show with their column. I want to group both the columns in the same container and have a parent header which is their data type name. The reason why I want to group the two columns under 1 container is that if I hide some of the columns and the mat-table is reloaded, the column width adjustment will not affect the Parent and Sub-headers position. They will stay perfectly aligned.

    I tried adding a 2nd 

    <tr mat-header-row *matHeaderRowDef="displayedParentColumns; sticky: true"></tr>

    and added a parent ng-container like the following

    <ng-container matColumnDef="parentBalances">

    <ng-container matColumnDef="priorBalance"> ....

    <ng-container matColumnDef="afterBalance"> ....

    </ng-container>

    This did not work and cause the reload to prompt an error that it can't find "priorBalance". 

    Is there a way to add a parent header or something that looks a header inside the parent container that span across two columns?

    Any help is appreciated. Thanks.

    <table mat-table [dataSource]="dataSource" matSort>
    
              <ng-container id="Balances" >
                // this parent header does not show up
                <th mat-header-cell *matHeaderCellDef>Bank Balances</th>
           
                <ng-container matColumnDef="priorBalance">
                    <th mat-header-cell *matHeaderCellDef mat-sort-header><strong>Prior</strong></th>
                    <td mat-cell *matCellDef="let checkingData">
                        <ng-container *ngFor="let balance of checkingData.beforeAccounts">
                          <div *ngFor="let value of balance.values; let i = index">
                            <mat-cell> {{value.dollars}} </mat-cell>
                          </div>
                        </ng-container>
                    </td>
                </ng-container> 
               
                <ng-container matColumnDef="afterBalance">
                    <th mat-header-cell *matHeaderCellDef mat-sort-header><strong>Afterwards</strong></th>
                    <td mat-cell *matCellDef="let checkingData">
                        <ng-container *ngFor="let balance of checkingData.afterAccounts">
                          <div *ngFor="let value of balance.values; let i = index">
                            <mat-cell> {{value.dollars}} </mat-cell>
                          </div>
                        </ng-container>
                    </td>
                </ng-container> 
    
    
      <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
    </table >

    Tuesday, May 7, 2019 6:11 PM

All replies

  • User-893317190 posted

    Hi comicrage,

    If you want to add a parent header row,  you must first define it, using

    <tr mat-header-row *matHeaderRowDef="['parent1']"
          >
      </tr>

    Then you could use matColumnDet to render the parent header.

    Below is my sample code.

     <table mat-table [dataSource]="dataSource">
    
    
        <ng-container matColumnDef="parent1">
          <th mat-header-cell *matHeaderCellDef colspan="4" style="text-align: center">parent2 </th> 
        </ng-container> 
        <ng-container matColumnDef="position">
          <th mat-header-cell *matHeaderCellDef> No. </th>
          <td mat-cell *matCellDef="let element"> {{element.position}} </td>
        </ng-container>
      
        <ng-container matColumnDef= "{{ displayName}}" *ngFor=" let displayName of ['name1','name2','name3'];index as i">
            <th mat-header-cell *matHeaderCellDef> {{ displayName}}</th>
           <td mat-cell *matCellDef="let srow">  {{ srow.names[i].name}}
          </ng-container>
    
        
          class="example-second-header-row">
      </tr> -->
      <tr mat-header-row *matHeaderRowDef="['parent1']"
          class="example-second-header-row">
      </tr>
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
       
       
       </table>
       

    Please pay  attention the mat-header-row definition is ordered, if you put mat-header-row *matHeaderRowDef="['parent1']" after <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> , it will show after child header.

    If you want to show two parent header , you could refer

       
       <table mat-table [dataSource]="dataSource">
    
        <!--render two parent headers-->
        <ng-container matColumnDef="parent1">
          <th mat-header-cell *matHeaderCellDef colspan="2">parent1</th>
        </ng-container>
        <ng-container matColumnDef="parent2">
          <th mat-header-cell *matHeaderCellDef colspan="2">parent2 </th>
        </ng-container>
       
        <ng-container matColumnDef="position">
          <th mat-header-cell *matHeaderCellDef> No. </th>
          <td mat-cell *matCellDef="let element"> {{element.position}} </td>
        </ng-container>
      
       
     
      
    
        <ng-container matColumnDef= "{{ displayName}}" *ngFor=" let displayName of ['name1','name2','name3'];index as i">
            <th mat-header-cell *matHeaderCellDef> {{ displayName}}</th>
           <td mat-cell *matCellDef="let srow">  {{ srow.names[i].name}}
          </ng-container>
               <! -- def two parent header columns-->
          <tr mat-header-row *matHeaderRowDef="['parent1','parent2']"
          class="example-second-header-row">
      </tr>
     
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
       
       
       </table>

    The result

    Please refer to mat-table's official document https://material.angular.io/components/table/examples

    It includes  muti-headers and muti-footers.

    Best regards,

    Ackerly Xu

    Wednesday, May 8, 2019 2:05 AM