I had created a data pager to use in a knockout / MVC4 project. Recently I adapted it to angular for another ASP.NET/MVC 4 project. I was told this may be useful for the community, so here it is. I will put this up on github soon.
The controller method: Should return a json object that has the following objects in it: TotalRecords, Records. TotalRecords is an int that tells the pager the total number of records in the source that passed the query.
Consuming javascript: Should initiate the pager, and handle the server requests. Here is a snippet that illustrates this:
--------------
Finally, the pager code:
The controller method: Should return a json object that has the following objects in it: TotalRecords, Records. TotalRecords is an int that tells the pager the total number of records in the source that passed the query.
Consuming javascript: Should initiate the pager, and handle the server requests. Here is a snippet that illustrates this:
scope.pager = new pager();
scope.filter = [[someFilterYouPassToControllerMethod]]
scope.pager.onGetRecords = function(){
scope.filter.StartRecord = scope.pager.currentBeginRecord;
scope.filter.NumRecords = scope.pager.numRecordsPerPage;
http({
method: 'GET',
url: [[controllerMethodUrl]],
params: scope.filter
})
.success(function (data) {
scope.pager.onRecordsFetched(data);
});
};
Here is an example of html/ng snippet that renders the pager (uses twitter bootstrap styles and font-awesome):--------------
<div class="container">
<div class="row">
<div class="col-md-6 form-inline">
<div class="input-prepend input-append">
<div class="btn-group">
<button class="btn btn-default btn-sm" ng-disabled="pager.cannotGoBack()" ng-click="pager.goToBeginning()"><i class="icon-fast-backward"></i></button>
<button class="btn btn-default btn-sm" ng-disabled="pager.cannotGoBack()" ng-click="pager.goBack()"><i class="icon-step-backward"></i></button>
</div>
<input type="text" ng-model="pager.currentPage" class="form-control" ng-model-onblur ng-change="pager.goToPage()" style="width: 54px;" />
<span class="add-on"> / {{pager.totalPages}} pages</span>
<div class="btn-group">
<button class="btn btn-default btn-sm" ng-disabled="pager.cannotGoForward()" ng-click="pager.goForward()"><i class="icon-step-forward"></i></button>
<button class="btn btn-default btn-sm" ng-disabled="pager.cannotGoForward()" ng-click="pager.goToEnd()"><i class="icon-fast-forward"></i></button>
</div>
<div class="add-on" ng-show="pager.isBusy">
<i class="icon-spinner icon-spin"></i>
</div>
</div>
</div>
<div class="col-md-6 form-inline">
<small class="pull-right"> showing {{pager.displayBeginRecord()}} to {{pager.displayEndRecord()}} out of {{pager.totalRecords}} records
.. <input type="text" ng-model="pager.numRecordsPerPage" class="form-control" ng-model-onblur ng-change="pager.initAndGetRecords()" style="width:54px"/> records per page</small>
</div>
</div>
</div>
----------------Finally, the pager code:
function pager() {
var that = this;
that.isBusy = false;
that.currentBeginRecord = 0;
that.totalRecords = 0;
that.numRecordsPerPage = 10;
that.currentPage = 1;
that.totalPages = 1;
that.records = [];
that.currentEndRecord = function () {
return (that.currentBeginRecord + that.records.length - 1);
};
that.canGoBack = function () {
return (that.currentBeginRecord > 0 && !that.isBusy);
};
var isNumeric = function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
that.canGoForward = function () {
return (that.currentBeginRecord + that.records.length < that.totalRecords && !that.isBusy);
};
that.cannotGoBack = function () { return !that.canGoBack(); }
that.cannotGoForward = function () { return !that.canGoForward(); }
that.displayBeginRecord = function () {
return that.currentBeginRecord + 1;
};
that.displayEndRecord = function () {
return that.currentEndRecord() + 1;
};
that.onRecordsFetched = function (data) {
that.records = data.Records;
that.totalRecords = data.TotalRecords;
that.totalPages = Math.ceil(data.TotalRecords / that.numRecordsPerPage);
that.currentPage = Math.ceil((that.currentBeginRecord + 1) / that.numRecordsPerPage);
that.isBusy = false;
};
that.goToPage = function () {
var cp = that.currentPage;
if (isNumeric(cp) && cp > 0 && cp <= that.totalPages) {
that.currentBeginRecord = (cp - 1) * that.numRecordsPerPage;
that.getRecords();
}
}
that.getRecords = function () {
that.isBusy = true;
if (typeof this.onGetRecords === "function") {
this.onGetRecords();
}
}
that.initAndGetRecords = function () {
that.currentBeginRecord = 0;
that.getRecords();
}
that.goToBeginning = function () {
that.currentBeginRecord = 0;
that.getRecords();
};
that.pageRefresh = function () {
that.getRecords();
};
that.goForward = function () {
that.currentBeginRecord = that.currentBeginRecord + that.records.length;
that.getRecords();
};
that.goBack = function () {
that.currentBeginRecord = that.currentBeginRecord - that.numRecordsPerPage;
if (that.currentBeginRecord < 0) that.currentBeginRecord = 0;
that.getRecords();
};
that.goToEnd = function () {
var recsInLastPage = that.totalRecords % that.numRecordsPerPage;
if (recsInLastPage < 1) recsInLastPage = that.numRecordsPerPage;
that.currentBeginRecord = that.totalRecords - recsInLastPage;
if (that.currentBeginRecord < 0) that.currentBeginRecord = 0;
that.getRecords();
};
}