Angular Material Table + Sorting + Pagination

By Arvind Rai, November 04, 2023
This page will walk through Angular Material table with sorting and pagination. To support Angular Material table we need to import MatTableModule, for sorting, import MatSortModule and for pagination, import MatPaginatorModule in application module. To create Angular material table, we need to use mat-table directive and dataSource in <table> element. dataSource is the source of data for table. It can be either simple data array or Observable of data array or a DataSource instance. For sorting we need to use matSort directive in <table> element and for pagination we need to use <mat-paginator> outside the <table> element. MatTableDataSource is a data source that accepts client-side data array and provides native supports for filtering, sorting and pagination.

1. Install Angular Material

Find the steps to install Angular Material in our Angular application.
1. Install Angular CLI using the link and create an Angular project.
2. Install following packages.
npm install --save @angular/material @angular/cdk 
Angular material also requires @angular/animations, if not already installed, then install it, too.
npm install --save @angular/animations 
3. Import BrowserAnimationsModule in application module.
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

@NgModule({
   imports: [BrowserAnimationsModule],
   ------
})
export class AppModule { } 
4. In styles.css, include a theme.
@import "~@angular/material/prebuilt-themes/indigo-pink.css"; 
5. To add material icon, we can use following link in our index.html. This step is optional.
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 

2. Table

To use Angular Material table in our Angular application, we need to import MatTableModule in application module.
import { MatTableModule } from '@angular/material/table'; 
Add MatTableModule into imports metadata of @NgModule decorator.
Now find the HTML code snippet for table.
<table mat-table [dataSource]="dataSource" >
  <ng-container matColumnDef="title">
    <th mat-header-cell *matHeaderCellDef> Title </th>
    <td mat-cell *matCellDef="let element"> {{element.title}} </td>
  </ng-container>
  ------
  
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> 
mat-table
mat-table is the selector of MatTable directive. MatTable is the wrapper for CdkTable. The CdkTable is a customizable table. It has dynamic columns and accessible DOM structure.

dataSource
It is the source of data for table. We can provide it in three ways. It can be either simple data array or Observable of data array or a DataSource instance.

matHeaderCellDef
matHeaderCellDef is the selector of MatHeaderCellDef directive. It defines header cell.

mat-header-cell
mat-header-cell is the selector of MatHeaderCell directive that adds right classes and role to header cell.

matCellDef
matCellDef is the selector of MatCellDef directive. It defines cell value.

mat-cell
mat-cell is the selector of MatCell directive that adds right classes and role to data cell.

matHeaderRowDef
matHeaderRowDef is the selector of MatHeaderRowDef directive that defines header row properties such as columns to display.

mat-header-row
mat-header-row is the selector of MatHeaderRow directive that adds right classes and role to cell outlet of header row.

matRowDef
matRowDef is the selector of MatRowDef directive that defines data row definition such as columns to display.

mat-row
mat-row is the selector of MatRow directive that defines right classes and role to the cell outlet of data row.

MatTableDataSource
MatTableDataSource is a data source that accepts client-side data array and provides native supports for filtering, sorting and pagination. In this case column name and data property name should be same. Find the code to get dataSource in our demo application.
import { MatTableDataSource } from '@angular/material';

@Component({
    selector: 'app-article',
    templateUrl: './article.component.html'
})
export class ArticleComponent {
    constructor(private articleService: ArticleService) {}
    
    displayedColumns: string[] = ['id', 'title', 'category', 'writer'];
    dataSource = new MatTableDataSource(this.articleService.getAllArticles());
   
} 

3. Sorting

To support sorting in our table we need to import MatSortModule in application module.
import { MatSortModule } from '@angular/material/sort'; 
Add MatSortModule into imports metadata of @NgModule decorator.
Now add matSort directive to the table and mat-sort-header directive to each column header cell that needs sorting.
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
   <ng-container matColumnDef="title">
     <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>
     <td mat-cell *matCellDef="let element"> {{element.title}} </td>
   </ng-container>
    ------
</table> 
matSort is the selector of MatSort directive that manages the sort state and provide default sort parameters. mat-sort-header is the selector of MatSortHeader directive that applies sorting behavior and styles. It allows clicking header element to change sorting and displays arrow for sort direction.
Now we need to assign MatSort to our dataSource.
@ViewChild(MatSort) sort: MatSort;
ngOnInit() {
   this.dataSource.sort = this.sort;
} 
MatSort is imported from @angular/material library.

4. Pagination

