-
Notifications
You must be signed in to change notification settings - Fork 0
Material Table
So, here you can see a tutorial for the angular material prebuild table, including button columns, rows sorting and filtering:
Sourse code: https://github.com/sefirus/material-table-example
- For the record, table is made to represent the folloving class:
export interface Procedure {
id: number;
name: string;
description: string;
duration: number;
cost: number;
}
At first, you need to install and add amgular material to your project using these commands:
npm i -g @angular/material
ng add @angular/material
At first, go to app.module.ts and import the following modules:
import { MatFormFieldModule } from '@angular/material/form-field'; //Specially for filtering
import { MatInputModule } from '@angular/material/input' //Specially for filtering
import { MatSortModule } from '@angular/material/sort'; //Specially for sorting
import { MatButtonModule } from '@angular/material/button'; //Specially for buttons
import { MatTableModule } from '@angular/material/table';
*Dont forget to write all of them inside imports
Than, create new component and go to the component`s typescript file, and import the following items:
import { MatSort } from '@angular/material/sort'; //Specially for sorting
import { ViewChild } from '@angular/core'; //Specially for sorting
import { MatTableDataSource } from '@angular/material/table';
After importing all libraries, go to the component`s typescript file, and under the imports section create a new array with the sample data for the table:
const DATA_SOURCE: Procedure[] = [
{
"id": 1,
"name": "first procedure",
"cost": 10,
"description": "first procedure desription",
"duration": 30
},
{
"id": 2,
"name": "second procedure",
"cost": 25,
"description": "sknd procedure desription",
"duration": 25
},
{
"id": 3,
"name": "third procedure",
"cost": 30,
"description": "thrd procedure desription",
"duration": 10
},
{
"id": 4,
"name": "fourth procedure",
"cost": 45,
"description": "frth procedure desription",
"duration": 40
},
{
"id": 5,
"name": "fifth procedure",
"cost": 50,
"description": "fifth procedure desription",
"duration": 35
},
{
"id": 6,
"name": "six procedure",
"cost": 65,
"description": "six procedure desription",
"duration": 15
},
{
"id": 7,
"name": "sevens procedure",
"cost": 70,
"description": "sevens procedure desription",
"duration": 10
}
]
Next, go to the component`s class, and create two following wariables inside it:
dataSource: MatTableDataSource<Procedure> = new MatTableDataSource(DATA_SOURCE); //Special data class to handle a table
displayedColumns: string[] = ['name', 'cost', 'description', 'duration', 'button']; //List of column names to be displayed
Than, go to the component`s html file and paste the following code:
-
mat-mable
inditates that table is a part of @angular/material so it can use all the features -
[dataSource]
stands for data sourse of the table. In fact, you can pass here any array with corresponding set of properties
<table
mat-table
[width]="700"
[dataSource]="dataSource">
</table>
So, we created a basic structureof the component. Now you can`t see any table elements or colums, but a blank page, because they are not defined in html (in fact, you need to define all the columns from the displayedColumns list)
So, lets paste html code for the columns to the table:
-
ng-container
stands for the definition of column`s container -
matColumnDef=""
stands for the element of thedisplayedColumns
list whitc column will represent -
mat-header-cell
with*matHeaderCellDef
stand for definition of column`s header -
mat-cell
stands for the definition of table cell -
*matCellDef="let element"
stands for the declaration of row`s wariable -
mat-header-row
andmat-row
stand for definition of the row -
*matHeaderRowDef="displayedColumns"
stands for the declaration of header row columns -
*matRowDef="let row; columns: displayedColumns;"
stands for the declaration of regular row, withdisplayedColumns
for columns of the row
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="cost">
<th mat-header-cell *matHeaderCellDef> Cost(T) </th>
<td mat-cell *matCellDef="let element"> {{element.cost}} </td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> Description </th>
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
</ng-container>
<ng-container matColumnDef="duration">
<th mat-header-cell *matHeaderCellDef> Duration </th>
<td mat-cell *matCellDef="let element"> {{element.duration}} </td>
</ng-container>
<ng-container matColumnDef="button">
<th mat-header-cell *matHeaderCellDef> Delete </th>
<td mat-cell *matCellDef="let element">
<button mat-raised-button (click)="onButtonclick(element)">B</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
Now, lets declare a method inside component`s class, that button will fire on click:
onButtonclick(element : Procedure){
console.log(element);
}
*Note thaе i can pass an object of cells type to the method, called from cell (click on the first row
s button):
Here we are! Now we have a basic angular material table:
Now, lets add sort to the table. At first, declare a new MatSort object with decorator inside of the component's class, right under the displayedColumns:
@ViewChild(MatSort) sort?: MatSort;
Than, we need to assign recently created sort to the dataSources sort property, but only anfter the view is initialized. Lets create a standart method
ngAfterViewInit()` to do it:
ngAfterViewInit(): void{
this.dataSource.sort = this.sort!;
}
Than, we need to add matSort
directive to the table definition and mat-sort-header
attribute to every column header of table. So, everything must look like this:
Here we are! We added sort to tables rows:
NOTE: You can play with different styles of sort direction arrow by using matSortXXX
directives on the table definition
Now, lets add filtering to the table. At first, we need to create an input field, to retrieve a pattern to filter. Lets do in using angular material predifined mat-form-field
input^:
<mat-form-field style="width: 700px;" appearance="outline">
<mat-label>Filter</mat-label>
<input matInput placeholder="Placeholder" #input>
</mat-form-field>
So, here we created such an inpur field:
NOTE: You can choose any different input field
Now, lets inplement a method that will get failter pattern from passed event and perform angular built-in filtering:
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
NOTE: this method searches every column of the table
And, last but not least, we need to call the method from the html input when te key is pressed. So, lets add direcrive (keyup)="applyFilter($event)"
to the input tag like that:
Here we are! Now we have fully implemented table with sorting and fitering!