In the previous post I populated the grid with data returned from an API, and in today’s post I’ll incorporate paging.

Head over to http://angular-ui.github.io/bootstrap/ & from the directives dropdown select “pagination”

You should see a set of pagination controls – each styled a bit differently, feel free to take a look at the markup and JavaScript & play with them in plunker to get familiar with how they work.

I like the one that limits the maximum number of visible buttons – so go ahead and copy the markup, I’ve highlighted the markup we’ll be copying below

NgWebApiGrid19

Paste this markup below the closing </table> tag in the students.tpl.html file as so

<div class="row top-buffer">
    <table class="table table-bordered table-striped table-responsive">
        <thead>
            <tr>
                <th>
                </th>
                <th>
                </th>
                <th>
                </th>
                <th>
                    Last Name
                </th>
                <th>
                    First Name
                </th>
                <th>
                    Date of Enrollment
                </th>

            </tr>
        </thead>
        <tbody data-ng-repeat="i in data">
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td>
                    <textarea class="form-control" style="width: 300px;height: 65px" ng-model="i.lastName"></textarea>
                </td>
                <td>
                    <textarea class="form-control" style="width: 300px;height: 65px" ng-model="i.firstMidName"></textarea>
                </td>
                <td>
                    <input type="text" class="form-control" style="width: 150px;height: 65px" ng-model="i.enrollmentDate" />
                </td>
            </tr>

        </tbody>
    </table>
  
  <pagination data-total-items="totalItems" ng-model="currentPage" data-max-size="NumberOfPageButtons" class=" pagination-sm" data-boundary-links="true" data-rotate="false" ng-change="pageChanged()" data-items-per-page="recordsPerPage"></pagination>


</div>

In the student.js file, the studentCtrl should look as so


.controller("studentCtrl", ["$scope", "dataService",
        function($scope, dataService) {
            $scope.data = dataService.students;

            $scope.totalItems = 0;
            $scope.currentPage = 1;
            $scope.maxSize = 5;
            $scope.recordsPerPage = 5;
            $scope.NumberOfPageButtons = 5;
            
            getData($scope, dataService);

            $scope.pageChanged = function() {

                console.log('Page changed to: ' + $scope.currentPage);
            };


        }]);

Also, make sure the ui.bootstrap dependency is getting injected when the ngWebApiGrid.student module is created, if you forget to inject this dependency then pagination component will not show and no error will be thrown when you inspect your console.

angular.module('ngWebApiGrid.student', ['ngRoute', 'ui.bootstrap'])
    .config(["$routeProvider", function($routeProvider) {
        $routeProvider.when("/", {
            controller: "studentCtrl",
            templateUrl: "app/simpleGrid/students.tpl.html"
        });

        $routeProvider.otherwise("/");
    }])

Run the solution, you should now see a pagination directive displayed as so
NgWebApiGrid20

If you click on any of the buttons in the pagination control nothing happens, that’s because we still have to wire-up our controller and data service to fetch the data – let’s do that next.

Go to the StudentsApiController and it should look as follows


        // GET: api/Students
        public StudentsContainer GetStudents(int currentPage, int recordsPerPage)
     {
 
         var pageNumber = currentPage;
         var pageSize = recordsPerPage;
         var begin = (pageNumber - 1) * pageSize;

            var totalNumberOfRecords = db.Students.Count();
            var students = db.Students.OrderBy(r=>r.ID).Skip(begin).Take(pageSize).ToList();

            var studentsContainer = new StudentsContainer { Students = students, RecordCount = totalNumberOfRecords };

            return studentsContainer;
        }

The code above should be self explanatory; essentially, we grab the page number and page size and calculate the records to be returned.

Now go over to the student.js file and modify the dataService to pass the currentPage and pageSize while making the Get request to the StudentsApiController above

 .factory("dataService", ["$http", "$q", function($http, $q) {

        var _students = [];

        var deferred = $q.defer();

        var _getStudents = function(options) {

            $http.get("api/StudentsApi?currentPage=" + options.currentPage + "&" + "recordsPerPage=" + options.recordsPerPage)
                .then(function(result) {
                    angular.copy(result.data.students, _students);
                    deferred.resolve(result.data.recordCount);
                },
                    function() {
                        deferred.reject();
                    });

            return deferred.promise;
        };

        return {
            students: _students,
            getStudents: _getStudents,
        };
    }])

Next, let’s create a helper function called getData(). This function will be called by our controller when it has to fetch the data.


var getData = function ($scope, dataService) {

    var options = {        

    };
    options.currentPage = $scope.currentPage;
    options.recordsPerPage = $scope.recordsPerPage;

    dataService.getStudents(options)
    .then(function (totalItems) {

        $scope.totalItems = totalItems;
    },
    function () {

        alert("error occurred: unable to get data");
    });

};

Lastly, modify the controller to make the call to the getData() function. The getData() function will get called when the page first loads and then each time the user clicks on the pagination buttons.

The controller code should look as so


 .controller("studentCtrl", ["$scope", "dataService",
        function($scope, dataService) {
            $scope.data = dataService.students;

            $scope.totalItems = 0;
            $scope.currentPage = 1;
            $scope.maxSize = 5;
            $scope.recordsPerPage = 5;
            $scope.NumberOfPageButtons = 5;
            
            getData($scope, dataService);

            $scope.pageChanged = function() {

                getData($scope, dataService);
            };


        }]);

The pagination control in the students.tpl.html should look as follows


 <pagination data-total-items="totalItems" ng-model="currentPage" data-max-size="NumberOfPageButtons" class=" pagination-sm" data-boundary-links="true" data-rotate="false" ng-change="pageChanged()" data-items-per-page="recordsPerPage"></pagination>


You should now be able to page through the data

NgWebApiGrid21

Source code is at https://github.com/SangeetAgarwal/NgWebApiGrid and you can see the changes I made for this blog post by looking at this commit

You might have noticed that there is a lag between the page first appearing and data getting loaded into the grid – this is especially noticeable over a slow network connection or when you are paging through the data very quickly – next time we’ll incorporate a loading/progress bar to let the user know that things are happening.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s