To support pagination we need to import MatPaginatorModule in application module.
import { MatPaginatorModule } from '@angular/material/paginator'; 
Add MatPaginatorModule into imports metadata of @NgModule decorator.
Now to paginate the table data we need to add <mat-paginator> outside the table. It provides navigation for paged information of a table.
<div class="mat-elevation-z8">
  <table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
    ------
  </table>
  <mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div> 
pageSizeOptions: Set of provided page size options to display to the user.
showFirstLastButtons: It shows the first/last button to the user.
Now we need to assign paginator to data source.
@ViewChild(MatPaginator) paginator: MatPaginator;   
ngOnInit() {
   this.dataSource.paginator = this.paginator;
} 
MatPaginator is imported from @angular/material library.

5. Complete Example

Find the project structure of our demo application.
my-app
|
|--src
|   |
|   |--app 
|   |   |
|   |   |--article.component.ts
|   |   |--article.component.html
|   |   |--article.ts
|   |   |--article.service.ts
|   |   |
|   |   |--app.component.ts
|   |   |--app.module.ts 
|   | 
|   |--main.ts
|   |--index.html
|   |--styles.css
|
|--node_modules
|--package.json 
Find a complete code of data table with sorting and pagination.
article.component.ts
import { Component, AfterViewInit, ViewChild } from '@angular/core';

import { ArticleService } from './article.service';
import { MatTableDataSource, } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';

@Component({
    selector: 'app-article',
    templateUrl: './article.component.html'
})
export class ArticleComponent implements AfterViewInit {
    @ViewChild(MatSort) sort = {} as MatSort;
    @ViewChild(MatPaginator) paginator = {} as MatPaginator;

    constructor(private articleService: ArticleService) { }

    displayedColumns: string[] = ['id', 'title', 'category', 'writer'];
    dataSource = new MatTableDataSource(this.articleService.getAllArticles());

    ngAfterViewInit() {
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
    }
} 
article.component.html
<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> No. </th>
      <td mat-cell *matCellDef="let element"> {{element.id}} </td>
    </ng-container>
  
    <!-- Title Column -->
    <ng-container matColumnDef="title">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>
      <td mat-cell *matCellDef="let element"> {{element.title}} </td>
    </ng-container>
  
    <!-- Category Column -->
    <ng-container matColumnDef="category">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Category </th>
      <td mat-cell *matCellDef="let element"> {{element.category}} </td>
    </ng-container>
  
    <!-- Writer Column -->
    <ng-container matColumnDef="writer">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Writer </th>
      <td mat-cell *matCellDef="let element"> {{element.writer}} </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, 20]" showFirstLastButtons></mat-paginator>
</div> 
article.ts
export interface Article {
    id: number;
    title: string;
    category: string;
    writer: string;
} 
article.service.ts
import { Injectable } from '@angular/core';
import { Article } from './article';

const All_ARTICLES: Article[] = [
  {id: 1, title: 'Angular 2 Tutorial', category: 'Angular', writer: 'Krishna'},
  {id: 2, title: 'Angular 6 Tutorial', category: 'Angular', writer: 'Mahesh'},
  {id: 3, title: 'Spring MVC tutorial', category: 'Spring', writer: 'Aman'},
  {id: 4, title: 'Spring Boot tutorial', category: 'Spring', writer: 'Suraj'},
  {id: 5, title: 'FreeMarker Tutorial', category: 'FreeMarker', writer: 'Krishna'},
  {id: 6, title: 'Thymeleaf Tutorial', category: 'Thymeleaf', writer: 'Mahesh'},
  {id: 7, title: 'Java 8 Tutorial', category: 'Java', writer: 'Aman'},
  {id: 8, title: 'Java 9 Tutorial', category: 'Java', writer: 'Suraj'}
];

@Injectable({
   providedIn: 'root'
})
export class ArticleService {
   getAllArticles() {
       return All_ARTICLES;
   }
} 
app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <app-article></app-article>
  ` 
})
export class AppComponent {
} 
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatTableModule } from '@angular/material/table';
import { MatSortModule } from '@angular/material/sort';
import { MatPaginatorModule } from '@angular/material/paginator';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { ArticleComponent } from './article.component';

@NgModule({
  declarations: [
    AppComponent,
    ArticleComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatTableModule,
    MatSortModule,
    MatPaginatorModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } 
styles.css
@import "~@angular/material/prebuilt-themes/indigo-pink.css";

table {
    width: 100%;
} 

Find the print screen of the output.
Angular Material Table + Sorting + Pagination

7. References

Table
Sort Header
Paginator

8. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us