In this post I am going to demonstrate how to use Angular UI Grid with server side pagination in ASP.Net MVC application.
Introduction:
Angular UI Grid is a data grid for AngularJS without JQuery that can perform with large data, which is part of the Angular UI suite.
Background:
Recently I was searching for a data table that have component like sorting, filtering, pagination, inline editor, responsive and other advance facilities. I have tried to integrate & use Jquery datatable(Angular), but the problem arise while I was trying to pass entire row passing while row click/row selected button click.
It fails to pass angular object (only can pass int, string, boolean) while render, this was a big issue to me as I was using angularJS in application frontend.
I decided to change the entire table, I found Angular UI Grid.
Let’s Get Into It:
As we know Angular UI Grid is a part of Angular UI, so we have some facilities. We need to download/install package before we are going to use in our application.
To download the package, go to URL: http://ui-grid.info
Fig: 1
SQL Database:
Let’s Create a SQL database, using the new database execute the table script to create new table in the new database.
CREATE TABLE [dbo].[tblProducts]( [ProductID] [int] NOT NULL, [ProductTitle] [nvarchar](256) NULL, [Type] [nvarchar](50) NULL, [Price] [numeric](18, 2) NULL, [CreatedOn] [datetime] NULL, CONSTRAINT [PK_tblProducts] PRIMARY KEY CLUSTERED ( [ProductID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
Demo Data:
INSERT INTO [tblProducts] SELECT 1,'Ape Lifestyle Cotton Casual T-Shirt - Gray','Clothing',270.00,getdate() Union All SELECT 2,'Cotton Casual Short Sleeve Polo - White','Clothing',790.50,getdate() Union All SELECT 3,'Cotton Casual Shirt - Sky Blue and White Stripe','Clothing',1555.00,getdate() Union All SELECT 4,'Cotton Mix Casual Panjabi - Thistle and Gray Stripe','Clothing',2458.00,getdate() Union All SELECT 5,'Cotton Mix Casual Panjabi - Black and Purple Stripe','Clothing',2458.00,getdate() Union All SELECT 6,'Cotton Casual Shirt - Red and White Check','Clothing',1735.00,getdate() Union All SELECT 7,'Kingstar TITANS 1 i19 Smartphone 8GB - White','Smartphone',6300.00,getdate() Union All SELECT 8,'MyCell Spider A4 Smartphone 8GB – White','Smartphone',7770.00,getdate() Union All SELECT 9,'HTC One M9S Nano-SIM Smartphone 16GB - Silver','Smartphone',26900.00,getdate() Union All SELECT 10,'WE X1 Smartphone 16GB – Silver','Smartphone',18600.00,getdate() Union All SELECT 11,'Microsoft Lumia 540 Smartphone 8GB – Cyan','Smartphone',13999.00,getdate() Union All SELECT 12,'BlackBerry Z10 Smartphone 16GB - White','Smartphone',18000.00,getdate() Union All SELECT 13,'Ape Lifestyle Cotton Casual T-Shirt - Gray','Clothing',270.00,getdate() Union All SELECT 14,'Cotton Casual Short Sleeve Polo - White','Clothing',790.50,getdate() Union All SELECT 15,'Cotton Casual Shirt - Sky Blue and White Stripe','Clothing',1555.00,getdate() Union All SELECT 16,'Cotton Mix Casual Panjabi - Thistle and Gray Stripe','Clothing',2458.00,getdate() Union All SELECT 17,'Cotton Mix Casual Panjabi - Black and Purple Stripe','Clothing',2458.00,getdate() Union All SELECT 18,'Cotton Casual Shirt - Red and White Check','Clothing',1735.00,getdate() Union All SELECT 19,'Kingstar TITANS 1 i19 Smartphone 8GB - White','Smartphone',6300.00,getdate() Union All SELECT 20,'MyCell Spider A4 Smartphone 8GB – White','Smartphone',7770.00,getdate() Union All SELECT 21,'HTC One M9S Nano-SIM Smartphone 16GB - Silver','Smartphone',26900.00,getdate() Union All SELECT 22,'WE X1 Smartphone 16GB – Silver','Smartphone',18600.00,getdate() Union All SELECT 23,'Microsoft Lumia 540 Smartphone 8GB – Cyan','Smartphone',13999.00,getdate() Union All SELECT 24,'BlackBerry Z10 Smartphone 16GB - White','Smartphone',18000.00,getdate()
MVC Application:
Let’s create a new demo application with visual studio 2015. Select MVC and Web API below. Click OK.
Fig: 2
After loading the initial application template, we need to install the script packages. We need to install two package using NuGet Package installer.
First we will install AngularJS and after that we need to add Angular-Ui-Grid. In package manager console write Install-Package angularjs. After successfully installation write Install-Package angular-ui-grid.
Fig: 3
Or we can install packages using NuGet package manager
AngularJS
Fig: 4
AngularJS-uigrid
Fig: 5
Our packages are installed, now we need to add a new controller and generate view to the application. In our master layout we need to add reference of script library.
Fig: 6
In the head section add the ui style reference
Fig:7
AngularJS
Let’s add folder’s to create angular script.
Fig: 8
JS-Module
var app; (function () { 'use strict'; app = angular.module('UIGrid_App', [ 'ngAnimate', // support for CSS-based animations 'ngTouch', //for touch-enabled devices 'ui.grid', //data grid for AngularJS 'ui.grid.pagination', //data grid Pagination 'ui.grid.resizeColumns', //data grid Resize column 'ui.grid.moveColumns', //data grid Move column 'ui.grid.pinning', //data grid Pin column Left/Right 'ui.grid.selection', //data grid Select Rows 'ui.grid.autoResize', //data grid Enabled auto column Size 'ui.grid.exporter' //data grid Export Data ]); })();
JS-Controller
app.controller('ProductsCtrl', ['$scope', 'CRUDService', 'uiGridConstants',
function ($scope, CRUDService, uiGridConstants) {
$scope.gridOptions = [];
//Pagination
$scope.pagination = {
paginationPageSizes: [15, 25, 50, 75, 100, "All"],
ddlpageSize: 15,
pageNumber: 1,
pageSize: 15,
totalItems: 0,
getTotalPages: function () {
return Math.ceil(this.totalItems / this.pageSize);
},
pageSizeChange: function () {
if (this.ddlpageSize == "All")
this.pageSize = $scope.pagination.totalItems;
else
this.pageSize = this.ddlpageSize
this.pageNumber = 1
$scope.GetProducts();
},
firstPage: function () {
if (this.pageNumber > 1) {
this.pageNumber = 1
$scope.GetProducts();
}
},
nextPage: function () {
if (this.pageNumber < this.getTotalPages()) {
this.pageNumber++;
$scope.GetProducts();
}
},
previousPage: function () {
if (this.pageNumber > 1) {
this.pageNumber--;
$scope.GetProducts();
}
},
lastPage: function () {
if (this.pageNumber >= 1) {
this.pageNumber = this.getTotalPages();
$scope.GetProducts();
}
}
};
//ui-Grid Call
$scope.GetProducts = function () {
$scope.loaderMore = true;
$scope.lblMessage = 'loading please wait....!';
$scope.result = "color-green";
$scope.highlightFilteredHeader = function (row, rowRenderIndex, col, colRenderIndex) {
if (col.filters[0].term) {
return 'header-filtered';
} else {
return '';
}
};
$scope.gridOptions = {
useExternalPagination: true,
useExternalSorting: true,
enableFiltering: true,
enableSorting: true,
enableRowSelection: true,
enableSelectAll: true,
enableGridMenu: true,
columnDefs: [
{ name: "ProductID", displayName: "Product ID", width: '10%', headerCellClass: $scope.highlightFilteredHeader },
{ name: "ProductTitle", title: "Product Title", width: '40%', headerCellClass: $scope.highlightFilteredHeader },
{ name: "Type", title: "Type", headerCellClass: $scope.highlightFilteredHeader },
{
name: "Price", title: "Price", cellFilter: 'number',
filters: [{ condition: uiGridConstants.filter.GREATER_THAN, placeholder: 'Minimum' }, { condition: uiGridConstants.filter.LESS_THAN, placeholder: 'Maximum' }],
headerCellClass: $scope.highlightFilteredHeader
},
{ name: "CreatedOn", displayName: "Created On", cellFilter: 'date:"short"', headerCellClass: $scope.highlightFilteredHeader },
{
name: 'Edit',
enableFiltering: false,
enableSorting: false,
width: '5%',
enableColumnResizing: false,
cellTemplate: '' +
'' +
'' +
'' +
''
}
],
exporterAllDataFn: function () {
return getPage(1, $scope.gridOptions.totalItems, paginationOptions.sort)
.then(function () {
$scope.gridOptions.useExternalPagination = false;
$scope.gridOptions.useExternalSorting = false;
getPage = null;
});
},
};
var NextPage = (($scope.pagination.pageNumber - 1) * $scope.pagination.pageSize);
var NextPageSize = $scope.pagination.pageSize;
var apiRoute = 'api/Product/GetProducts/' + NextPage + '/' + NextPageSize;
var result = CRUDService.getProducts(apiRoute);
result.then(
function (response) {
$scope.pagination.totalItems = response.data.recordsTotal;
$scope.gridOptions.data = response.data.productList;
$scope.loaderMore = false;
},
function (error) {
console.log("Error: " + error);
});
}
//Default Load
$scope.GetProducts();
//Selected Call
$scope.GetByID = function (model) {
$scope.SelectedRow = model;
};
}
]);
JS-Service
app.service('CRUDService', function ($http) { //**********----Get Record----*************** this.getProducts = function (apiRoute) { return $http.get(apiRoute); } });
Ui-Grid
In index.cshtml page add ui-grid directive
Fig: 9
The loader which will show a loading messaging while data is loading from server.
Fig: 10
At bottom end, add angular reference to the page
Fig: 11
Complete Ui Code:
@{ ViewBag.Title = "Products"; }Products with UI Grid
AngularScript{ }{{lblMessage}}{{pagination.pageNumber}} - {{pagination.ddlpageSize}} of {{pagination.totalItems}} items{{SelectedRow}}
Model: Our Ui is ready Let’s create a new model in our demo application.
Fig: 12
I have used api controller to get data from server, which will get called while pagination operate.
Api-Controller:
[RoutePrefix("api/Product")] public class ProductController : ApiController { private dbUIGrid_Entities _ctx = null; [HttpGet, ResponseType(typeof(tblProduct)), Route("GetProducts/{pageNumber:int}/{pageSize:int}")] public IHttpActionResult GetProducts(int pageNumber, int pageSize) { ListproductList = null; int recordsTotal = 0; try { using (_ctx = new dbUIGrid_Entities()) { recordsTotal = _ctx.tblProducts.Count(); productList = _ctx.tblProducts.OrderBy(x => x.ProductID) .Skip(pageNumber) .Take(pageSize) .ToList(); } } catch (Exception) { } return Json(new { recordsTotal, productList }); } }
Final Output:
Fig: 13
Filter Data:
Fig: 14
Source Code: I’ve uploaded the full source code to download/clone , Hope this will help 🙂
Partha Protim says:
Nice work, Go ahead.
Bright future have waiting for you.
. says:
Angular UI-Grid Paging Server Side, is there a version for Angular 2