Introduction
In this article we are going to learn how we create server side pagination which is very useful whenever we need to display large number of records.
This is part 2nd of it you can check its 1st Part by clicking the below link.
So here we are displaying number of records and with that it will calculate the number of pages but in one page we can see only selected records so rather than fetching all records at one time we are going to fetch records based on pages this will increase our performance.Also we are designing previous and next button which will work differently.
How it will work ?
In this Part we are working on the Prev and Next button and its logic ,basically what we have seen is whenever we clicks on next button it shows the just next page records of the following page for example suppose you are on page 1 and when you click on next it would show page 2 records sounds very simple but here in this article I am using different approach let me clarify my point with one more example suppose total we have 7 pages and in one page only 5 pages should show then next two page will come after you click on next button,so if you are in page 1 when you click on next then it would not show page 2 records it will change the page track and show you next page i.e page 6 and page 7(page 6 is the active one here) .
BACK END
Here in 1st Part we already have  created database and tables so no need to create it again if you don't have the related database,tables and  stored procedure,then I strongly recommend you do and check its 1st part link is in the top .
FRONT END
This is a step wise process we are going to change some of the code in some files so without wasting any time in adding components and services lets move to step 1.
Step 1: Lets copy this html code and replace it to pagination.html file,some changes as compared to previous part code here we are adding new buttons for checking companies per page like 5,10,15 by default 5,when you click on 10 then 10 records will show per page and according to that pages are calculating .

Also i have added previous and next button with some styles so that user can move from one page field to another directly.
  1. <div class="row">  
  2. <div class="col-12 col-md-12">  
  3. <div class="card">  
  4. <div class="card-header">  
  5. <div class="row">  
  6. <div>  
  7. Companies 1-{{pageSize}} (Total:{{totalCompaniesCount}})  
  8. </div>  
  9.   
  10. <div style="margin: auto;" class="add-row add-row-rel top-paging">  
  11. <span class="cpp">Companies per page:</span>  
  12. <a (click)="setRecPerPage(small)" [ngClass]="smallPageRow? 'active':'mr-2'">{{small}}</a>  
  13. <a (click)="setRecPerPage(medium)" [ngClass]="mediumPageRow? 'active':'mr-2'">{{medium}}</a>  
  14. <a (click)="setRecPerPage(large)" [ngClass]="largePageRow? 'active':'mr-2'">{{large}}</a>  
  15. </div>  
  16. </div>  
  17.   
  18. </div>  
  19. <div class="card-body position-relative">  
  20. <!-- <div class="tbl-note-dentist">  
  21. Sort list by select <span>table headers</span>, click again to reorder  
  22. ascending/descending  
  23. </div> -->  
  24. <div class="table-responsive cnstr-record companie-tbl">  
  25. <table class="table table-bordered heading-hvr">  
  26. <thead>  
  27. <tr>  
  28. <th style="cursor: pointer;" [ngClass]="order =='CompanyNumber'? 'active':''"  
  29. (click)="setOrder('CompanyNumber')" width="80">Company Name.</th>  
  30. <th style="cursor: pointer;" [ngClass]="order =='CompanyType'? 'active':''"  
  31. (click)="setOrder('CompanyType')" width="75">City</th>  
  32. <th [ngClass]="order =='CompanyName'? 'active':''" style="cursor: pointer;"  
  33. (click)="setOrder('CompanyName')">State  
  34. </th>  
  35. <th [ngClass]="order =='OrgNo'? 'active':''" style="cursor: pointer;" (click)="setOrder('OrgNo')"  
  36. width="75">CEO  
  37. </th>  
  38. <th [ngClass]="order =='Street'? 'active':''" style="cursor: pointer; width:250px"  
  39. (click)="setOrder('Street')">Publish Year</th>  
  40. </tr>  
  41. </thead>  
  42. <tbody>  
  43. <tr *ngFor="let item of companies">  
  44. <td>{{item.CompanyName}}</td>  
  45. <td>{{item.City}}</td>  
  46. <td>{{item.State}}</td>  
  47. <td>{{item.Owner}}</td>  
  48. <td>{{item.PublishYear}}</td>  
  49.   
  50. </tr>  
  51. </tbody>  
  52. </table>  
  53.   
  54.   
  55. </div>  
  56. <!-- Code by pagination -->  
  57. <div class="container mw-100">  
  58. <div class="row">  
  59. <div class="col-md-3"> </div>  
  60. <div *ngIf="companies !=0" class="col-md-6">  
  61. <ul class="pagination justify-content-center">  
  62. <li class="page-item">  
  63. <a (click)="showPrevCompanies()"  
  64. [ngClass]="(paginationService.showNoOfCurrentPage ==1)?'notAllowed':'page-link'"  
  65. style="margin-top: 5px; margin-right: 20px;cursor: pointer;">Prev</a></li>  
  66. <li *ngFor="let page of pageField;let i=index" class="page-item">  
  67. <a (click)="showCompaniesByPageNumber(page,i)" [ngClass]="pageNumber[i] ? 'pageColor':'page-link'"  
  68. style=" margin-right: 5px;;margin-top: 5px;cursor: pointer;">{{page}}</a>  
  69.    
  70. </li>  
  71. <li class="page-item"><a (click)="showNextCompanies()"  
  72. [ngClass]="(paginationService.disabledNextBtn)?'notAllowed':'page-link'"  
  73. style="margin-top: 5px;margin-left: 20px; cursor: pointer;">Next</a> </li>  
  74. </ul>  
  75. <div style="text-align: center;">  
  76. Page {{currentPage}} of Total page {{paginationService.exactPageList}}  
  77. </div>  
  78. </div>  
  79. </div>  
  80. </div>  
  81. </div>  
  82. </div>  
  83. </div>  
  84. </div>  
