Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Server-side pagination in AngularJS + ASP.NET MVC

0.00/5 (No votes)
14 Aug 2016 1  
This article talks about how to implement server-side AngularJS pagination in ASP.Net MVC web application.

Introduction

This article is about creating a pagination in an ASP.NET MVC web application using angular-utils-pagination by  and PageList by Troy Goode.

i.  https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

ii. https://github.com/TroyGoode/PagedList

Background

Basic idea for this pagination method is instead of grabbing data for all the pages, it will only perform ajax to grab the data needed for that specific page each time when user clicks button for next page.

The benefits of server-side pagination approach:

  • Much more efficient for large data set (only data set for that page is needed).
  • Faster initial load.
  • Would not have out of memory issue as browser only stores data set for that specific page.

Using the code

Basic Setup

Create an ASP.Net web application project.

<img src="1117149/Untitled.png" style="width: 662px; height: 372px;" />

Select MVC

<img src="1117149/Untitled1.png" style="width: 662px; height: 372px;" />

After succesfully created the project, open up Manage NuGet Packages.

<img src="1117149/Untitled3.png" style="width: 667px; height: 375px;" />

Upon Manage NuGet Package screen, search for AngularJS and install.

<img src="1117149/Untitled4.png" style="width: 667px; height: 324px;" />

Next, search for PageList by Troy Goode (https://github.com/TroyGoode/PagedList) in NuGet Package screen and click install.

<img src="1117149/Untitled8.png" style="width: 667px; height: 388px;" />

Then navigate to https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination and download the files dirPagination.js and dirPagination.tpl.html.

Alternatively you can install with Bower:

bower install angular-utils-pagination

or npm:

npm install angular-utils-pagination

Now the file set up is completed and we can start coding.

In here we have create a page call "Add Pagination" and will have a list of dishes at the server side.

<img src="1117149/Untitled6.png" style="width: 667px; height: 326px;" />

Server side C#:

For simplicity I'll use hardcoded list as an example, however in actual usage it could be retrieve from a database.

//
// Model to store the list
//
public class DishesModel
{
  public List<string> Dishes_List { get; set; }

  // Pagination
  public int? Page { get; set; }
  public int TotalDishesCount { get; set; }
  public IPagedList<string> DishesPageList { get; set; }
}

//
// This part could be a web api or in the MVC controller
//
public JsonResult dishesPagination(int? Page)
{
  int pageSize = 10;             
  int pageNumber = (Page ?? 1);

  if (Page > 0)             
  {                 
    dishes_model.Page = Page;             
  }
  List<string> dishes = new List<string>();

  DishesModel dishes_model = new DishesModel();           
  
  // Hardcoded list for simplicity, it could be from database
  for (int i = 1; i < 100; i++)
  {
    dishes.Add("noodles");
    dishes.Add("sausage");
    dishes.Add("beans on toast");
    dishes.Add("cheeseburger");
    dishes.Add("battered mars bar");
    dishes.Add("crisp butty");
    dishes.Add("yorkshire pudding");
    dishes.Add("wiener schnitzel");
    dishes.Add("sauerkraut mit ei");
    dishes.Add("onion soup");
    dishes.Add("bak choi");
    dishes.Add("avacado maki");
  }

  dishes_model.Dishes_List = dishes;
  dishes_model.TotalDishesCount = dishes_model.Dishes_List.Count();
  dishes_model.DishesPageList = dishes_model.Dishes_List.ToPagedList(pageNumber, pageSize);

  return Json(dishes_model);
}

Html:

@{
    ViewBag.Title = "Add Pagination";
}

<h2>Add Pagination</h2>
<div ng-app="myApp" ng-cloak>
    <div ng-controller="addPaginationCtrl">
        <!-- Dishes Table -->
        <div class="table-responsive table-Item">
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th style="text-align:center;" width="10%">#</th>
                        <th>Dish Name</th>
                    </tr>
                </thead>
                <tbody>
                    <!-- Loading message -->
                    <tr ng-show="showLoading">
                        <td colspan="2">
                            <div><b>{{LoadingText}}</b></div>
                        </td>
                    </tr>
                    <tr dir-paginate="idx in dishesPageList | itemsPerPage:itemsPerPage" total-items="total_count" pagination-id="dishesPagination">
                        <td>{{itemsPerPage *(pageno-1)+$index+1}}</td>
                        <td>{{idx}}</td>
                    </tr>
                </tbody>
            </table>
            <div align="right">
                <dir-pagination-controls max-size="8"
                                         direction-links="true"
                                         boundary-links="true"
                                          pagination-id="dishesPagination"
                                         on-page-change="getData(newPageNumber)">
                </dir-pagination-controls>
            </div>
        </div>
    </div>
</div>
<!--angular-utils-pagination library-->
<script src="~/Scripts/AngularPagination/dirPagination.js"></script>

Javascript:

<script>
    (function ($) {
        'use strict';

        // Injects "angularUtils.directives.dirPagination" dependency
        angular.module("myApp", ["angularUtils.directives.dirPagination"]);

        angular.module("myApp").controller("addPaginationCtrl", ["$scope", "addPaginationService", function ($scope, addPaginationService) {
            // Initialize variable
            $scope.itemsPerPage = 10;
            $scope.pageno = 1;
            $scope.total_count = 0;
            $scope.dishesPageList = [];

            // This would fetch the data on page change.
            $scope.getData = function (pageno) { 
                // Proceed to search function once validation success
                $scope.LoadingText = "Loading Dishes...";
                $scope.showLoading = true;

                // Resets page list and total count on each page change
                $scope.dishesPageList = [];
                $scope.total_count = 0;

                // Assign new page number
                $scope.pageno = pageno;

                addPaginationService.searchDishesPage(pageno)
                    .then(function (result) {
                        // if total dish count more than zero hides the loading text
                        if (result.TotalDishesCount > 0) {
                            $scope.showLoading = false;
                        }
                        else {
                            $scope.LoadingText = "Dishes not available.";
                            $scope.showLoading = true;
                        };

                        // Assigns total count and page list
                        $scope.total_count = result.TotalDishesCount;
                        $scope.dishesPageList = result.DishesPageList;
                    }, function () {
                        // error
                        $scope.LoadingText = "Error occur, please try again.";
                        $scope.showLoading = true;
                    }).finally(function () {
                        // called no matter success or failure                        
                    });
            };

            // Initial load set to page 1
            $scope.getData(1);
        }]);

        angular.module("myApp").factory("addPaginationService", ["$http", function ($http) {
            var service = {};

            var dishesList = [];

            service.getDishesList = function () {
                return dishesList;
            };

            // Ajax call to server to retrieve dishes data based on page number
            service.searchDishesPage = function (pageno) {
                var model = {
                    Page: pageno
                }

                return $http({
                    method: "POST",
                    url: '@Url.Action("dishesPagination", "Home")',
                    headers: { 'Content-Type': 'application/json; charset=utf-8' },
                    data: model
                }).then(
                function successCallback(response) {
                    dishesList = response.data.DishesPageList;
                    return response.data;
                },
                function errorCallback(response) {
                    console.log("Search Dishes Error:" + response);
                    // May add exception code
                });
            };

            return service;
        }]);
    })(jQuery);
</script>

 

Testing the App

Compiled and execute the web application. 

<img src="1117149/Untitled7.png" style="width: 667px; height: 269px;" />

Demo web site: http://mytutorial.yolio.my.tmp13.mschosting.com/home/addpagination

Points of Interest

To learn how to implement ASP.Net MVC pagination in AngularJS. 

History

  • 13th August, 2016: First version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here