AngularJS Tutorial - 8.2, ngGrid Server pagination

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...)

Screenshot

The samples can be run with Firefox, in general or by running, into the directory,

Download

The source for this part is here: 08paginationnggrid.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

    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!

        $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>

Last modified on: April 23, 2015