Click here to Skip to main content
15,885,216 members
Articles / Web Development / ASP.NET / ASP.NET4.0

Server-side pagination in AngularJS + ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.57/5 (7 votes)
14 Aug 2016CPOL1 min read 23.2K   9   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.

Image 1

Select MVC

Image 2

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

Image 3

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

Image 4

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

Image 5

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.

Image 6

Server side C#:

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

C#
//
// 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:

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. 

Image 7

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Malaysia Malaysia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralVery good Artical Pin
DD Naw Smith27-Jun-17 7:37
DD Naw Smith27-Jun-17 7:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.