Search code examples
angularangular-materialangular-material-table

How to align a nested Angular Material table with its parent columns?


I am using Angular Material's table (not the display: flex version) and I am using a nested table, but I want the columns of the nested table to line up with the headings for the parent table.

This way the parent's column labels will apply to both itself and the nested table.

This is what it looks like now. But I want the 2 columns in the nested table to also be aligned such that Street aligns with "name" and the number aligns with "email".

enter image description here

Here is a stackblitz for the table.

CSS

table {
  width: 100%;
}

tr.example-detail-row {
  height: 0;
}

.example-element-row td {
  border-bottom-width: 0;
}

.example-element-detail {
  overflow: hidden;
  display: flex;
}

.inner-table {
  width: 100%;
}

HTML

<table mat-table #outerSort="matSort" [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8" matSort>
    <ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> {{column}} </th>
        <td mat-cell *matCellDef="let element"> {{element[column]}} </td>
    </ng-container>

    <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
    <ng-container matColumnDef="expandedDetail">
        <td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
            <div class="example-element-detail" *ngIf="element.addresses?.data.length" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
                <div class="inner-table mat-elevation-z8" *ngIf="expandedElement">
          <table #innerTables mat-table #innerSort="matSort" [dataSource]="element.addresses" matSort>
            <ng-container matColumnDef="{{innerColumn}}" *ngFor="let innerColumn of innerDisplayedColumns">
              <td mat-cell *matCellDef="let element"> {{element[innerColumn]}} </td>
            </ng-container>
            <tr mat-row *matRowDef="let row; columns: innerDisplayedColumns;"></tr>
          </table>
                </div>
            </div>
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
    <tr mat-row *matRowDef="let element; columns: columnsToDisplay;" [class.example-element-row]="element.addresses?.data.length"
     [class.example-expanded-row]="expandedElement === element" (click)="toggleRow(element)">
    </tr>
    <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
</table>

This stackblitz originally came from this link and I just modified it a bit.


Solution

  • It's better to use Angular Material Table Flex Version, but with adding some dirty code this will be fix:

    I added below css code to css file:

    .mat-column-name {
      width: 200px;
    }
    
    .mat-column-street {
      padding-left: 0 !important;
      width: 200px;
    }
    

    also you can see stackblitz link.

    in this way name column & street column fixed to 200px or how much you want.