Server-Side Pagination Using ASP.NET Core and Angular 8 - Part Three
Join the DZone community and get the full member experience.
Join For FreeIntroduction
- Server Side Pagination using ASP.NET Core and Angular 8-Part 1
- Server Side Pagination using ASP.NET Core and Angular 8-Part 2
How Will it Work?
Back End
xxxxxxxxxx
USE [Company]
GO
/****** Object: StoredProcedure [dbo].[Usp_GetAllCompanies] Script Date: 1/17/2020 11:05:09 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Proc [dbo].[Usp_GetAllCompanies]
@PageNo INT ,
@PageSize INT ,
@SortOrder VARCHAR(200)
As
Begin
Select * From (Select ROW_NUMBER() Over (
Order by
CASE WHEN @SortOrder = 'CompanyName_ASC' THEN CompanyName
END ASC,
CASE WHEN @SortOrder = 'CompanyName_DESC' THEN CompanyName
END DESC,
CASE WHEN @SortOrder = 'City_ASC' THEN City
END ASC,
CASE WHEN @SortOrder = 'City_DESC' THEN City
END DESC,
CASE WHEN @SortOrder = 'State_ASC' THEN [State]
END ASC,
CASE WHEN @SortOrder = 'State_DESC' THEN [State]
END DESC,
CASE WHEN @SortOrder = 'Owner_ASC' THEN [Owner]
END ASC,
CASE WHEN @SortOrder = 'Owner_DESC' THEN [Owner]
END DESC,
CASE WHEN @SortOrder = 'Year_ASC' THEN PublishYear
END ASC,
CASE WHEN @SortOrder = 'Year_DESC' THEN PublishYear
END DESC
) AS 'RowNum', *
from [CompanyDetails]
)t where t.RowNum Between ((@PageNo-1)*@PageSize +1) AND (@PageNo*@pageSize)
End
Front End
Step 1
xxxxxxxxxx
<div class="row">
<div class="col-12 col-md-12">
<div class="card">
<div class="card-header">
<div class="row">
<div>
Companies 1-{{pageSize}} (Total:{{totalCompaniesCount}})
</div>
<div style="margin: auto;" class="add-row add-row-rel top-paging">
<span class="cpp">Companies per page:</span>
<a (click)="setRecPerPage(small)" [ngClass]="smallPageRow? 'active':'mr-2'">{{small}}</a>
<a (click)="setRecPerPage(medium)" [ngClass]="mediumPageRow? 'active':'mr-2'">{{medium}}</a>
<a (click)="setRecPerPage(large)" [ngClass]="largePageRow? 'active':'mr-2'">{{large}}</a>
</div>
</div>
</div>
<div class="card-body position-relative">
<div class="tbl-note-dentist">
Sort list by select <span>table headers</span>, click again to reorder
ascending/descending
</div>
<div class="table-responsive cnstr-record companie-tbl">
<table class="table table-bordered heading-hvr">
<thead>
<tr>
<th style="cursor: pointer;" [ngClass]="order =='CompanyName'? 'headActive':''"
(click)="sortByHeading('CompanyName')" width="80">Company Name.</th>
<th style="cursor: pointer;" [ngClass]="order =='City'? 'headActive':''"
(click)="sortByHeading('City')" width="75">City</th>
<th [ngClass]="order =='State'? 'headActive':''" style="cursor: pointer;"
(click)="sortByHeading('State')">State
</th>
<th [ngClass]="order =='Owner'? 'headActive':''" style="cursor: pointer;" (click)="sortByHeading('Owner')"
width="75">CEO
</th>
<th [ngClass]="order =='Year'? 'headActive':''" style="cursor: pointer; width:250px"
(click)="sortByHeading('Year')">Publish Year</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of companies">
<td>{{item.CompanyName}}</td>
<td>{{item.City}}</td>
<td>{{item.State}}</td>
<td>{{item.Owner}}</td>
<td>{{item.PublishYear}}</td>
</tr>
</tbody>
</table>
</div>
<!-- Code by pagination -->
<div class="container mw-100">
<div class="row">
<div class="col-md-3"> </div>
<div *ngIf="companies !=0" class="col-md-6">
<ul class="pagination justify-content-center">
<li class="page-item">
<a (click)="showPrevCompanies()"
[ngClass]="(paginationService.showNoOfCurrentPage ==1)?'notAllowed':'page-link'"
style="margin-top: 5px; margin-right: 20px;cursor: pointer;">Prev</a></li>
<li *ngFor="let page of pageField;let i=index" class="page-item">
<a (click)="showCompaniesByPageNumber(page,i)" [ngClass]="pageNumber[i] ? 'pageColor':'page-link'"
style=" margin-right: 5px;;margin-top: 5px;cursor: pointer;">{{page}}</a>
</li>
<li class="page-item"><a (click)="showNextCompanies()"
[ngClass]="(paginationService.disabledNextBtn)?'notAllowed':'page-link'"
style="margin-top: 5px;margin-left: 20px; cursor: pointer;">Next</a> </li>
</ul>
<div style="text-align: center;">
Page {{currentPage}} of Total page {{paginationService.exactPageList}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Step 2
There are some changes in the CSS file, so just replace this code with pagination.component.css.
xxxxxxxxxx
@charset "utf-8";
/* CSS Document */
@media all{
*{padding:0px;margin:0px;}
div{vertical-align:top;}
img{max-width:100%;}
html {font-smoothing:antialiased; osx-font-smoothing:grayscale;}
body{overflow:auto!important; width:100%!important;}
html, body{background-color:#e4e5e6;}
html {position:relative; min-height:100%;}
.card{border-radius:4px;}
.card-header:first-child {border-radius:4px 4px 0px 0px;}
/*Typekit*/
html, body{font-family:'Roboto', sans-serif; font-weight:400; font-size:13px;}
body{padding-top:52px;}
p{font-family:'Roboto', sans-serif; color:#303030; font-weight:400; margin-bottom:1rem;}
input, textarea, select{font-family:'Roboto', sans-serif;}
h1,h2,h3,h4,h5,h6{font-family:'Roboto', sans-serif; font-weight:700;}
h1{font-size:20px; color:#000000; margin-bottom:10px;}
h2{font-size:30px;}
h3{font-size:24px;}
h4{font-size:18px;}
h5{font-size:14px;}
h6{font-size:12px;}
.row {margin-right:-8px; margin-left:-8px;}
.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:8px; padding-left:8px;}
.card-header{background-color:#f0f3f5; border-bottom:1px solid #c8ced3; font-size:13px; font-weight:600; color:#464646; text-transform:uppercase; padding:.75rem 8px;}
.cnstr-record th{white-space:nowrap;padding:.45rem .2rem; font-size:13px; border-bottom-width:0px!important;}
.cnstr-record thead{background:#f0f3f5;}
.cnstr-record .form-control{font-size:13px; padding:0px 0rem 0px 0.2rem; height:calc(2rem + 2px);}
.cnstr-record select.form-control{padding-left:.05rem;}
.cnstr-record .table td, .cnstr-record .table th {vertical-align:middle;}
.cnstr-record .table td{padding:.3rem;}
.cnstr-record .table td h4{margin:0px;}
.wp-50{width:50px;}
.wp-60{width:60px;}
.wp-70{width:70px;}
.wp-80{width:80px;}
.wp-90{width:90px;}
.wp-100{width:100px;}
.mw-auto{min-width:inherit;}
.expand-row{width:100%; border:solid 1px #596269; display:inline-block; border-radius:3px; width:16px; height:16px; vertical-align:top; background:#596269; color:#ffffff!important;}
.expand-row img{vertical-align:top; position:relative; top:2px;}
.sub-table th{font-weight:400; font-size:12px;}
.sub-table td{background:#efefef;}
.no-bg td{background:inherit;}
.mw-100{max-width:100%;}
.activeTabColor{
color: #fff;
background-color: #000000;
}
.page-item:first-child .page-link {
margin-left: 0;
border-top-left-radius: .25rem;
border-bottom-left-radius: .25rem;
}
.pageColor{
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: white!important;
background-color: black!important;
border: 1px solid #dee2e6;
}
.notAllowed{
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
cursor: not-allowed;
}
.page-link {
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
}
.mr-2{
background-color: #007bff;
color: white!important;
margin: 5px;
padding: 5px;
cursor: pointer;
}
.active{
background-color: black;
color: white!important;
margin: 5px;
padding: 5px;
cursor: pointer;
}
.headActive{
color: red;
}
}
Step 3
sortByHeading
method.
xxxxxxxxxx
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';
import { PaginationService } from './pagination.service';
import { CompaniesPerPage } from './CompaniesPerPage';
@Component({
selector: 'app-pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {
companies = [];
pageNo: any = 1;
pageNumber: boolean[] = [];
sortOrder: any = 'CompanyName_ASC';
order:any='CompanyName';
//Pagination Variables
//Page Row variables
smallPageRow: boolean = true;
mediumPageRow: boolean = false;
largePageRow: boolean = false;
small = CompaniesPerPage.small;
medium = CompaniesPerPage.medium;
large = CompaniesPerPage.large;
pageField = [];
exactPageList: any;
paginationData: number;
companiesPerPage: any = CompaniesPerPage.small;
orderBy: string='Asc';
totalCompanies: any;
totalCompaniesCount: any;
currentPage = 1;
constructor(public service: ApiService, public paginationService: PaginationService) { }
ngOnInit() {
this.pageNumber[0] = true;
this.paginationService.temppage = 0;
this.getAllCompanies();
}
getAllCompanies() {
this.service.getAllCompanies(this.pageNo, this.companiesPerPage, this.sortOrder).subscribe((data: any) => {
this.companies = data;
this.getAllCompaniesCount();
})
}
getAllCompaniesCount() {
this.service.getAllCompaniesCount().subscribe((res: any) => {
this.totalCompaniesCount = res;
this.totalNoOfPages();
})
}
//Method For Pagination
totalNoOfPages() {
this.paginationData = Number(this.totalCompaniesCount / this.companiesPerPage);
let tempPageData = this.paginationData.toFixed();
if (Number(tempPageData) < this.paginationData) {
this.exactPageList = Number(tempPageData) + 1;
this.paginationService.exactPageList = this.exactPageList;
} else {
this.exactPageList = Number(tempPageData);
this.paginationService.exactPageList = this.exactPageList
}
this.paginationService.pageOnLoad();
this.pageField = this.paginationService.pageField;
}
showCompaniesByPageNumber(page, i) {
this.companies = [];
this.pageNumber = [];
this.pageNumber[i] = true;
this.pageNo = page;
this.currentPage =page;
this.getAllCompanies();
}
//Pagination Start
showPrevCompanies() {
if (this.paginationService.showNoOfCurrentPage != 1) {
this.paginationService.prevCompanies();
this.pageNumber = [];
this.pageNumber[0] = true;
this.currentPage = this.paginationService.pageField[0];
this.getAllCompanies();
}
}
showNextCompanies() {
if (this.paginationService.disabledNextBtn == false) {
this.pageNumber = [];
this.paginationService.nextCompanies();
this.pageNumber[0] = true;
this.currentPage = this.paginationService.pageField[0];
this.getAllCompanies();
}
}
sortByHeading(value: string, id) {
this.companies = [];
this.sortOrder = value;
this.order =value;
if (this.orderBy == "Desc") {
this.orderBy = "Asc"
this.sortOrder =this.sortOrder+'_ASC';
} else {
this.orderBy = "Desc";
this.sortOrder =this.sortOrder+'_DESC'
}
this.getAllCompanies();
}
setRecPerPage(noOfRec) {
this.companies = [];
this.pageNumber = [];
this.pageNumber[0] = true;
this.paginationService.temppage = 0;
if (noOfRec == CompaniesPerPage.small) {
this.smallPageRow = true;
this.mediumPageRow = false;
this.largePageRow = false;
this.companiesPerPage = noOfRec;
this.currentPage = 1;
this.pageNumber[0] = true;
this.getAllCompanies();
}
else if (noOfRec == CompaniesPerPage.medium) {
this.smallPageRow = false;
this.mediumPageRow = true;
this.largePageRow = false;
this.companiesPerPage = noOfRec;
this.currentPage = 1;
this.pageNumber[0] = true;
this.getAllCompanies();
} else {
this.smallPageRow = false;
this.mediumPageRow = false;
this.largePageRow = true;
this.companiesPerPage = noOfRec;
this.currentPage = 1;
this.pageNumber[0] = true;
this.getAllCompanies();
}
//this.pageSize = page;
}
}
Step 6
xxxxxxxxxx
import {
Injectable
} from '@angular/core';
import {
CompaniesPerPage
} from './CompaniesPerPage';
@Injectable()
export class PaginationService {
//Pagination Variables
pageNumberPerPage = 0;
pageNumberShow = CompaniesPerPage.displayNoOfPagesPerPage;
temppage: number = 0;
disabledNextBtn: boolean;
disabledPrevBtn: boolean = true;
pageField = [];
exactPageList: any;
prevtrue: boolean;
nexttrue: boolean;
currentPage = 1;
pageNumber: boolean[] = [];
showNoOfCurrentPage: any = 1;
showPageOnlyOntabsChange: boolean = true;
lastPage: any = 0;
constructor() {}
// On page load
pageOnLoad() {
if (this.temppage == 0) {
this.pageField = [];
for (var a = 0; a < this.pageNumberShow; a++) {
this.pageField[a] = this.temppage + 1;
this.temppage = this.temppage + 1;
if (this.exactPageList == this.pageField[a]) {
for (var b = 0; b < this.pageNumberShow - 7; b++) {
if (a == b) {
this.temppage = this.temppage - (b + 1);
this.prevtrue = false;
break;
}
}
this.disabledNextBtn = true;
break;
} else {
this.disabledNextBtn = false;
}
}
}
}
prevCompanies() {
this.pageNumber[0] = true;
this.nexttrue = true;
if (this.showNoOfCurrentPage != 1) {
this.disabledNextBtn = false;
this.showNoOfCurrentPage = this.showNoOfCurrentPage - 1;
if (this.prevtrue) {
if (this.lastPage == 0) {
this.temppage = this.temppage - 10;
this.prevtrue = false;
} else {
this.temppage = this.lastPage;
this.nexttrue = false;
this.prevtrue = false;
this.lastPage = 0;
}
}
for (var a = this.pageNumberShow - 1; a >= 0; a--) {
this.pageField[a] = this.temppage;
this.temppage = this.temppage - 1;
}
if (this.temppage == 0) {
this.showPageOnlyOntabsChange = false;
}
this.currentPage = this.pageField[0];
}
}
nextCompanies() {
if (this.disabledNextBtn == false) {
this.disabledPrevBtn = false;
this.pageField = [];
this.prevtrue = true;
this.showNoOfCurrentPage = this.showNoOfCurrentPage + 1;
this.pageNumber[0] = true;
if (this.nexttrue) {
this.temppage = this.temppage + 10;
this.nexttrue = false;
}
for (var a = 0; a < this.pageNumberShow; a++) {
this.pageField[a] = this.temppage + 1;
this.temppage = this.temppage + 1;
if (this.exactPageList == this.pageField[a]) {
this.lastPage = this.pageField[a];
this.lastPage = this.lastPage - (a + 1);
for (var b = 0; b < this.pageNumberShow - 7; b++) {
if (a == b) {
this.temppage = this.temppage - (b + 1);
//this.prevtrue = false;
break;
}
}
this.disabledNextBtn = true;
break;
} else {
this.disabledNextBtn = false;
}
}
this.currentPage = this.pageField[0];
}
}
}
ng serve -o
.
Conclusion
Opinions expressed by DZone contributors are their own.
Comments