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!
Related
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?
I am using angularJs and I use this function in my controller to get data from database
this.callServer = function callServer(criteria) {
ctrl.searchParameters = criteria;
ctrl.isLoading = true;
var start = $scope.itemsPerPage * ($scope.currentPage - 1);
var limit = $scope.itemsPerPage;
service.getRandomsItems(criteria, start, limit).then(
function(result) {
var remainder = $scope.totalItems % $scope.itemsPerPage
if (remainder > 0)
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage) + 1;
else
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage);
ctrl.displayed = result.randomsItems;
$scope.totalItems = result.total;
ctrl.isLoading = false;
});
};
}
and I call this function in my controller too to handle the paging issue
$scope.pageChanged = function(currentPage) {
$scope.currentPage = currentPage;
ctrl.callServer($scope.criteria);
}
As you can see, my function callServer returns ctrl.displayed which is the rows that displayed in current page
Now I want to work with new page so I called ctrl.callServer to get new page then I called ctrl.selectCurrentPage() just like that
$scope.pageChanged = function(currentPage) {
$scope.currentPage = currentPage;
ctrl.callServer($scope.criteria);
ctrl.selectCurrentPage() // I want this function to be called when ctrl.callServer($scope.criteria) is finished
}
where
ctrl.selectCurrentPage = function() {
ctrl.selection.push(this.displayed[i].userId);
ctrl.selectionRow.push(this.displayed[i]);
}
in Simple English I want ctrl.selectCurrentPage to be called when ctrl.callServer is finsih and get the new data
but that not happen.
Just return a promise from callServer and use it in pageChanged.
The first step:
this.callServer = function callServer(criteria) {
ctrl.searchParameters = criteria;
ctrl.isLoading = true;
var start = $scope.itemsPerPage * ($scope.currentPage - 1);
var limit = $scope.itemsPerPage;
return service.getRandomsItems(criteria, start, limit).then(function(result) {
var remainder = $scope.totalItems % $scope.itemsPerPage
if (remainder > 0)
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage) + 1;
else
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage);
ctrl.displayed = result.randomsItems;
$scope.totalItems = result.total;
ctrl.isLoading = false;
});
};
Then:
$scope.pageChanged = function(currentPage) {
$scope.currentPage = currentPage;
ctrl.callServer($scope.criteria).then(function () {
ctrl.selectCurrentPage();
});
}
Try to avoid callback hell. Please read the article for some useful information.
pass it as a callback;
this.callServer = function callServer(criteria, callback) {
ctrl.searchParameters = criteria;
ctrl.isLoading = true;
var start = $scope.itemsPerPage * ($scope.currentPage - 1);
var limit = $scope.itemsPerPage;
service.getRandomsItems(criteria, start, limit).then(
function(result) {
var remainder = $scope.totalItems % $scope.itemsPerPage
if (remainder > 0)
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage) + 1;
else
$scope.numPages = parseInt($scope.totalItems / $scope.itemsPerPage);
ctrl.displayed = result.randomsItems;
$scope.totalItems = result.total;
ctrl.isLoading = false;
callback();
});
};
} ]);
$scope.pageChanged = function(currentPage) {
$scope.currentPage = currentPage;
ctrl.callServer($scope.criteria, ctrl.selectCurrentPage);
}
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;
};
};
I'm trying to create subsets of an Array in a recurring manner. I've an Array in the form of [0,1,2,3,4,5,6]. I'd like to create subsets like [0,1,2], [1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,0],[6,0,1],[0,1,2] and so on. But, its not breaking after [4,5,6].
Here is my code
var app = angular.module('app',[]);
app.controller('EventController',function EventController($scope) {
$scope.count = 0;
var arr = [], subArr = [], currentIndex;
for(var i = 0; i < 7; i++) {
arr.push(i)
}
$scope.next = function() {
currentIndex = $scope.count;
subArr = [];
$scope.count++;
subArr.push(currentIndex);
subArr.push(currentIndex+1);
subArr.push(currentIndex+2);
if(arr.indexOf(currentIndex+1) == -1) {
console.log(currentIndex+1,'Element not available');
$scope.count = 0;
currentIndex = $scope.count
}
console.log(subArr);
}
});
Here is the fiddle
Any ideas would be greatly appreciated.
Try this:
var app = angular.module('app',[]);
app.controller('EventController',function EventController($scope) {
$scope.count = 0;
var subArr = [], currentIndex;
$scope.arr = [];
for(var i = 0; i < 7; i++) {
$scope.arr.push(i);
}
$scope.next = function() {
currentIndex = $scope.count;
//console.log(currentIndex);
subArr = [];
$scope.count++;
subArr.push(currentIndex);
if($scope.arr.indexOf(currentIndex) == $scope.arr.length -2) {
console.log(currentIndex+2,'Element not available');
subArr.push(currentIndex+1);
$scope.count = 0;
subArr.push($scope.arr[0]);
}
else if($scope.arr.indexOf(currentIndex) == $scope.arr.length -1) {
console.log(currentIndex+1,'Element not available');
subArr.push($scope.arr[0]);
subArr.push($scope.arr[1]);
currentIndex = $scope.count;
}
else{
subArr.push(currentIndex+1);
subArr.push(currentIndex+2);
}
console.log(subArr);
}
});
The problem is, you are pushing elements before if condition.
1. Move the if block before pushing data to array
2. Change arr.indexOf(currentIndex+1) == -1 to arr.indexOf(currentIndex+2) == -1
var app = angular.module('app',[]);
app.controller('EventController',function EventController($scope) {
$scope.count = 0;
var arr = [], subArr = [], currentIndex;
for(var i = 0; i < 7; i++) {
arr.push(i)
}
$scope.next = function() {
currentIndex = $scope.count;
//console.log(currentIndex);
subArr = [];
$scope.count++;
subArr.push((currentIndex)%arr.length);
subArr.push((currentIndex+1)%arr.length);
subArr.push((currentIndex+2)%arr.length);
console.log(subArr);
}
});
I guess the below code will help. It is self explanatory.
function createSubset (array, subsetSize, subsets){
var inputArray = array,
subset,
subsetCollection = [],
noOfSubsets = subsets || inputArray.length + 1,
size = subsetSize,
current = 0,
i;
while (noOfSubsets--) {
subset = [];
for (i = 0; i < size; i++) {
subset.push( inputArray[ (current + i) % inputArray.length] );
}
current += 1 ;
subsetCollection.push(subset);
}
return subsetCollection;
}
console.log('Test Case start');
var a = [0,1,2,3,4,5,6],
result = createSubset(a, 3);
console.log(result);
console.log('Test Case end');
console.log('Test Case start');
var a = [0,1,2,3,4,5,6],
result = createSubset(a, 3, 4);
console.log(result);
console.log('Test Case end');
My HTML has a loop with ng-repeat:
<div class="row">
<div ng-repeat="item in model.painel track by item.codigoIncidente">
<strong>{{item.restante.horaMinutoSegundo}}</strong>
</div>
</div>
My controller has a $interval that decrement horaMinutoSegundo.
nihilApp.controller('IncidentePainelController', ['$scope', '$interval', 'Incidente', function ($scope, $interval, Incidente) {
$scope.model = {
painel: [],
};
var find = function() {
Incidente.listPainel({pagina: 0}).$promise.then(function (result) {
$scope.model.painel = result.pagedList;
$scope.model.totalItems = result.totalGeral;
}, function (error) {
console.log(error);
});
};
var updateTime = function() {
for (var i = 0; i < $scope.model.painel.length; i++) {
if ($scope.model.painel[i].status.id === 'E' && $scope.model.painel[i].restante.segundos > 0) {
var segundos = $scope.model.painel[i].restante.segundos - 1;
$scope.model.painel[i].restante.horaMinutoSegundo = getHoraMinutoSegundo(segundos);
}
}
};
var getHoraMinutoSegundo = function (segundos) {
var horaMath = Math.floor(segundos / 3600);
var remMath = Math.floor(segundos % 3600);
var minutoMath = Math.floor(remMath / 60);
var segundoMath = Math.floor(remMath % 60);
var hrStr = (horaMath < 10 ? "0" : "") + horaMath;
var mnStr = (minutoMath < 10 ? "0" : "") + minutoMath;
var secStr = (segundoMath < 10 ? "0" : "") + segundoMath;
return hrStr.concat(":").concat(mnStr).concat(":").concat(secStr);
};
$interval(updateTime, 1000);
find();
}]);
But the {{item.restante.horaMinutoSegundo}} does not update in HTML. Can someone help me with this problem ? Thanks a lot!
https://jsfiddle.net/araraujo/96w3jrrh/
It should work, but you have a little mistake in your code.
var segundos = $scope.model.painel[i].restante.segundos - 1;
You put new segundos value into a variable, but you didn't update the one from scope.
Here is the fiddle with the updated version
There are two things you need to change
inject $interval in your controller
app.controller('MainCtrl', function($scope, $interval) {
}
Update your model so that it match the with your logic inside for loop. Something like below.
$scope.model = {
painel: [{restante : 1 }] }
you must add $scope.apply at the end.
var updateTime = function() {
for (var i = 0; i < $scope.model.painel.length; i++) {
if ($scope.model.painel[i].status.id === 'E' && $scope.model.painel[i].restante.segundos > 0) {
var segundos = $scope.model.painel[i].restante.segundos - 1;
$scope.model.painel[i].restante.horaMinutoSegundo = getHoraMinutoSegundo(segundos);
}
}
$scope.apply();
};
Found the gap, replace this line
var segundos = $scope.model.painel[i].restante.segundos - 1;
With
scope.model.painel[i].restante.segundos = $scope.model.painel[i].restante.segundos - 1;