Reputation: 71
I am starting out with angular and I have a nested object which i would like to paginate. The items to be paginated are some of the 'attributes' in the given object. The queuelist object is nested with array within array. Any help would be appreciated. The plunker link for non-paginated data is:
https://plnkr.co/edit/zgo0msd6y5ba6DJ6qGlc?p=preview
app.js:
var app = angular.module("myApp",[])
.controller("mycontroller",['$scope',function($scope){
$scope.queuelist = [
{
"name": "ONE",
"QueueList": [
{
"id": 1,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:64"
},
{
"id": 2,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:65"
},
{
"id": 3,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:66"
}
],
"$$hashKey": "object:59"
},
{
"name": "TWO",
"QueueList": [
{
"id": 4,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:72"
},
{
"id": 5,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:73"
},
{
"id": 6,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:74"
},
{
"id": 7,
"attributes": {
"a": 1,
"b": "2017-07-25T12:57:06Z",
"c": 1500967626000,
"d": "asdasd",
"e": "aasdasdasd",
"f": 0
},
"$$hashKey": "object:75"
}
],
"$$hashKey": "object:60"
}
];
$scope.objects = [];
/*
for(i=0;i<$scope.data.length;i++){
$scope.data2.push($scope.data[i].QueueList);
};
*/
for(i=0;i<$scope.queuelist.length;i++){
for(j=0;j<$scope.queuelist[i].QueueList.length;j++){
$scope.objects.push($scope.queuelist[i].QueueList[j].attributes);
};
};
}])
and index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script type= "text/javascript" src= "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script type= "text/javascript" src= "app.js"></script>
<style>
table, td, th {
border: 1px solid #ddd;
text-align: left;
}
table {
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 15px;
}
</style>
</head>
<body>
<div ng-controller="mycontroller">
<div ng-repeat="queueJob in queuelist">
{{queueJob.name}}
<table>
<thead>
<tr>
<th><b>a</b></th>
<th><b>b</b></th>
<th><b>c</b></th>
<th><b>e</b></th>
<th><b>f</b></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="queue in queueJob.QueueList">
<td>{{queue.attributes.a}}</td>
<td>{{queue.attributes.b}}</td>
<td>{{queue.attributes.c}}</td>
<td>{{queue.attributes.e}}</td>
<td>{{queue.attributes.f}}</td>
</tr>
<br/><br/>
</tbody>
</table>
<br/><br/>
<br/><br/>
</div>
</div>
</body>
</html>
Upvotes: 4
Views: 1225
Reputation: 2818
You can do this using a combination of:
1) First create the custom filter.
app.filter("startFrom", function thisFilter() {
return function(input, index) {
return input.slice(parseInt(index));
};
});
The filter takes in an index
which it goes on to use in the Array.prototype.slice() method. The slice()
method slices the array at the given index and returns a new array containing all remaining objects. The filter returns the new array.
2) Use the custom filter and built-in limitTo filter in the ng-repeat
directive.
<tr ng-repeat="queue in queueJob.QueueList | startFrom: queueJob.pageIndex | limitTo: 1">
Here we use the newly created startFrom
custom filter passing it the queueJob.pageIndex
property as the filter's index
parameter. We pass the results of the startFrom
filter onto the limitTo
filter which reduces the number of records to 1
.
Note: We have to use the pageIndex
property on the queueJob
itteration variable because this ng-repeat
is contained within another ng-repeat
and so a $scope.pageIndex
variable would have been conflicted and subsequently overwritten.
3) Create next and previous buttons
<tr>
<td colspan="5">
<button class="btn"
ng-click="onPrevClicked(queueJob)"
ng-disabled="isFirst(queueJob)">
<span class="fa fa-chevron-left"></span>
Prev
</button>
<button class="btn"
ng-click="onNextClicked(queueJob)"
ng-disabled="isLast(queueJob)">
Next
<span class="fa fa-chevron-right"></span>
</button>
Page {{ queueJob.pageIndex + 1 }}
</td>
</tr>
Here we use ng-click
directives to invoke controller functions that increment/decrement the queueJob
object's pageIndex
property. We also use ng-disabled
directives to prevent navigating next/previous if the user is on the first/last record.
4) Create the bindable functions in the controller
$scope.onPrevClicked = onPrevClicked;
$scope.onNextClicked = onNextClicked;
$scope.isFirst = isFirst;
$scope.isLast = isLast;
function onPrevClicked(obj) {
if (!isFirst(obj)) obj.pageIndex--;
}
function onNextClicked(obj) {
if (!isLast(obj)) obj.pageIndex++;
}
function isFirst(obj) {
return obj.pageIndex === 0;
}
function isLast(obj) {
return obj.pageIndex + 1 === obj.QueueList.length;
}
5) Initialise the pageIndex
properties upfront
$scope.queuelist.forEach(function(obj) {
obj.pageIndex = 0;
});
This initialised the pageIndex
as a number that can be incremented and subsequently decremented.
Demo
CodePen: Using a custom filter to do pagination
Upvotes: 3