I'm having trouble finding an answer on how to merge columns cells in mat-table. Only saw few examples in merging row cells using when
. So was wondering if i can find answers here.
I have this JSON data:
{
"id": 4,
"description": "this is another block",
"block_size": 3480,
"lot_count": 5,
"lots": [
{
"id": 17,
"lot_name": "test 17",
"status": "SOLD",
"block_id": 4,
"lot_id": 1,
"lot_size": 828
},
{
"id": 18,
"lot_name": "test 18",
"status": "OPEN",
"block_id": 4,
"lot_id": 2,
"lot_size": 885
},
{
"id": 19,
"lot_name": "test 19",
"status": "SOLD",
"block_id": 4,
"lot_id": 3,
"lot_size": 648
},
{
"id": 20,
"lot_name": "test 20",
"status": "OPEN",
"block_id": 4,
"lot_id": 4,
"lot_size": 553
},
{
"id": 21,
"lot_name": "Test 21",
"status": "OPEN",
"block_id": 4,
"lot_id": 5,
"lot_size": 566
}
]
}
And was expecting an output in mat-table as:
+------------------------------------------------------------------+
| No. Lot Name Block Block Size Lot Id Lot Size |
+------------------------------------------------------------------+
| 17 test 17 1 828 |
| 18 test 18 2 885 |
| 19 test 19 4 3480 3 648 |
| 20 test 20 4 553 |
| 21 test 21 5 566 |
+------------------------------------------------------------------+
As you can see I want to make the cells in columns Block and Block Size to merge.
Meanwhile you probably found a solution to your problem but since I just created the following StackBlitz
, I share it in case someone else looks for a solution to the same issue.
https://stackblitz.com/edit/angular-gevqvq
The
RowSpanComputer
class from this solution is based on code found in the open source project Koia. In there, the computedrowspan
attributes are used withinsummary-table.component.html
.
UPDATE
The code example in the above linked StackBlitz works only for optimistic cases. Ideally no row spans are computed for the last table column, otherwise rows are not displayed if they are identical to the previous one.
ngOnInit() {
this.columnNames = Object.keys(this.data[0]);
this.lastColumnName = this.columnNames[this.columnNames.length - 1];
this.allButLastColumnNames = this.columnNames.slice(0, -1);
this.rowSpans = this.rowSpanComputer.compute(this.data, this.allButLastColumnNames);
}
In the HTML template this must also be taken into account. There we treat the preceding and the last column differently.
<table mat-table *ngIf="rowSpans" [dataSource]="data" class="mat-elevation-z8">
<ng-container *ngFor="let columnName of allButLastColumnNames; let iCol = index" [matColumnDef]="columnName">
<th mat-header-cell *matHeaderCellDef>{{ columnName }}</th>
<td mat-cell *matCellDef="let row; let iRow = index" [attr.rowspan]="rowSpans[iCol][iRow].span"
[style.display]="rowSpans[iCol][iRow].span === 0 ? 'none' : ''">{{ row[columnName] }}</td>
</ng-container>
<ng-container [matColumnDef]="lastColumnName">
<th mat-header-cell *matHeaderCellDef>{{ lastColumnName }}</th>
<td mat-cell *matCellDef="let row; let iRow = index">{{ row[lastColumnName] }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnNames"></tr>
<tr mat-row *matRowDef="let row; columns: columnNames"></tr>
</table>
Please take a look at this improved StackBlitz and see how it works.