Angular Material is a collection of Material Design components for an Angular app. You can apply Material Design by using these components very easily. Angular Material became very easy with the release of Angular 6. Here, we will work on Angular Material with Angular 7.
Here is the link to Angular Material: https://material.angular.io/
In this blog, we are going to learn about Angular Material Table, that is, mat-table
. The mat-table
provides a Material Design styled data-table that can be used to display rows of data.
we are going to use Angular 7 project to work with Angular Material Table component. If you are still working on Angular 6, and wants to upgrade your Angular CLI to Angular 7, here is the below link to upgrade from Angular 6 to Angular 7.
Update Angular 6 to Angular 7 version
Also, here is the link to create your first app in Angular 7 as well.
Update Angular 6 to Angular 7 version
Let’s create our Angular 7 Material app using this command.
<em>ng new angularmat</em>
In this example, angularmat
is our project name. A new project folder is created, the Angular project template is downloaded and the needed dependencies are installed. Once everything is set up, and now you are ready to run your application by using this command.
<em>ng serve --open</em>
Now, it’s a time to add Angular Material dependencies in our project.
You can use the npm command to install Angular Material, Angular CDK and Angular Animations to your project.
npm install --save @angular/material @angular/cdk @angular/animations
Once the above packages have been installed in your app, the next step is to configure the animation by importing BrowserAnimationsModule
in your app.module.ts
file.
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@NgModule({
......
imports: [
BrowserAnimationsModule
],
.....
})
export class AppModule { }
It is required to importing the Angular Material theme in your project. Open your project’s filestyles.css
, and add this line.
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
You can use Angular Material Icons in your project. Here is the official link of Material Design Icons. Open yourindex.html
and add this link in this file.
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
Now, in order to use Angular Material Table, you have to import the MatTableModule
in your module file. Open the app.module.ts
file, and import this statement.
import {MatTableModule} from '@angular/material/table';
@NgModule({
......
imports: [
MatTableModule
],
.....
})
export class AppModule { }
app.module.ts
To display data in our mat-table, let’s first create our sample data interface and populate the data. I am going to create an interface EmployeeData
having the following properties. Adding the array of employee’s names and their favorite colors as well.
Adding the array constants of employee’s names and their favorite colors. The getEmployees()
function will return the full employee data to display.
export interface EmployeeData {
Id: string;
EmpName: string;
Color: string;
Hours: number;
}
const FAVORITE_COLORS: string[] = ['gray', 'black', 'navy', 'blue', 'teal', 'green', 'purple',
'fuchsia', 'lime', 'olive', 'aqua', 'yellow', 'orange', 'red', 'maroon'];
const EMP_NAMES: string[] = ['Robert', 'Jing Jo', 'Thomas', 'Peter', 'Sam', 'Jack',
'Charlie', 'Maria', 'Julia', 'Albert', 'Arthur', 'James',
'Simran', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];
//This function will create employee data
function getEmployees(id: number): EmployeeData {
const name =
EMP_NAMES[Math.round(Math.random() * (EMP_NAMES.length - 1))] + ' ' +
EMP_NAMES[Math.round(Math.random() * (EMP_NAMES.length - 1))].charAt(0) + '.';
return {
Id: id.toString(),
EmpName: name,
Color: FAVORITE_COLORS[Math.round(Math.random() * (FAVORITE_COLORS.length - 1))],
Hours: 8
};
}
app.component.ts
Once you have setup the data for mat-table, we are now good to go to bind it with mat-table. Let’s import MatTableDataSource
in our app.component.ts file.
Update Angular 6 to Angular 7 version
Fill thedisplayedColumns
array with the name of columns to be displayed in our table. Also, mention theEmployeeData
interface as our data source. We have created aemplist
properties, and assigned the 100 employees to this list. Finally, I have passed thisemplist
to ourmat-table
data source property.
displayedColumns: string[] = ['Id', 'EmpName', 'Color', 'Hours'];
dataSource: MatTableDataSource<EmployeeData>;
emplist: any;
constructor() {
// Create 100 employees
this.emplist = Array.from({ length: 100 }, (_, k) => getEmployees(k + 1));
// Assign the data to the data source
this.dataSource = new MatTableDataSource(this.emplist);
}
app.component.ts
Next step to create our html template to bind these properties to mat-table
component. Here is the syntax of data binding in our app.component.html file.
Write your mat-table
and bind the [dataSource]
property to it.
<table mat-table [dataSource]="dataSource">
....
</table>
app.component.html
This is the simple form of binding data to mat-table. The table will take the array and render a row for each object in the data array.
After creating our mat-table
and binding its [dataSource]
, next step is to create our column template.
Each column should have a unique column name and it will contain the contents of its header and row cells.
<ng-container matColumnDef="Id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let row"> {{row.Id}} </td>
</ng-container>
app.component.html
In the above sample, we have given the unique name "Id"
to our column property matColumnDef
. Inside the ng-container
, we have defined mat-header-cell
for displaying the ID
header, and bind the data using {{row.Id}}
to mat-cell
of our template.
So the complete column bindings will be like this:
<!-- ID Column -->
<ng-container matColumnDef="Id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let row"> {{row.Id}} </td>
</ng-container>
<!-- Employee Name Column -->
<ng-container matColumnDef="EmpName">
<th mat-header-cell *matHeaderCellDef>Employee Name </th>
<td mat-cell *matCellDef="let row"> {{row.EmpName}} </td>
</ng-container>
<!-- Color Column -->
<ng-container matColumnDef="Color">
<th mat-header-cell *matHeaderCellDef> Color </th>
<td mat-cell *matCellDef="let row"> {{row.Color}} </td>
</ng-container>
<!-- Hours Column -->
<ng-container matColumnDef="Hours">
<th mat-header-cell *matHeaderCellDef>Hours </th>
<td mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.Hours}} </td>
</ng-container>
app.component.html
In the last step, we have to define row template, where we will tell the table which columns be rendered in the header and data rows. For that purpose, we have already created a variable displayedColumn
in our component class file.
Update Angular 6 to Angular 7 version
Add these two lines at the bottom of your mat-table tag to specify, which columns we are going to show.
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
app.component.html
so the complete html template will be like this.
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
<!-- ID Column -->
<ng-container matColumnDef="Id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let row"> {{row.Id}} </td>
</ng-container>
<!-- Employee Name Column -->
<ng-container matColumnDef="EmpName">
<th mat-header-cell *matHeaderCellDef>Employee Name </th>
<td mat-cell *matCellDef="let row"> {{row.EmpName}} </td>
</ng-container>
<!-- Color Column -->
<ng-container matColumnDef="Color">
<th mat-header-cell *matHeaderCellDef> Color </th>
<td mat-cell *matCellDef="let row"> {{row.Color}} </td>
</ng-container>
<!-- Hours Column -->
<ng-container matColumnDef="Hours">
<th mat-header-cell *matHeaderCellDef>Hours </th>
<td mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.Hours}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
app.component.html
Now, it is the time to run your app and see the data in the mat-table
. Run ng serve --open
in your terminal.
Showing 100 of rows in mat-table
Till now, we have implemented our basic mat-table
. Now, let’s move to the next feature of mat-table
, that is, pagination.
mat-paginator
is used to provide pagination with the mat-table
. Each paginator requires two basic things:
The paginator displays a dropdown of page sizes for the user to choose from. The options for this dropdown can be set via pageSizeOptions
The current pageSize will always appear in the dropdown, even if it is not included in pageSizeOptions
.
To implement the pagination, first of all, import the MatPaginatorModule
in your app.module.ts file. Add MatPaginatorModule
in imports[]
array as well.
import {MatTableModule} from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
.....
MatTableModule,
MatPaginatorModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.module.ts
Let’s implement the MatPaginator
in our app.component.ts file.
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatPaginator } from '@angular/material';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
.......
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor() {
......
}
ngOnInit() {
this.dataSource.paginator = this.paginator;
}
}
......
app.component.ts
Also, place <mat-paginator>
element on app.component.html file as well.
Update Angular 6 to Angular 7 version
Let me explain you about this pagination control. First of all, we importedViewChild
andMatPaginator
in our component class file. Then we accessed ourMatPaginator
control using@ViewChild(MatPaginator)
, and inngOnInit()
life-cycle hook, we assigned this paginator to ourdatasource
paginator property.
Don’t forget to put <mat-paginator>
with [pageSizeOptions]
attribute on component html file.
Mat-table with Pagination
In this step, we are going to implement mat-table sorting feature. Like other modules, we have to first import MatSortModule
in our app.module.ts file. Add this MatSortModule in import[]
array as well.
import {MatTableModule} from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material';
import {MatSortModule} from '@angular/material/sort';
import { AppComponent } from './app.component';
@NgModule({
........
imports: [
.....
MatTableModule,
MatPaginatorModule,
MatSortModule
],
......
})
export class AppModule { }
app.module.ts
Now, go to the app.component.html file, add matSort
to <table mat-table>
tag. Also, we have to add mat-sort-header
to each column. Add mat-sort-header
to <th mat-header-cell>
of each column. The complete html file looks like this:
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
<ng-container matColumnDef="Id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<td mat-cell *matCellDef="let row"> {{row.Id}} </td>
</ng-container>
<!-- Employee Name Column -->
<ng-container matColumnDef="EmpName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Employee Name </th>
<td mat-cell *matCellDef="let row"> {{row.EmpName}} </td>
</ng-container>
<!-- Color Column -->
<ng-container matColumnDef="Color">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Color </th>
<td mat-cell *matCellDef="let row"> {{row.Color}} </td>
</ng-container>
<!-- Hours Column -->
<ng-container matColumnDef="Hours">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Hours </th>
<td mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.Hours}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>
app.component.html
Notice carefully, where we have added matSort
to …
mat-sort-header
to … of each column.
Now, move to app.component.ts file, and implement the sorting over there as well.
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
.....
@ViewChild(MatSort) sort: MatSort;
......
ngOnInit() {
.....
this.dataSource.sort = this.sort;
}
}
gistfile1.txt
Let me explain this, first of all, we have imported MatSort
in our component class file. Then using @ViewChild(MatSort)
, we accessed our MatSort
component, and finally, we assigned sort
to datasource sort
property.
Mat-table sorting
Look at the table headers, you will header a sort arrow on each on mouse hover. In this picture, I sorted Employee Name, and you can an arrow on this column as well.
In this last point, I am going to show you how to filter your mat-table
.
First of all, import these statement in your app.module.ts file, and add MatFormFieldModule
and MatInputModule
in imports[]
array.
Update Angular 6 to Angular 7 version> Update Angular 6 to Angular 7 version
After importing above modules, let placematInput
field on our app.component.html file.
<h3>Filter</h3>
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
I have bind an event applyFilter()
on matInput
keyup() event, which will filter our data. Let’s create our applyFilter()
function in the component class file.
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
Mat-table filtering
The applyFilter()
is very simple. It will use the datasource.filter
property to filter the mat-table
, and if we used paginator
, it will set the first page as result.
You can download the complete project from Github.
☞ Angular RxJS: Observables, Observers and Operators Introduction
☞ The Pros and Cons of Angular Development
☞ Real Time Apps with TypeScript: Integrating Web Sockets, Node & Angular
☞ Angular 8 - Reactive Forms Validation Example
☞ Angular vs React vs Vue: Which is the Best Choice for 2019?
☞ A comparison between Angular and React
☞ Getting Started with Nx in Angular
#angular #angular-js #javascript