Custom Pagination Component In Angular 6

Introduction

 
Today, we will learn how to create a custom component for Pagination in Angular and also, how to use the component in another component as a child component.
 
Code 
 
Full code available on my github repository app-pagination . Please do contribute on my github reposiotry for enhacements and optimizations.

Prerequisites

Basic knowledge of Angular components/modules and TypeScript.
 
Here, I will create a custom component for pagination and will show you how to use that component in your app. Before proceeding, you must have  basic knowledge of Angular.
 
I am assuming that you have already created an Angular app. Here, I'll show how to create a component in your existing app.
 
Note
I will use bootstrap 4 for designing the pagination component, So, you have to install the bootstrap package too in your existing app.

Step 1

Create a folder named app-pagination in your app's component folder. We will create all the components and modules in this folder only.

Step 2

Now, we will create the component for pagination. You can create the component by executing the below command in the app-pagination directory created in the first step.
  1. ng generate component app-pagination  
The above command will generate .ts and .html files for our component. Paste the below code in the app-pagination.component.ts file generated from above command.
 
app.pagination.component.ts
  1. import { Component , Input , OnChanges , Output , EventEmitter} from '@angular/core';  
  2.   
  3. @Component({  
  4.   selector: 'app-pagination',  
  5.   templateUrl: './app-pagination.component.html'  
  6. })  
  7.   
  8. export class PaginationComponent implements OnChanges {  
  9.   
  10.     @Input() totalRecords = 0;  
  11.     @Input() recordsPerPage = 0;  
  12.   
  13.     @Output() onPageChange: EventEmitter<number> = new EventEmitter();  
  14.   
  15.     public pages: number [] = [];  
  16.     activePage: number;  
  17.   
  18.     ngOnChanges(): any {  
  19.       const pageCount = this.getPageCount();  
  20.       this.pages = this.getArrayOfPage(pageCount);  
  21.       this.activePage = 1;  
  22.       this.onPageChange.emit(1);  
  23.     }  
  24.   
  25.     private  getPageCount(): number {  
  26.       let totalPage = 0;  
  27.   
  28.       if (this.totalRecords > 0 && this.recordsPerPage > 0) {  
  29.         const pageCount = this.totalRecords / this.recordsPerPage;  
  30.         const roundedPageCount = Math.floor(pageCount);  
  31.   
  32.         totalPage = roundedPageCount < pageCount ? roundedPageCount + 1 : roundedPageCount;  
  33.       }  
  34.   
  35.       return totalPage;  
  36.     }  
  37.   
  38.     private getArrayOfPage(pageCount: number): number [] {  
  39.       const pageArray = [];  
  40.   
  41.       if (pageCount > 0) {  
  42.           for(let i = 1 ; i <= pageCount ; i++) {  
  43.             pageArray.push(i);  
  44.           }  
  45.       }  
  46.   
  47.       return pageArray;  
  48.     }  
  49.   
  50.     onClickPage(pageNumber: number): void {  
  51.         if (pageNumber >= 1 && pageNumber <= this.pages.length) {  
  52.             this.activePage = pageNumber;  
  53.             this.onPageChange.emit(this.activePage);  
  54.         }  
  55.     }  
  56. }  
 Here, we have created the pagination component. This component is accepting two inputs - TotalRecords and RecordsPerPage,
  1. RecordsPerPage is used for the number of items we want to display in single page. 
  2. TotalRecords is used for the total number of items count which we want to display in pages.
 Also, we have created EventEmitter which will emit the currently active page number to parent component whenever we will click on the page number.
 
Step 3
 
Paste the below code in app-pagination.component.html file.
  1. <nav aria-label="page navigation example">  
  2.   <ul class="pagination">  
  3.     <li class="page-item" (click)="onClickPage(activePage - 1)"><a class="page-link" href="javascript:void(0);">«  
  4.         Previous</a></li>  
  5.     <li class="page-item" [ngClass]="{'active': activePage === item}" *ngFor="let item of pages"  
  6.       (click)="onClickPage(item)"><a class="page-link" href="javascript:void(0);">{{item}}</a></li>  
  7.     <li class="page-item" (click)="onClickPage(activePage + 1)"><a class="page-link" href="javascript:void(0);">Next  
  8.         »</a></li>  
  9.   </ul>  
  10. </nav>  
Here, we have added the HTML template for our component. We have used *ngFor directive to iterate over all the page counts and display those pages in li element. We have bound the click event of li to onClickPage() method which we have defined in app-pagination.component.ts.
 
Step 4 
 
Now, we will create the module for the above created component so, that we can use this component in any other component.
 
Note
You can directly use this component by directly declaring this component in the app.module.ts file without creating a separate module for this component. But this approach will not enable lazy loading. To enable the advantage of lazy loading, we will declare this component in a separate module.
 
