In Focus

Custom Paging In Angular-UI Grid

In this article, you will learn how to implement custom paging using Angular UI-Grid in MVC application with Web API.

Read the below articles first to understand the AngularJS UI-grid.

Prerequisites

Visual Studio 2017 is the prerequisite to work with this article.

Thus, let's just use the sections with which we can implement the functionality.

  • Create ASP.NET MVC 5 Application.
  • Adding Model.
  • Scaffolding in MVC 5.
  • View in MVC 5.
  • Log in an Entity Framework.

Create ASP.NET MVC 5 Application

In this section, we'll create an ASP.NET Web Application with the MVC 5 Project Template. Use the procedure given below.

Step 1

Open Visual Studio 2015 and click "New Project".

Step 2

Select "Web" from the left pane and create ASP.NET Web application.

Step 3

Select the MVC Project template in the next ASP.NET wizard.

Visual Studio automatically creates the MVC 5 Application, adds some files and folders to the solution.

Working with Entity Framework

Step 1

Right click on Models folder, click Add New Item, select ADO.NET Entity Data Model from Data template and give a name.

Step 2

Select EF Designer from the database.

Step 3

Make a new connection and select a connection, if you already have a connection.

Step 4

Select tables, view, and stored procedures and click Finish.

 

Here, you have 2 ways to add Web API class. You can add new Web API controller and select model class and data source that will generate API class with entity framework. Another way is to generate it manually. So in this article, I will create a manual API class.

Model Class

  1. public class Employee {  
  2.     public int EmployeeID {  
  3.         get;  
  4.         set;  
  5.     }  
  6.     public string FirstName {  
  7.         get;  
  8.         set;  
  9.     }  
  10.     public string LastName {  
  11.         get;  
  12.         set;  
  13.     }  
  14.     public string City {  
  15.         get;  
  16.         set;  
  17.     }  
  18.     public string Region {  
  19.         get;  
  20.         set;  
  21.     }  
  22.     public string PostalCode {  
  23.         get;  
  24.         set;  
  25.     }  
  26.     public string Country {  
  27.         get;  
  28.         set;  
  29.     }  
  30.     public string Notes {  
  31.         get;  
  32.         set;  
  33.     }  
  34. }  
Now, add a builder class.
  1. //Entity set  
  2. public NORTHWNDEntities db = new NORTHWNDEntities();  
  3. /// <summary>  
  4. /// get employee list using linq  
  5. /// </summary>  
  6. /// <returns></returns>  
  7. public async Task < IEnumerable < Employee >> GetEmployee() {  
  8.     try {  
  9.         return await (from n in db.Employees select new Employee {  
  10.             EmployeeID = n.EmployeeID,  
  11.                 FirstName = n.FirstName,  
  12.                 LastName = n.LastName,  
  13.                 City = n.City,  
  14.                 Region = n.Region,  
  15.                 PostalCode = n.PostalCode,  
  16.                 Country = n.Country,  
  17.                 Notes = n.Notes  
  18.         }).OrderByDescending(n => n.EmployeeID).ToListAsync();  
  19.     } catch (Exception ex) {  
  20.         throw ex;  
  21.     }  
  22. }  

If you want to use a stored procedure, then read my previous article.

Web API

Right click on controller folder, click Add and select Controller and select Web API 2 Controller – Empty.

  1. [RoutePrefix("api/EmployeeAPI")]  
  2. public class EmployeeAPIController: ApiController {  
  3.     private readonly EmployeeVMBuilder _employeeVMBuilder = new EmployeeVMBuilder();  
  4.     // GET api/<controller>  
  5.     [Route("GetEmployee")]  
  6.     public async Task < IEnumerable < Employee >> GetEmployee() {  
  7.         return await _employeeVMBuilder.GetEmployee();  
  8.     }  
  9. }  

Thus, we are done with Entity framework and API Controller here. Now, install the files given below, using "Manage NuGet Package". 

