Pagination in Angular.js - javascript

I am trying to add pagination in Angular js.Sinch my server returns huge number of rows on each query So i am using some limit offset to get only 101 rows(required rows+1) at a time.(Building array of 20 pages ,reusing extra row value for next request.)
No- of rows per page=5
So on getting 101 rows means i can paginate upto 20 pages. Since i already have an extra row So i know there is more data left , So on next page request again am querying to get rows 101-201. But my doubt here is how to add logic in next page and previous page function and how to build next or previous set of data?
My app.js-
My 1st time request-
$scope.startingid = null;
$scope.numberofrows= 101;
Api.customer.query({ productId : $scope.customer , productperiod :$scope.customerPeriod,startingid:$scope.startingid,numberofrows:$scope.numberofrows }).$promise.then(function(result) {
if(result){
if(result&&result.length==0){
$scope.addErrorAlert("No Customer data found with this productId and Period.", true);
$scope.displayPage = 'search';
return;
}
$scope.customerResult = result;
$scope.displayPage = 'drill';
$scope.showData();
}
// Pagination Logic-
My code is working fine if result set is small number of data. But need to implement in such a way that it can handle large number of rows as well.
few doubts-
1. how to build the data for request 101-201.
2. next and previous page logic
$scope.paged = function (valLists,itemsPerPage)
{
var retVal = [];
for (var i = 0; i < valLists.length; i++) {
if (i % itemsPerPage === 0) {
retVal[Math.floor(i / itemsPerPage)] = [valLists[i]];
} else {
retVal[Math.floor(i / itemsPerPage)].push(valLists[i]);
}
}
return retVal;
};
$scope.pagination = function () {
$scope.ItemsByPage = $scope.paged( $scope.customerResult, $scope.itemsPerPage );
};
$scope.showData = function( ){
// $scope.noOfrows = 101;
$scope.itemsPerPage = 5;
$scope.currentPage = 0;
$scope.pagination();
$scope.range = function() {
var rangeSize = 4;
var ps = [];
var start;
start = $scope.currentPage;
if ( start > $scope.pageCount()-rangeSize ) {
start = $scope.pageCount()-rangeSize+1;
}
for (var i=start; i<start+rangeSize; i++) {
ps.push(i);
}
return ps;
};
$scope.prevPage = function() {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.DisablePrevPage = function() {
return $scope.currentPage === 0 ? "disabled" : "";
//?? TODO add logic for samething as disabled next page and build table data
};
$scope.pageCount = function() {
return Math.ceil($scope.customerResult.length/$scope.itemsPerPage)-1;
};
$scope.nextPage = function() {
if ($scope.currentPage < $scope.pageCount()) {
$scope.currentPage++;
}
};
$scope.DisableNextPage = function() {
if($scope.currentPage === $scope.pageCount()){
if($scope.noOfrows >$scope.customerResult.length)
return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
$scope.noOfrows = $scope.noOfrows+ 100;
Api.customerReq.query({ productId : $scope.customerProduct , productperiod :$scope.customerPeriod, noOfrows:$scope.noOfrows }).$promise.then(function(result) {
if(result){
if(result&&result.length==0){
return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
}
$scope.showData();// how to build all data on when i query for 101-201 data?
}
});
}
};
$scope.setPage = function(n) {
$scope.currentPage = n;
};
};

Related

ng-repeat not updating properly in Angular js

I'm trying to put pagination with ng-repeat. Getting result but by the time showing old data and suddenly hide and show new set data, like jerking. My angularjs version is "1.5.8".
$scope.gap = 5;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 5;
$scope.pagedItems = [];
$scope.currentPage = 0;
var resultData = [...];
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')(resultData, function (item) {
for(var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
console.log($scope.pagedItems)
};
$scope.range = function (size,start, end) {
var ret = [];
//console.log(size,start, end);
if (size < end) {
end = size;
start = size-$scope.gap;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
// console.log(ret);
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
console.log($scope.pagedItems[$scope.currentPage]);
$scope.currentPage = this.n;
};
$scope.search();
html
<tr ng-repeat="user in pagedItems[currentPage]" >
<td>{{user.name}} {{$index}}</td>
</tr>
As above code, that table row update as 5 row. but when I click next or page numbers showing 10 rows and hide 5 rows. I hope you understand guys! Help me.
In my opinion you are thinking wrong, it's simpler to use custom filter and break up your business logic like this
app.filter('startFrom', function() {
return function(input, start) {
start = +start;
return input.slice(start);
}
});
then in the controller you can do
$scope.showResults = function() {
$scope.list = $filter('startFrom')($scope.initialList, $scope.page * $scope.itemsPerPage);
$scope.list = $filter('limitTo')($scope.list, $scope.itemsPerPage);
}
};
now you need only to update $scope.page and reuse $scope.showResults() to update the view
<tr ng-repeat="user in list" >
<td>{{user.name}} {{$index}}</td>
</tr>
I don't think that your problem is cause by ng-repeat. I just take your code, add some dummy data and do a test and it's totally work fine.
You can check it here https://codepen.io/Cushdrive/pen/zvPPXd
Because angular is two way binding, so I'm wonder that could it be some paging info was triggered somewhere. Could you double check on some variable like currentPage itemPerPages or pagedItems to see if it being used somewhere else?

AngularJS: Trying to display content using ng-repeat, but page is shown to be blank

Here is the page where I'm trying to display content. It's showing up blank. My application is a single page application, so most of the code is in the index.html file
verbPractice.html
<div>
<h1>Practice verbs here</h1>
<div class="row" ng-repeat="sentence in listOfSentences">
<div class="col-xs-12">
<p>{{sentence.first}} {{sentence.second}} {{sentence.third}}</p>
</div>
</div>
</div>
This page is linked to from another page called verbSelect.html. Here is the relevant code from that page
<div class="btn btn-primary" ui-sref="app.verbPractice" ng-click="storeInfo(); generateSentences()">Submit</div>
Both the above pages are under the same controller called verbController:
(function() {
'use strict';
angular.module('arabicApp')
.controller('verbController', ['$scope', 'verbFactory', 'pronounFactory', 'attachedFactory', function($scope, verbFactory, pronounFactory, attachedFactory){
//Gets verbs from server
$scope.verbArray = verbFactory.getVerbs().query(
function(response) {
$scope.verbArray = response;
}
);
//Gets pronouns from server
$scope.pronouns = pronounFactory.getPronouns().query(
function(response) {
$scope.pronouns = response;
}
);
$scope.attached = attachedFactory.getAttached().query(
function(response) {
$scope.attached = response;
}
);
//Stores the array of selected verbs
$scope.selectedVerbs = [];
$scope.numSelectedVerbs = 0;
//Searches theArray for name and returns its index. If not found, returns -1
$scope.searchArray = function(theArray, name) {
for (var i = 0; i < theArray.length; i++) {
if (theArray[i].name === name) {
return i;
}
}
return -1;
};
//Adds verbs to selected list
$scope.addToSelected = function(theVerb) {
var num = $scope.searchArray($scope.selectedVerbs, theVerb.name);
var divToChange = document.getElementById("verbSelect_"+theVerb.name);
if (num > -1) { //Found. Remeove it from selectedVerbs
$scope.selectedVerbs.splice(num, 1);
divToChange.className = divToChange.className.replace( /(?:^|\s)listItemActive(?!\S)/g , '' );
$scope.numSelectedVerbs = $scope.numSelectedVerbs - 1;
} else { //Not found. Add it in
$scope.selectedVerbs.push(theVerb);
divToChange.className += " listItemActive";
$scope.numSelectedVerbs = $scope.numSelectedVerbs + 1;
}
};
//Stores how many practice questions the user wants
$scope.howMany = 0;
//Stores what tense of verbs the user wants
$scope.verbTense = "Both";
//Stores what form the user wants
$scope.verbVoice = "Both";
//Include commands?
$scope.includeCommands = false;
//Sentense that will be generated
$scope.listOfSentences = [];
$scope.generateSentence = function(isCommand, theTense, theVoice) {
var sent = {"first": "", "second": "", "third": ""};
var attachedPicker = Math.floor(Math.random()*14);
var attachedToUse = $scope.attached[attachedPicker].attached;
var pronounPicker = Math.floor(Math.random()*14);
var pronounToUse = $scope.pronouns[pronounPicker].pronoun;
sent.first = pronounToUse;
var verbPicker = Math.floor(Math.random()*$scope.numSelectedVerbs);
var verbToUse = $scope.selectedVerbs[verbPicker][theTense][pronounToUse];
if (isCommand === true) {
sent.second = verbToUse;
} else {
if (theVoice === "Passive") {
if (theTense === "Past") { sent.second = "were"; }
else { sent.second = "are"; }
sent.third = verbToUse;
} else {
sent.second = verbToUse;
sent.third = attachedToUse;
}
}
return sent;
};
$scope.storeInfo = function() {
localStorage.setItem("howMany", $scope.howMany);
localStorage.setItem("verbTense", $scope.verbTense);
localStorage.setItem("verbVoice", $scope.verbVoice);
localStorage.setItem("includeCommands", $scope.includeCommands);
};
$scope.getStoredInfo = function() {
$scope.howMany = localStorage.getItem("howMany");
$scope.verbTense = localStorage.getItem("verbTense");
$scope.verbVoice = localStorage.getItem("verbVoice");
$scope.includeCommands = localStorage.getItem("includeCommands");
};
//Generates sentences using the variables from verbSelect
$scope.generateSentences = function() {
$scope.getStoredInfo();
var tensePicker;
var voicePicker;
var doCommand;
var rand;
for (var i = 0; i < $scope.howMany; i++) {
//Picks the verb tense
if ($scope.verbTense === "Both") {
rand = Math.floor(Math.random());
if (rand === 0) { tensePicker = "Past"; }
else { tensePicker = "Present"; }
} else {
tensePicker = $scope.verbTense;
}
//Picks the verb voice
if ($scope.verbVoice === "Both") {
rand = Math.floor(Math.random());
if (rand === 0) { voicePicker = "Active"; }
else { voicePicker = "Passive"; }
} else {
voicePicker = $scope.verbVoice;
}
//If the voice is passive, use past tense
if ($scope.verbVoice === "Passive") { tensePicker = "Past"; }
//Determines if the sentence will be a command sentence or not
if ($scope.includeCommands === true) {
rand = Math.floor(Math.random() * 6);
if (rand === 0) { doCommand = true; }
else { doCommand = false; }
} else {
doCommand = false;
}
var sentence = $scope.generateSentence(doCommand, tensePicker, voicePicker);
$scope.listOfSentences.push(sentence);
}
console.log($scope.listOfSentences);
};
}])
;
})();
The variables: howMany, verbTense, verbVoice, isCommand, are set on this verbSelect.html page using ng-model. Both the verbSelect.html page and verbPractice.html page are under the same controller.
Everything seems to be working fine. At the end of my generateSentences() function, I output $scope.listOfSentences to the log, and it shows up without any problems, the array is being populated just fine. However, in my verbPractice.html page, nothing is showing up except the <h1> heading. For some reason, even though the $scope.listOfSentences array is populated, ng-repeat doesn't seem to be looping. Does anyone have any idea why?
Sorry for the long post
Thanks for taking the time to read and answer this question!

Angular 1 button instead of 3

I have a problem with this pagination code. I have 1 button instead of 3. Can you help?
paginator.js
$scope.generateButtons = function () {
var buttons = [],
pageCount = getPageCount(),
buttonCount;
console.log("page " + pageCount);
buttonCount = pageCount > 2 ? 3 : pageCount;
for (var i = 0; i < buttonCount; i++) {
var index = +$scope.offset + i -1;
if (index > 0) {
buttons.push(index);
}
};
return buttons;
};
View in plunker
My suggestion is to use Angular UI bootstrap pagination, and not write it from scratch https://angular-ui.github.io/bootstrap/#/pagination
angular.module('ui.bootstrap.demo').controller('PaginationDemoCtrl', function ($scope, $log) {
$scope.totalItems = 64;
$scope.currentPage = 4;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
$scope.pageChanged = function() {
$log.log('Page changed to: ' + $scope.currentPage);
};
$scope.maxSize = 5;
$scope.bigTotalItems = 175;
$scope.bigCurrentPage = 1;
});
It's really not about angular related problem. Its all about the logic for $scope.generateButtons = function () {...} Please change your logic as you need. Here is your code (edited) for displaying 3 buttons.
$scope.generateButtons = function () {
var buttons = [],
pageCount = getPageCount(),
buttonCount;
buttonCount = pageCount > 2 ? 3 : pageCount;
for (var i = 0; i < buttonCount; i++) {
var index = parseInt($scope.offset) + i+1;
if (index >= 0) { // this `if` is not really needed
buttons.push(index);
}
};
return buttons;
};
Enjoy!

JSOM dynamicly get two announcements from all lists in all webs

Need help with the chaining. The functions work. But async calls make it hard for me to get everything. Help me think right!
My thought:
Get All Webs recursively (function works)
Get all lists from webs and iff announcementlist add to array and pass along
Get two items from all announcmentlists and sort by created.
Add ALL announcement items into one large array (to be able to sort array later.
Heres the code,
function getAllWebs(success, error) {
var ctx = SP.ClientContext.get_current();
var web = ctx.get_site().get_rootWeb();
var result = [];
var level = 0;
result.push(web);
var getAllWebsInner = function (web, result, success, error) {
level++;
var ctx = web.get_context();
var webs = web.get_webs();
ctx.load(webs, 'Include(Title,Webs,ServerRelativeUrl)');
ctx.executeQueryAsync(
function () {
for (var i = 0; i < webs.get_count() ; i++) {
var web = webs.getItemAtIndex(i);
result.push(web);
if (web.get_webs().get_count() > 0) {
getAllWebsInner(web, result, success, error);
}
}
level--;
if (level == 0 && success)
success(result);
},
error);
};
getAllWebsInner(web, result, success, error);
}
function error(sender, args) {
console.log(args.get_message());
};
function getAnnouncementLists(web, success, error) {
var dfd = $.Deferred();
var ctx = web.get_context();
var collList = web.get_lists();
var result = []
ctx.load(collList, 'Include(Title, Id, BaseTemplate)');
ctx.executeQueryAsync(function () {
for (var i = 0; i < collList.get_count() ; i++) {
var list = collList.getItemAtIndex(i);
var bTemp = list.get_baseTemplate();
if (bTemp == 104) {
result.push(list);
}
}
//success(result);
dfd.resolve(result);
}, error);
return dfd.promise();
}
function getListItems(list, success, error) {
var dfd = $.Deferred();
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><Query><OrderBy><FieldRef Name="Created" Ascending="False"></FieldRef>'
+ '</OrderBy></Query><ViewFields><FieldRef Name="Title"/><FieldRef Name="Body"/>' +
'<FieldRef Name="Created"/></ViewFields><RowLimit>2</RowLimit></View>');
var listItems = list.getItems(camlQuery);
var result = []
var ctx = list.get_parentWeb().get_context();
ctx.load(listItems);
ctx.executeQueryAsync(function () {
for (var i = 0; i < listItems.get_count() ; i++) {
var item = listItems.getItemAtIndex(i);
result.push(item);
}
dfd.resolve(result);
//success(result);
}, error);
return dfd.promise();
}
function printResults(items) {
var sortedItems = items.sort(dynamicSort("get_created()"));
alert(sortedItems);
}
function dynamicSort(property) {
var sortOrder = 1;
if (property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a, b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
$(document).ready(function () {
var items = getAllWebs(
function (allwebs) {
var array = [];
for (var i = 0; i < allwebs.length; i++) {
getAnnouncementLists(allwebs[i]).then(function (announceLists) {
for (var i = 0; i < announceLists.length; i++) {
getListItems(announceLists[i]).then(function (items) {
array.push(items);
});
}
});
}
return array;
}
);
//getAllWebs(
// function (allwebs) {
// for (var i = 0; i < allwebs.length; i++) {
// getAnnouncementLists(allwebs[i],
// function (announceLists) {
// for (var i = 0; i < announceLists.length; i++) {
// getListItems(announceLists[i],
// function (items) {
// printResults(items);
// }, error);
// }
// }, error);
// }
// }, error);
});
Given the requirements to retrieve list items from Announcements lists located across site collection, below is demonstrated the modified example that contains some improvements such as:
the number of requests to the server is reduced
fixed the issue in getAllWebs function that prevents to return any results if site contains only a root web
Example
function getAllWebs(propertiesToRetrieve,success, error) {
var ctx = SP.ClientContext.get_current();
var web = ctx.get_site().get_rootWeb();
var result = [];
var level = 0;
ctx.load(web, propertiesToRetrieve);
result.push(web);
var getAllWebsInner = function (web, result, success, error) {
level++;
var ctx = web.get_context();
var webs = web.get_webs();
var includeExpr = 'Include(Webs,' + propertiesToRetrieve.join(',') + ')';
ctx.load(webs, includeExpr);
ctx.executeQueryAsync(
function () {
for (var i = 0; i < webs.get_count() ; i++) {
var web = webs.getItemAtIndex(i);
result.push(web);
if (web.get_webs().get_count() > 0) {
getAllWebsInner(web, result, success, error);
}
}
level--;
if (level == 0 && success)
success(result);
},
error);
};
getAllWebsInner(web, result, success, error);
}
function loadListItems(lists,query,success,error,results){
var results = results || [];
var curList = lists[0];
var ctx = curList.get_context();
var listItems = curList.getItems(query);
ctx.load(listItems);
ctx.executeQueryAsync(function () {
results.push.apply(results, listItems.get_data());
lists.shift();
if(lists.length > 0) {
loadListItems(lists,query,success,error,results);
}
if(lists.length == 0)
success(results);
}, error);
}
function dynamicSort(property) {
var sortOrder = 1;
if (property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a, b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
var propertiesToRetrieve = ['Lists.Include(BaseTemplate)','ServerRelativeUrl'];
getAllWebs(propertiesToRetrieve,
function(allwebs){
//1. get filtered lists
var allAnnouncementLists = [];
allwebs.forEach(function(w){
var announcementLists = w.get_lists().get_data().filter(function(l){
if(l.get_baseTemplate() == SP.ListTemplateType.announcements)
return l;
});
allAnnouncementLists.push.apply(allAnnouncementLists, announcementLists);
});
//2.Load list items from lists
var query = new SP.CamlQuery(); //<-set your custom query here
loadListItems(allAnnouncementLists,query,
function(allListItems){
//3.Sort and print results
var sortedItems = allListItems.sort(dynamicSort("get_created()"));
sortedItems.forEach(function(item){
console.log(item.get_item('Title'));
});
},logError);
},
logError);
function logError(sender,args){
console.log(args.get_message());
}

Js Pagination error

I need to perform a pagination where I need to display 5 rows every time. First 5 rows are displayed. On the second click, the next 5, the third rows no. 11-15, and so on. I need to display even if at least one row is there (after n clicks where totalRows mod 5 is less than 5). I do not get this.
function rightArrow()
{
pageCount = document.getElementById('pgCnt').value; //totalRows / 5
totCount = document.getElementById('totCnt').value; //totalRows
currPage = tempRows - pageCount + 2; //current set of rows
document.getElementById('tempPage').value = tempPage;
var m = totCount%5;
if(pageCount != tempRows)
m = 5;
else
{ m = (totCount % 5) - 1;
document.getElementById('rightArr').disabled = true;
}
document.getElementById('pgCnt').value = document.getElementById('pgCnt').value - 1;
for(i = 0; i < m;i++)
{
$.ajax({
type: "POST",
url: "getEODRow.php",
data: "page=" + currPage + "&row=" + i,
success: function(html)
{
var row = document.getElementById('chRecommend').insertRow(0);
temp = html.split(",");
for(j = 0; j < 9; j++)
{
str = temp[j].replace("\"","");
str = temp[j].replace("\"",'');
str = temp[j].replace("[",'');
col = row.insertCell(j);
col.innerHTML = str;
}
}
});
}
currPage++;
}
I realize this question is pretty much dead, but I came across it looking for something else, and I figured I'd toss an answer at it. Since it's not a critical issue, I went ahead and reworked everything you've got here plus a lot of code that you didn't choose to include.
// App namespace
var MyApp = {Paging: {}};
// Paging Controller
MyApp.Paging.Controller = function(){ this.init.apply(this,arguments);};
MyApp.Paging.Controller.prototype =
{
// Initializer gets everything hooked up
init: function()
{
$.log("Initializing Paging Controller.")
// Get all the nodes we'll need
this.totCntNode = document.getElementById("totCnt");
this.pgCntNode = document.getElementById("pgCnt");
this.currMinNode = document.getElementById("currMin");
this.currMaxNode = document.getElementById("currMax");
this.prevPageButton = document.getElementById("prevPageButton");
this.nextPageButton = document.getElementById("nextPageButton");
this.pageContainer = document.getElementById("pageOfItems");
// Mimic table's .insertRow to make row adding easy
this.pageContainer.insertRow = function() {
var row = document.createElement("div");
row.className = "row clearfix";
for (var i = 0; i < MyApp.Paging.Model.itemsPerRow; i++)
{
var cell = document.createElement("span");
row.appendChild(cell);
}
this.appendChild(row);
return row;
};
// Attach listeners to the next and previous buttons
this.prevPageButton.onclick = this.showPrevPage.bind(this);
this.nextPageButton.onclick = this.showNextPage.bind(this);
// Update the display for the first time
this.updatePageInfo();
},
// Run this whenever the model has changed and needs to update the display
updatePageInfo: function()
{
// Get info about what page we're on
var currentPage = MyApp.Paging.Model.currentPage,
totalPages = MyApp.Paging.Model.getTotalPages(),
itemCount = MyApp.Paging.Model.itemCount,
pageSize = MyApp.Paging.Model.getPageSize(),
rowsPerPage = MyApp.Paging.Model.rowsPerPage,
rowsOnThisPage = Math.ceil(MyApp.Paging.Model.getItemsOnPage(currentPage)/MyApp.Paging.Model.itemsPerRow);
// Clear out previous page data
while (this.pageContainer.children.length > 0)
{
this.pageContainer.removeChild(this.pageContainer.children[0]);
}
// Add space for the new page data
for (var rowInd = 0; rowInd < rowsOnThisPage ; rowInd++)
{
this.pageContainer.insertRow();
}
$.log("Loading Page " + currentPage + ".");
// Request the data via ajax for each row
for(var i = 0; i < rowsOnThisPage ; i++)
{
$.ajax({
type: MyApp.Paging.Model.queryType,
url: MyApp.Paging.Model.queryURI,
data: MyApp.Paging.Model.getQueryData(currentPage, i),
success: function(pageNum, rowNum, result)
{
// Don't serve data from the wrong page
if (pageNum !== MyApp.Paging.Model.currentPage) return;
// When we get the data back, put it into the correct container
// regardless of when it was received
var row = this.pageContainer.children[rowNum],
temp = result.replace(/[\["]/g,"").split(","),
str = "";
for(var j = 0; j < temp.length; j++)
{
row.children[j].innerHTML = temp[j];
}
}.bind(this, currentPage, i)
});
}
// Update the informational bits under the items
this.totCntNode.textContent = itemCount;
this.pgCntNode.textContent = totalPages;
var min = currentPage * (pageSize ) + 1;
this.currMinNode.textContent = min;
this.currMaxNode.textContent = Math.min(min + pageSize - 1, itemCount);
// Disable the prev page button if there are no previous pages
if (currentPage <= 0)
{
if (this.prevPageButton.className.indexOf("disabled") < 0)
{
this.prevPageButton.className += " disabled";
}
}
// Enable the prev page button if there are previous pages
else
{
if (this.prevPageButton.className.indexOf("disabled") > -1)
{
this.prevPageButton.className = this.prevPageButton.className.replace(/(?:^|\s+)disabled(?!\S)/g, "");
}
}
// Disable the next page button if there are next pages
if (currentPage + 1 >= totalPages)
{
if (this.nextPageButton.className.indexOf("disabled") < 0)
{
this.nextPageButton.className += " disabled";
}
}
// Enable the next page button if there are next pages
else
{
if (this.nextPageButton.className.indexOf("disabled") > -1)
{
this.nextPageButton.className = this.nextPageButton.className.replace(/(?:^|\s+)disabled(?!\S)/g, "");
}
}
},
// This is called when the next page button is clicked.
showNextPage: function()
{
if (MyApp.Paging.Model.currentPage + 1 >= MyApp.Paging.Model.getTotalPages())
{
// Shouldn't have been able to activate this anyway
}
else
{
MyApp.Paging.Model.currentPage++;
this.updatePageInfo();
}
return false;
},
// This is called when the prev page button is clicked
showPrevPage: function()
{
if (MyApp.Paging.Model.currentPage <= 0)
{
// Shouldn't have been able to activate this anyway
}
else
{
MyApp.Paging.Model.currentPage--;
this.updatePageInfo();
}
return false;
}
};
// I typically expect an object like this to be created by the server and dropped dynamically onto the page
MyApp.Paging.Model = {
itemCount: 140,
itemsPerRow: 9,
rowsPerPage: 5,
currentPage: 0,
queryType: "POST",
queryURI: "getEODRow.php",
queryDataFormat: "page={itemPage}&row={itemRow}",
getTotalPages: function() {
with(MyApp.Paging.Model) {
return Math.ceil(itemCount/(itemsPerRow*rowsPerPage));
}
},
getPageSize: function() {
with(MyApp.Paging.Model) {
return itemsPerRow * rowsPerPage;
}
},
getItemsOnPage: function(pageNum) {
with(MyApp.Paging.Model) {
return Math.min(((pageNum+1) * getPageSize()), itemCount) - pageNum*getPageSize();
}
},
getItemsInRow: function(pageNum, rowNum) {
with(MyApp.Paging.Model) {
var onPage = getItemsOnPage(pageNum);
return Math.min((rowNum+1)*itemsPerRow, onPage) - rowNum*itemsPerRow;
}
},
getQueryData: function(itemPage, itemRow) {
with(MyApp.Paging.Model) {
var data = queryDataFormat;
data = data.replace(/{itemPage}/gi, itemPage);
data = data.replace(/{itemRow}/gi, itemRow);
return data;
}
}
};
So, whenever the page is loaded, with an onload handler or whatever, you would create and hang onto a singleton instance of the Paging Controller.
MyApp.Paging.Controller.instance = new MyApp.Paging.Controller();
This should handle issues with Ajax calls returning out of order as well as partial pages of data and partial rows within those pages.
Demo: http://jsfiddle.net/2UJH8/8/

Categories