Create the app-pagination.module.ts file in app-pagination directory created in the first step and paste the below code.
  1. import { NgModule } from '@angular/core';  
  2. import { CommonModule} from '@angular/common';  
  3.   
  4. import {PaginationComponent} from './app-pagination.component';  
  5.   
  6. @NgModule({  
  7.     declarations: [  
  8.         PaginationComponent  
  9.     ],  
  10.     imports: [  
  11.         CommonModule  
  12.     ],  
  13.     exports: [  
  14.         PaginationComponent  
  15.     ]  
  16. })  
  17. export class PaginationModule  
  18. {  
  19. }  
Here, we have declared our component in declaration [] and exported the same component so we can use this component in another module. Our component is ready to use in another component. Now, I will demonstrate how to use this pagination component in any other component.
 
Note
For the sake of simplicity, I will use this component app.component but you can use it any of the components.
 
Step 5
 
Import the PaginationModule created in the above step in app.module.ts file so that we can use the created component in app.component.
 
Step 6
 
Paste the below code in app.component.ts file.
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.   selector: 'app-root',  
  5.   templateUrl: './app.component.html',  
  6.   styleUrls: ['./app.component.scss']  
  7. })  
  8. export class AppComponent {  
  9.   activePage:number = 0;  
  10.   
  11.   displayActivePage(activePageNumber:number){  
  12.     this.activePage = activePageNumber  
  13.   }  
  14. }  
Here, we have created one method, i.e., displayActivePage() to catch the emitted value of active page from child component.
 
Step 7
 
Paste the below code in app.component.html.
  1. <div class="container">  
  2.     <div class="row">  
  3.         <div class="col-md-12 text-center">  
  4.             <h4>Simple Table</h4>  
  5.         </div>  
  6.         <div class="col-lg-8 col-md-10 ml-auto mr-auto">  
  7.             <div class="table-responsive">  
  8.                 <table class="table table-striped">  
  9.                     <thead>  
  10.                         <tr>  
  11.                             <th class="text-center">#</th>  
  12.                             <th>Product Name</th>  
  13.                             <th>Type</th>  
  14.                             <th>Qty</th>  
  15.                             <th class="text-right">Price</th>  
  16.                             <th class="text-right">Amount</th>  
  17.                         </tr>  
  18.                     </thead>  
  19.                     <tbody>  
  20.                         <tr>  
  21.                             <td class="text-center">1</td>  
  22.                             <td>Moleskine Agenda</td>  
  23.                             <td>Office</td>  
  24.                             <td>25</td>  
  25.                             <td class="text-right">€ 49</td>  
  26.                             <td class="text-right">€ 1,225</td>  
  27.                         </tr>  
  28.                         <tr>  
  29.                             <td class="text-center">2</td>  
  30.                             <td>Stabilo Pen</td>  
  31.                             <td>Office</td>  
  32.                             <td>30</td>  
  33.                             <td class="text-right">€ 10</td>  
  34.                             <td class="text-right">€ 300</td>  
  35.                         </tr>  
  36.                         <tr>  
  37.                             <td class="text-center">3</td>  
  38.                             <td>A4 Paper Pack</td>  
  39.                             <td>Office</td>  
  40.                             <td>50</td>  
  41.                             <td class="text-right">€ 10.99</td>  
  42.                             <td class="text-right">€ 109</td>  
  43.                         </tr>  
  44.                         <tr>  
  45.                             <td class="text-center">4</td>  
  46.                             <td>Apple iPad</td>  
  47.                             <td>Meeting</td>  
  48.                             <td>10</td>  
  49.                             <td class="text-right">€ 499.00</td>  
  50.                             <td class="text-right">€ 4,990</td>  
  51.                         </tr>  
  52.                         <tr>  
  53.                             <td class="text-center">5</td>  
  54.                             <td>Apple iPhone</td>  
  55.                             <td>Communication</td>  
  56.                             <td>10</td>  
  57.                             <td class="text-right">€ 599.00</td>  
  58.                             <td class="text-right">€ 5,999</td>  
  59.                         </tr>  
  60.                     </tbody>  
  61.                 </table>  
  62.             </div>  
  63.         </div>  
  64.     </div>  
  65.     <div class="row">  
  66.             <div class="col-lg-8 col-md-10 ml-auto mr-auto">  
  67.                 <span><strong>Current Active Page = </strong> {{activePage}}</span>  
  68.             </div>  
  69.     </div>  
  70.     <div class="row">  
  71.         <div class="col-lg-8 col-md-10 ml-auto mr-auto">  
  72.              <div class="float-right"> <app-pagination [totalRecords]="23" [recordsPerPage]="5" (onPageChange)="displayActivePage($event)"></app-pagination> </div>     
  73.         </div>  
  74.     </div>  
  75. </div>  

Conclusion

 
We have created the pagination component successfully and also, we have used the created component in app.component.ts. Let me know your reviews and comments. 
 
Full code available on my github repository  app-pagination . Please do contribute on my github reposiotry for enhacements and optimizations.