New version Angular 9
AngularJS Tutorial - 8.2, ngGrid Server pagination
-
Next
In this part we will discover how to create a grid with angular ngView directive.
Remember that you will have to include JQuery (still have to understand why but...)

The samples can be run with Firefox, in general or by running, into the directory,
- If you have Python 2.x: python -m SimpleHTTPServer 8000
- If you have Python 3.x: python -m http.server 8000
- If you have Perl:
- cpan HTTP::Server::Brick # install dependency
- perl -MHTTP::Server::Brick -e '$s=HTTP::Server::Brick->new(port=>8000); $s->mount("/"=>{path=>"."}); $s->start'
- If you are under windows: "C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:%CD% /port:8000
Download
The source for this part is here: 08_pagination_nggrid.zip.
The data service
We will change the data service to handle paging requests. The function "list" will be changed. Note
that we added the "count" parameter too, to define how many items we will need.
this.list=function(currentPage,pageSize,count){
var start = currentPage * pageSize;
var end = start + count;
var result = "/customers?range=["+start+","+end+"]";
return result;
};
We will add even a function to get the total data length from headers (fakerest stores there this value)
this.getListCount = function(data,headers){
var contentRange = headers()['content-range'];
var length = contentRange.split('/');
return parseInt(length[1]);
}
The base controller
Most important thing, the pages for angular ngGrid are 1 based!!!!
The generic controller loadData function must be changed to handle the pagination. Note that we
require pageSize+1 items. This is to guarantee that we know in advance if a "next" exists.
$scope.loadData = function(requiredPage){
//Sanity check
if(!requiredPage){
requiredPage = 1;
}
var pageSize = parseInt($scope.pagingOptions.pageSize);
//Getting the address
var address= dataService.list(requiredPage-1,pageSize,pageSize+1);
$http.get(address)
.success(function(data, status, headers, config){
var dataOriginalLength = data.length;
data = data.splice(0,pageSize);
if(callbacks.postLoadData)data = callbacks.postLoadData(data,headers);
$scope.data = data;
if($scope.pagingOptions.hasCount){
$scope.totalCount = dataService.getListCount($scope.data,headers);
}else{
if(dataOriginalLength==pageSize+2){
$scope.totalCount = (requiredPage)*(pageSize+1);
}else{
if(dataOriginalLength<pageSize){
$scope.totalCount = (requiredPage-1)*(pageSize)+$scope.data.length;
}else{
$scope.totalCount = (requiredPage)*(pageSize)+$scope.data.length;
}
}
}
$scope.pagingOptions.currentPage = requiredPage;
if (!$scope.$$phase) {
$scope.$apply();
}
})
.error(function(data,status,headers,config){
globalMessagesService.showMessage(data.message,status);
});
}
At the end of the load data we apply the scope changes. Note that
- First we verify that we are in a AngularJS lifecycle phase allowing the apply
- Then we call the apply
if (!$scope.$$phase) {
$scope.$apply();
}
Finally we load the data
$scope.loadData(1);
The Customers controller
The settings for the grid must be added here to let everything work!
-
Paging Options: The options controlling the paging
- pageSizes: Array with the list of allowed pagesizes
- pageSize: The default page size
- currentPage: The page on which the grid will start
-
Grid Options: Options for the visualization of the grid
- data: The model that will be used
- columnDefs: The list of coulumnt. Note that for the id row we use a custom template
- enablePaging: ...
- showFooter: ...
- pagingOptions: The paging options defined before
- totalServerItems: The NAME of the variable containg the count of items in the enclosing controller
- enableRowSelection: ....
- plugins: Array of the plugins loaded. Actually we use the ngGridFlexibleHeightPlugin, that "Automatically resize a table to accomodate a varying number of rows."
$scope.pagingOptions = {
pageSizes: [10],
pageSize: 10,
currentPage: 1
};
$scope.gridOptions = {
data:'data',
columnDefs:[
{field:'first_name',displayName:'FirstName'},
{field:'last_name',displayName:'LastName'},
{field:'id',displayName:'',cellTemplate:'app/common/buttonCell.html'}
],
enablePaging: true,
showFooter: true,
totalServerItems: 'totalCount',
pagingOptions: $scope.pagingOptions,
plugins: [new ngGridFlexibleHeightPlugin()],
enableRowSelection: false
}
Cell Template
Since we will want to show the buttons for editing and selection on one row we built a custom cell template.
ngGrid pass to every cell a parameter "row" that inside the "entity" variable contains the object returned on
the list.
<div> <button type="button" class="btn btn-default btn-xs" ng-click="viewDetail(row.entity)"> <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> </button> .... </div>
View template
On the list the thing is very simple. A div that references the options and add a style to
handle the height of the grid!
<div class="gridStyle" ng-grid="gridOptions"></div>