Hey guys, in this post we
are going to see how to make expandable/collapsible rows with the angular
material table. Angular material table already provided us a solution for
expandable/collapsible rows but, at a time we can expand only one row. So
here we are going to see how to expand/collapse multiple rows at the same time, and
very important is without installing any third-party package or tool. Let’s do it step by step.
[You can download the
project on the link given below at the end of the page]
[If you have any problem related to the Angular material table please check our following posts:
Click here for a simple material table with searching, sorting, and pagination,
Click here for inline editing and validation with template-driven forms in the angular material table,
Click here for add/remove columns dynamically in the angular material table,
Click here for a table inside a row and multiple paginators in the angular material table]
At the HTML side, we have
created one material table to show the data of a student and added an expandable
row after completing all columns definition. Here we have everything the same as
angular material table expandable row, but we have changed the way, how the expandable row expands and how it gets data.
We have added separate
field in student object to maintain the state of row (expanded/collapsed) and
applied an expanded and collapsed class based on state. You can check the following
HTML for the same.
app.component.html
<div class="row">
<div class="col-12 text-center">
<label for="Heading" class="form-control">
Multiple expandable / collapseble rows - angular Material Table
</label>
</div>
</div>
<div class="row justify-content-center">
<div class="col-8">
<div class="example-container mat-elevation-z8">
<mat-table #table [dataSource]="dataSource" multiTemplateDataRows>
<!-- Expand Column -->
<ng-container matColumnDef="expand">
<mat-header-cell *matHeaderCellDef> Expand </mat-header-cell>
<mat-cell *matCellDef="let element">
<span *ngIf="!element.isExpanded" class="signs">+</span>
<span *ngIf="element.isExpanded" class="signs">-</span>
</mat-cell>
</ng-container>
<!-- Roll No Column -->
<ng-container matColumnDef="rollNo">
<mat-header-cell *matHeaderCellDef> Roll No </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.rollNo}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<!-- Marks Column -->
<ng-container matColumnDef="marks">
<mat-header-cell *matHeaderCellDef> Marks </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.marks}} </mat-cell>
</ng-container>
<!-- Standard Column -->
<ng-container matColumnDef="standard">
<mat-header-cell *matHeaderCellDef> Standard </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.standard}} </mat-cell>
</ng-container>
<!-- Expanded Content Column - The detail row is made up of this one column -->
<ng-container matColumnDef="expandedDetail">
<mat-cell *matCellDef="let detail">
<p>hey this is expanded block
You can Put here any static content as well as dynamic content</p>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" matRipple class="element-row"
[class.expanded]="row.isExpanded" (click)="expandCollapse(row)"></mat-row>
<mat-row *matRowDef="let row; columns: ['expandedDetail'];"
[@detailExpand]="row.isExpanded == true ? 'expanded' : 'collapsed'" style="overflow: hidden">
</mat-row>
</mat-table>
</div>
</div>
</div>
In typescript file we have
first defined student’s blueprint/structure to hold the data and added
isExpanded an extra variable to manage the state. Here we can have multiple
ways to manage the same, we can add an extra variable or we can create a separate
array to hold the state of each row, but we choose to add extra variable
because it is less confusing and easy to use.
Then added some data of
student and bonded with the material table.
Here we have just written
a one function which changes the state of a row from collapsed to expanded and
expanded to collapsed. You can check following ts file for the same.
app.component.ts
import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';
import { MatTableDataSource } from '@angular/material';
export interface Student {
rollNo: number;
name: string;
marks: number;
standard: string;
isExpanded: boolean;
}
const data: Student[] = [
{ isExpanded: false, rollNo: 1, name: 'Ramesh', marks: 78, standard: '10' },
{ isExpanded: false, rollNo: 2, name: 'Suresh', marks: 56, standard: '12' },
{ isExpanded: false, rollNo: 3, name: 'Adi', marks: 77, standard: '7' },
{ isExpanded: false, rollNo: 4, name: 'Rina', marks: 57, standard: '9' },
{ isExpanded: false, rollNo: 5, name: 'Tapil', marks: 66, standard: '9' },
{ isExpanded: false, rollNo: 6, name: 'Sugul', marks: 88, standard: '5' },
{ isExpanded: false, rollNo: 7, name: 'Aftar', marks: 46, standard: '5' },
{ isExpanded: false, rollNo: 8, name: 'Oxa', marks: 57, standard: '5' },
{ isExpanded: false, rollNo: 9, name: 'Tam', marks: 76, standard: '5' },
{ isExpanded: false, rollNo: 10, name: 'Luis', marks: 87, standard: '7' }
];
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', visibility: 'hidden' })),
state('isExpanded', style({ height: '*', visibility: 'visible' })),
transition('isExpanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class AppComponent {
displayedColumns = ['expand', 'rollNo', 'name', 'marks', 'standard'];
dataSource = new MatTableDataSource<Student>();
constructor() {
this.dataSource.data = data;
}
expandCollapse(row) {
if (row.isExpanded) {
row.isExpanded = false;
} else {
row.isExpanded = true;
}
}
}
Small
CSS code to make +, - button bold and large.
app.component.css
.signs{
font-weight: bolder;
font-size: large;
}
Here
is the sample output screenshot
That’s
it, we have successfully implemented a demo for multiple expandable/collapsible
rows in the angular material table. Hope you like it.
Here
is the demo
[download the demo]
[ If you are preparing for an interview please click here - angular interview questions and answers ]
[ If you are preparing for an interview please click here - angular interview questions and answers ]
Comments
Post a Comment