Add JavaScript files and CSS reference in BundleConfig.cs.

  1. bundles.Add(new ScriptBundle("~/bundles/angular").Include(  
  2. "~/Scripts/angular.js",  
  3. "~/Scripts/angular-route.js",  
  4. "~/Scripts/ui-grid.js"));  
  5. bundles.Add(new ScriptBundle("~/bundles/employee").Include(  
  6. "~/Angular/app.js",  
  7. "~/Angular/Services/employeeService.js",  
  8. "~/Angular/Controller/employeeController.js"));  

 And render on _layout.cshtml.

  1. <div class="navbar-collapse collapse">  
  2.     <ul class="nav navbar-nav">  
  3.         <li>@Html.ActionLink("Home""Index""Home")</li>  
  4.         <li>@Html.ActionLink("About""About""Home")</li>  
  5.         <li>@Html.ActionLink("Contact""Contact""Home")</li>  
  6.         <li>@Html.ActionLink("Employee""Index""Employee")</li>  
  7.     </ul>  
  8. </div>   
  9. @Scripts.Render("~/bundles/jquery")   
  10. @Scripts.Render("~/bundles/bootstrap")   
  11. @Scripts.Render("~/bundles/angular")   
  12. @Scripts.Render("~/bundles/employee")  
  13. @RenderSection("scripts", required: false)  
Now, add a new Angular Controller with scope. I am using just one script for Module, Service, and Controller. You can have it separate if working on a big project.

Module

  1. //Define an angular module for our app  
  2. var app = angular.module('app', ['ngRoute''ui.grid''ui.grid.edit''ui.grid.pagination''ui.grid.autoResize''ui.grid.expandable''ui.grid.selection''ui.grid.pinning']).config(function($routeProvider, $locationProvider) {  
  3.     $locationProvider.hashPrefix('');  
  4.     $routeProvider.when('/', {  
  5.         templateUrl: 'Home',  
  6.         controller: 'homeController'  
  7.     }).when('/employee', {  
  8.         templateUrl: 'Employee',  
  9.         controller: 'employeeController'  
  10.     });  
  11.     //$locationProvider.html5Mode(true);  
  12.     //$locationProvider.html5Mode(true).hashPrefix('*');  
  13. });  
Service
  1. app.service('employeeService'function($http) {  
  2.     this.getEmployees = function() {  
  3.         var req = $http.get('api/EmployeeAPI/GetEmployee');  
  4.         return req;  
  5.     };  
  6. });  