Step 2:Some changes in css file so just replace this code with pagination.component.css
  1. @charset "utf-8";  
  2. /* CSS Document */  
  3. @media all{  
  4. *{padding:0px;margin:0px;}  
  5. div{vertical-align:top;}  
  6. img{max-width:100%;}  
  7. html {-webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;}  
  8. body{overflow:auto!importantwidth:100%!important;}  
  9. html, body{background-color:#e4e5e6;}  
  10. html {position:relativemin-height:100%;}  
  11. .card{border-radius:4px;}  
  12. .card-header:first-child {border-radius:4px 4px 0px 0px;}  
  13. /*Typekit*/  
  14. html, body{font-family:'Roboto'sans-seriffont-weight:400font-size:13px;}  
  15. body{padding-top:52px;}  
  16. p{font-family:'Roboto'sans-serifcolor:#303030font-weight:400margin-bottom:1rem;}  
  17. input, textarea, select{font-family:'Roboto'sans-serif;}  
  18. h1,h2,h3,h4,h5,h6{font-family:'Roboto'sans-seriffont-weight:700;}  
  19. h1{font-size:20pxcolor:#000000margin-bottom:10px;}  
  20. h2{font-size:30px;}  
  21. h3{font-size:24px;}  
  22. h4{font-size:18px;}  
  23. h5{font-size:14px;}  
  24. h6{font-size:12px;}  
  25. .row {margin-right:-8pxmargin-left:-8px;}  
  26. .col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto {padding-right:8pxpadding-left:8px;}  
  27. .card-header{background-color:#f0f3f5border-bottom:1px solid #c8ced3font-size:13pxfont-weight:600color:#464646text-transform:uppercasepadding:.75rem 8px;}  
  28. .cnstr-record th{white-space:nowrap;padding:.45rem .2rem; font-size:13pxborder-bottom-width:0px!important;}  
  29. .cnstr-record thead{background:#f0f3f5;}  
  30. .cnstr-record .form-control{font-size:13pxpadding:0px 0rem 0px 0.2rem; height:calc(2rem + 2px);}  
  31. .cnstr-record select.form-control{padding-left:.05rem;}  
  32. .cnstr-record .table td, .cnstr-record .table th {vertical-align:middle;}  
  33. .cnstr-record .table td{padding:.3rem;}  
  34. .cnstr-record .table td h4{margin:0px;}  
  35. .wp-50{width:50px;}  
  36. .wp-60{width:60px;}  
  37. .wp-70{width:70px;}  
  38. .wp-80{width:80px;}  
  39. .wp-90{width:90px;}  
  40. .wp-100{width:100px;}  
  41. .mw-auto{min-width:inherit;}  
  42. .expand-row{width:100%border:solid 1px #596269display:inline-block; border-radius:3pxwidth:16pxheight:16pxvertical-align:topbackground:#596269color:#ffffff!important;}  
  43. .expand-row img{vertical-align:topposition:relative; top:2px;}  
  44. .sub-table th{font-weight:400font-size:12px;}  
  45. .sub-table td{background:#efefef;}  
  46. .no-bg td{background:inherit;}  
  47. .mw-100{max-width:100%;}  
  48.   
  49.   
  50. .activeTabColor{  
  51. color#fff;  
  52. background-color#000000;  
  53. }  
  54. .page-item:first-child .page-link {  
  55. margin-left0;  
  56. border-top-left-radius: .25rem;  
  57. border-bottom-left-radius: .25rem;  
  58. }  
  59.   
  60. .pageColor{  
  61. positionrelative;  
  62. displayblock;  
  63. padding: .5rem .75rem;  
  64. margin-left-1px;  
  65. line-height1.25;  
  66. colorwhite!important;  
  67. background-colorblack!important;  
  68. border1px solid #dee2e6;  
  69. }  
  70. .notAllowed{  
  71. positionrelative;  
  72. displayblock;  
  73. padding: .5rem .75rem;  
  74. margin-left-1px;  
  75. line-height1.25;  
  76. color#007bff;  
  77. background-color#fff;  
  78. border1px solid #dee2e6;  
  79. cursor: not-allowed;  
  80. }  
  81. .page-link {  
  82. positionrelative;  
  83. displayblock;  
  84. padding: .5rem .75rem;  
  85. margin-left-1px;  
  86. line-height1.25;  
  87. color#007bff;  
  88. background-color#fff;  
  89. border1px solid #dee2e6;  
  90. }  
  91.   
  92. .mr-2{  
  93. background-color#007bff;  
  94. colorwhite!important;  
  95. margin5px;  
  96. padding5px;  
  97. cursorpointer;  
  98. }  
  99. .active{  
  100. background-colorblack;  
  101. colorwhite!important;  
  102. margin5px;  
  103. padding5px;  
  104. cursorpointer;  
  105. }  
  106.   
  107. }  
Step 3:Copy the below code and replace it with pagination.component.ts
Here i am importing one class which is companies per page which will show the number of records per page .
  1. import { Component, OnInit } from '@angular/core';  
  2. import { ApiService } from './api.service';  
  3. import { PaginationService } from './pagination.service';  
  4. import { CompaniesPerPage } from './CompaniesPerPage';  
  5.   
  6. @Component({  
  7.   selector: 'app-pagination',  
  8.   templateUrl: './pagination.component.html',  
  9.   styleUrls: ['./pagination.component.css']  
  10. })  
  11. export class PaginationComponent implements OnInit {  
  12.   
  13.   companies = [];  
  14.   pageNo: any = 1;  
  15.   pageNumber: boolean[] = [];  
  16.   sortOrder: any = 'CompanyName';  
  17.   
  18.   //Pagination Variables  
  19.   //Page Row variables  
  20.   smallPageRow: boolean = true;  
  21.   mediumPageRow: boolean = false;  
  22.   largePageRow: boolean = false;  
  23.   
  24.   small = CompaniesPerPage.small;  
  25.   medium = CompaniesPerPage.medium;  
  26.   large = CompaniesPerPage.large;  
  27.   
  28.   pageField = [];  
  29.   exactPageList: any;  
  30.   paginationData: number;  
  31.   companiesPerPage: any = CompaniesPerPage.small;;  
  32.   totalCompanies: any;  
  33.   totalCompaniesCount: any;  
  34.   currentPage = 1;  
  35.   
  36.   constructor(public service: ApiService, public paginationService: PaginationService) { }  
  37.   
  38.   ngOnInit() {  
  39.     this.pageNumber[0] = true;  
  40.     this.paginationService.temppage = 0;  
  41.     this.getAllCompanies();  
  42.   }  
  43.   getAllCompanies() {  
  44.     this.service.getAllCompanies(this.pageNo, this.companiesPerPage, this.sortOrder).subscribe((data: any) => {  
  45.       this.companies = data;  
  46.       this.getAllCompaniesCount();  
  47.     })  
  48.   }  
  49.   getAllCompaniesCount() {  
  50.     this.service.getAllCompaniesCount().subscribe((res: any) => {  
  51.       this.totalCompaniesCount = res;  
  52.       this.totalNoOfPages();  
  53.     })  
  54.   }  
  55.   
  56.   //Method For Pagination  
  57.   totalNoOfPages() {  
  58.   
  59.     this.paginationData = Number(this.totalCompaniesCount / this.companiesPerPage);  
  60.     let tempPageData = this.paginationData.toFixed();  
  61.     if (Number(tempPageData) < this.paginationData) {  
  62.       this.exactPageList = Number(tempPageData) + 1;  
  63.       this.paginationService.exactPageList = this.exactPageList;  
  64.     } else {  
  65.       this.exactPageList = Number(tempPageData);  
  66.       this.paginationService.exactPageList = this.exactPageList  
  67.     }  
  68.     this.paginationService.pageOnLoad();  
  69.     this.pageField = this.paginationService.pageField;  
  70.   
  71.   }  
  72.   showCompaniesByPageNumber(page, i) {  
  73.     this.companies = [];  
  74.     this.pageNumber = [];  
  75.     this.pageNumber[i] = true;  
  76.     this.pageNo = page;  
  77.     this.currentPage =page;  
  78.     this.getAllCompanies();  
  79.   }  
  80.   
  81.   //Pagination Start  
  82.   
  83.   showPrevCompanies() {  
  84.   
  85.     if (this.paginationService.showNoOfCurrentPage != 1) {  
  86.       this.paginationService.prevCompanies();  
  87.       this.pageNumber = [];  
  88.       this.pageNumber[0] = true;  
  89.       this.currentPage = this.paginationService.pageField[0];  
  90.       this.getAllCompanies();  
  91.     }  
  92.   
  93.   }  
  94.   
  95.   showNextCompanies() {  
  96.   
  97.     if (this.paginationService.disabledNextBtn == false) {  
  98.       this.pageNumber = [];  
  99.       this.paginationService.nextCompanies();  
  100.       this.pageNumber[0] = true;  
  101.       this.currentPage = this.paginationService.pageField[0];  
  102.       this.getAllCompanies();  
  103.     }  
  104.   }  
  105.   
  106.   setRecPerPage(noOfRec) {  
  107.   
  108.     this.companies = [];  
  109.     this.pageNumber = [];  
  110.     this.pageNumber[0] = true;  
  111.     this.paginationService.temppage = 0;  
  112.     if (noOfRec == CompaniesPerPage.small) {  
  113.       this.smallPageRow = true;  
  114.       this.mediumPageRow = false;  
  115.       this.largePageRow = false;  
  116.       this.companiesPerPage = noOfRec;  
  117.       this.currentPage = 1;  
  118.       this.pageNumber[0] = true;  
  119.       this.getAllCompanies();  
  120.   
  121.     }  
  122.     else if (noOfRec == CompaniesPerPage.medium) {  
  123.       this.smallPageRow = false;  
  124.       this.mediumPageRow = true;  
  125.       this.largePageRow = false;  
  126.       this.companiesPerPage = noOfRec;  
  127.       this.currentPage = 1;  
  128.       this.pageNumber[0] = true;  
  129.       this.getAllCompanies();  
  130.   
  131.     } else {  
  132.       this.smallPageRow = false;  
  133.       this.mediumPageRow = false;  
  134.       this.largePageRow = true;  
  135.       this.companiesPerPage = noOfRec;  
  136.       this.currentPage = 1;  
  137.       this.pageNumber[0] = true;  
  138.       this.getAllCompanies();  
  139.   
  140.     }  
  141.     //this.pageSize = page;  
  142.   }  
  143. }  
Step 4: For fetching records per page i am using an enum class CompaniesPerPage Class.Create a new class called CompaniesPerPage.ts and paste the below code.
  1. export enum CompaniesPerPage {  
  2. small = 5,  
  3. medium = 10,  
  4. large= 15,  
  5. displayNoOfPagesPerPage=10  
  6. }  
Step 5:For getting the records a service must be called to connect with the web API for that copy the below code and paste it in Api.service.ts file.
  1. import { Injectable } from '@angular/core';  
  2. import { HttpClient } from '@angular/common/http';  
  3. import { Observable } from 'rxjs';  
  4.   
  5. @Injectable({  
  6. providedIn: 'root'  
  7. })  
  8. export class ApiService {  
  9. private url = "";  
  10.   
  11. constructor(public http: HttpClient) {  
  12. }  
  13.   
  14. getAllCompanies(pageNo,pageSize,sortOrder): Observable<any> {  
  15. this.url = 'http://localhost:59390/api/Pagination/getAllCompanies?pageNo=' + pageNo+'&pageSize='+pageSize+'&sortOrder='+sortOrder;  
  16. return this.http.get(this.url);  
  17. }  
  18.   
  19. getAllCompaniesCount(): Observable<any> {  
  20. this.url = 'http://localhost:59390/api/Pagination/getAllCompaniesCount';  
  21. return this.http.get(this.url);  
  22. }  
  23. }  
Step 6:This is the most important file of this article as i have separated the logic for previous and next button so that it can be easy to reuse the same code rather than writing it every time .In our Part 1 i have given the logic for  page load only but in this part 2, code for previous and next button with different logic so just copy this below code and replace it with  pagination.service.ts file.
  1. import { Injectable } from '@angular/core';  
  2. import { CompaniesPerPage } from './CompaniesPerPage';  
  3.   
  4. @Injectable()  
  5.   
  6. export class PaginationService {  
  7.     //Pagination Variables  
  8.       
  9.     pageNumberPerPage = 0;  
  10.     pageNumberShow = CompaniesPerPage.displayNoOfPagesPerPage;  
  11.     temppage: number = 0;  
  12.     disabledNextBtn: boolean;  
  13.     disabledPrevBtn: boolean = true;  
  14.     pageField = [];  
  15.     exactPageList: any;  
  16.     prevtrue: boolean;  
  17.     nexttrue: boolean;  
  18.     currentPage = 1;  
  19.     pageNumber: boolean[] = [];  
  20.     showNoOfCurrentPage: any = 1;  
  21.     showPageOnlyOntabsChange: boolean = true;  
  22.     lastPage: any = 0;  
  23.   
  24.     constructor() {  
  25.     }  
  26.   
  27.     // On page load   
  28.     pageOnLoad() {  
  29.         if (this.temppage == 0 ) {  
  30.               
  31.             this.pageField = [];  
  32.             for (var a = 0; a < this.pageNumberShow; a++) {  
  33.                 this.pageField[a] = this.temppage + 1;  
  34.                 this.temppage = this.temppage + 1;  
  35.                 if (this.exactPageList == this.pageField[a]) {  
  36.                     for (var b = 0; b < this.pageNumberShow - 7; b++) {  
  37.                         if (a == b) {  
  38.                             this.temppage = this.temppage - (b + 1);  
  39.                             this.prevtrue = false;  
  40.                             break;  
  41.                         }  
  42.                     }  
  43.                     this.disabledNextBtn = true;  
  44.                     break;  
  45.                 } else {  
  46.                     this.disabledNextBtn = false;  
  47.                 }  
  48.             }  
  49.         }  
  50.     }  
  51.   
  52.     prevCompanies() {  
  53.   
  54.         this.pageNumber[0] = true;  
  55.         this.nexttrue = true;  
  56.         if (this.showNoOfCurrentPage != 1) {  
  57.             this.disabledNextBtn = false;  
  58.             this.showNoOfCurrentPage = this.showNoOfCurrentPage - 1;  
  59.             if (this.prevtrue) {  
  60.                 if (this.lastPage == 0) {  
  61.                     this.temppage = this.temppage - 10;  
  62.                     this.prevtrue = false;  
  63.                 } else {  
  64.                     this.temppage = this.lastPage ;  
  65.                     this.nexttrue =false;  
  66.                     this.prevtrue = false;  
  67.                     this.lastPage = 0;  
  68.                 }  
  69.             }  
  70.             for (var a = this.pageNumberShow - 1; a >= 0; a--) {  
  71.                 this.pageField[a] = this.temppage;  
  72.                 this.temppage = this.temppage - 1;  
  73.             }  
  74.             if (this.temppage == 0) {  
  75.                 this.showPageOnlyOntabsChange = false;  
  76.             }  
  77.             this.currentPage = this.pageField[0];  
  78.         }  
  79.     }  
  80.   
  81.     nextCompanies() {  
  82.   
  83.         if (this.disabledNextBtn == false) {  
  84.             this.disabledPrevBtn = false;  
  85.             this.pageField = [];  
  86.             this.prevtrue = true;  
  87.             this.showNoOfCurrentPage = this.showNoOfCurrentPage + 1;  
  88.             this.pageNumber[0] = true;  
  89.             if (this.nexttrue) {  
  90.                 this.temppage = this.temppage + 10;  
  91.                 this.nexttrue = false;  
  92.             }  
  93.             for (var a = 0; a < this.pageNumberShow; a++) {  
  94.                 this.pageField[a] = this.temppage + 1;  
  95.                 this.temppage = this.temppage + 1;  
  96.                 if (this.exactPageList == this.pageField[a]) {  
  97.                     this.lastPage = this.pageField[a];  
  98.                     this.lastPage = this.lastPage - (a + 1);  
  99.                     for (var b = 0; b < this.pageNumberShow - 7; b++) {  
  100.                         if (a == b) {  
  101.                             this.temppage = this.temppage - (b + 1);  
  102.   
  103.                             //this.prevtrue = false;  
  104.                             break;  
  105.                         }  
  106.                     }  
  107.                     this.disabledNextBtn = true;  
  108.                     break;  
  109.                 } else {  
  110.                     this.disabledNextBtn = false;  
  111.                 }  
  112.             }  
  113.             this.currentPage = this.pageField[0];  
  114.         }  
  115.     }  
  116.   
  117. }  
 So with the above step our coding part is done now its time to check the output  by using the command ng serve -o.
Here below images we can see that total number of records are 60 which means total are 60 records but we are only showing only 5 records at one page and 60/5 =12 so total are 12 pages but in screen we are showing only 10 pages when you click on next button next page will come which is 11 and 12 .When you clicks on 15 which means you want to see 15 records per page so the number of pages in one screen will going to change which is 60/15=4 only 4 pages we are going to see .
Here is how the logic works .
 
Conclusion
In this article, I tried to explain how to display selected number of records per page and next and previous button by applying different approach using server-side pagination in  angular 8 and ASP.NET.
This is part 2 of server-side pagination.
In my next article or part 3 of this, we will learn one more step ahead we are going to perform header sorting using pagination.
I am just a learner and eager to learn new things not just related to technology, but also in all aspects.
"Knowledge is knowing that we cannot know."
Last but not the least your feedback its very important that i get a chance to improve myself so for that i need your valuable comments good i will take it as a motivation and negative comments for me to improve so that i can learn more and more. Please let me know if you liked and understood this article and how I could improve it.
For any questions about this article regarding code or something please leave a comment. 

Comments

Popular posts from this blog

Introduction To Firebase

Sharing Data from child to parent in angular 8 using @viewChild

Create Dynamic Row with Custom Multi Dropdown Checkbox with only two values checked.