Controller
  1. app.controller("employeeController"function($scope, $filter, employeeService, $window, $http, $log, $interval) {  
  2.     init();  
  3.   
  4.     function init() {  
  5.         //$scope.employees = []; //Commented  
  6.         employeeService.getEmployees().then(function(result) {  
  7.             //$scope.employees = result.data; //Commented  
  8.             //Added for custom paging  
  9.             $scope.gridOptions.totalItems = result.data.length;  
  10.             $scope.totalPage = Math.ceil($scope.gridOptions.totalItems / $scope.pageSize);  
  11.             $scope.gridOptions.data = result.data;  
  12.             console.log($scope.Employees);  
  13.         }, function(error) {  
  14.             $window.alert('Oops! Something went wrong while fetching employee data.');  
  15.         });  
  16.         var paginationOptions = {  
  17.             pageNumber: 1,  
  18.             pageSize: 10,  
  19.         };  
  20.         $scope.currentPage = 1;  
  21.         $scope.pageSize = paginationOptions.pageSize;  
  22.         $scope.gridOptions = {  
  23.             enableRowSelection: true,  
  24.             selectionRowHeaderWidth: 35,  
  25.             enableRowHeaderSelection: true,  
  26.             //paginationPageSizes: [10, 20, 30, 40], //Commented  
  27.             // paginationPageSize: 10, //Commented  
  28.             paginationPageSizes: [$scope.pageSize, $scope.pageSize * 2, $scope.pageSize * 3],  
  29.             paginationPageSize: paginationOptions.pageSize,  
  30.             enableSorting: true,  
  31.             columnDefs: [{  
  32.                 name: '',  
  33.                 field: 'EmployeeID',  
  34.                 enableColumnMenu: false,  
  35.                 enableHiding: false,  
  36.                 exporterSuppressExport: true,  
  37.                 enableSorting: false,  
  38.                 enableFiltering: false,  
  39.                 visible: false  
  40.             }, {  
  41.                 name: 'First Name',  
  42.                 field: 'FirstName',  
  43.                 headerCellClass: 'tablesorter-header-inner',  
  44.                 enableFiltering: true,  
  45.                 enableCellEdit: true,  
  46.             }, {  
  47.                 name: 'Last Name',  
  48.                 field: 'LastName',  
  49.                 headerCellClass: 'tablesorter-header-inner',  
  50.                 enableFiltering: true,  
  51.                 enableCellEdit: true,  
  52.             }, {  
  53.                 name: 'City',  
  54.                 field: 'City',  
  55.                 headerCellClass: 'tablesorter-header-inner',  
  56.                 enableFiltering: true,  
  57.                 enableCellEdit: true,  
  58.             }, {  
  59.                 name: 'Region',  
  60.                 field: 'Region',  
  61.                 enableCellEdit: false,  
  62.                 headerCellClass: 'tablesorter-header-inner',  
  63.                 enableFiltering: true  
  64.             }, {  
  65.                 name: 'Postal Code',  
  66.                 field: 'PostalCode',  
  67.                 enableCellEdit: false,  
  68.                 headerCellClass: 'tablesorter-header-inner',  
  69.                 enableFiltering: true  
  70.             }, {  
  71.                 name: 'Country',  
  72.                 field: 'Country',  
  73.                 enableCellEdit: false,  
  74.                 headerCellClass: 'tablesorter-header-inner',  
  75.                 enableFiltering: true  
  76.             }, {  
  77.                 name: 'Notes',  
  78.                 field: 'Notes',  
  79.                 enableCellEdit: false,  
  80.                 headerCellClass: 'tablesorter-header-inner',  
  81.                 enableFiltering: true  
  82.             }],  
  83.             //This code used for export grid data in csv file  
  84.             enableGridMenu: true,  
  85.             enableSelectAll: true,  
  86.             exporterMenuPdf: false,  
  87.             enableFiltering: true,  
  88.             exporterCsvFilename: 'EmployeeList_' + $filter('date')(new Date(), 'MM/dd/yyyy') + '.csv',  
  89.             exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),  
  90.             onRegisterApi: function(gridApi) {  
  91.                 $scope.gridApi = gridApi;  
  92.                 gridApi.selection.on.rowSelectionChanged($scope, function(row) {  
  93.                     var msg = 'row selected ' + row.isSelected;  
  94.                     $log.log(msg);  
  95.                     console.log(msg);  
  96.                     $window.alert(msg);  
  97.                 });  
  98.                 gridApi.selection.on.rowSelectionChangedBatch($scope, function(rows) {  
  99.                     var msg = 'rows changed ' + rows.length;  
  100.                     $log.log(msg);  
  101.                     $window.alert(msg);  
  102.                     console.log(msg);  
  103.                 });  
  104.                 gridApi.pagination.on.paginationChanged($scope, function(newPage, pageSize) {  
  105.                     debugger;  
  106.                     paginationOptions.pageNumber = newPage;  
  107.                     paginationOptions.pageSize = pageSize;  
  108.                     $scope.pageSize = pageSize;  
  109.                     $scope.currentPage = newPage;  
  110.                     $scope.totalPage = Math.ceil($scope.gridOptions.totalItems / $scope.pageSize);  
  111.                 });  
  112.             },  
  113.             //end here  
  114.             //data for grid  
  115.             // data: 'employees'  
  116.         };  
  117.     }  
  118. });  
Index
  1. @ {  
  2.     ViewBag.Title = "Index";  
  3.     Layout = "~/Views/Shared/_Layout.cshtml";  
  4. } < h2 > Employee < /h2> < div ng - controller = "employeeController" > < div ui - grid = "gridOptions"  
  5. ui - grid - pagination  
  6. ui - grid - selection  
  7. ui - grid - exporter  
  8. ui - grid - resize - columns  
  9. ui - grid - auto - resize  
  10. class = "grid" > < /div> < /div>  
As everything is done, run the application.

In the given screenshot, you can see the page index and page size. Click "Next" to see the next page index.

Conclusion

In this article, we have seen how to implement paging with Angular UI-Grid with Web API and Entity Framework in MVC. If you have any questions or comments, drop me a line in the comments section.