Pagination of nested objects in angular js - angularjs

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>

You can do this using a combination of:
A custom filter (to determine how many records to skip), and...
The built in limitTo filter (to limit the number of records to the desired page size)
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

Related

AngularJS orderBy property incorrect

I'm iterating over an array of objects and would like them sorted alphabetically by the 'ecuName' property. I don't understand why 'HVAC' is rendering before 'ABC'.
"ecuInfoList": [
{
"id": 4,
"ecuName": "ACC"
},
{
"id": 6,
"ecuName": "HVAC"
},
{
"id": 5,
"ecuName": "ABG"
}
]
Edit
Forgot to add the template code.
<div ng-repeat="ecu in config.ecuInfoList | orderBy:'ecuName' track by $index"><strong>{{ ecu.ecuName }}</strong>...
You might now access the array with ng-repeat properly. Check the working DEMO
DEMO
var app = angular.module('testApp',[]);
app.controller('testCtrl',function($scope){
$scope.data = { "ecuInfoList": [
{
"id": 4,
"ecuName": "ACC"
},
{
"id": 6,
"ecuName": "HVAC"
},
{
"id": 5,
"ecuName": "ABG"
}
]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="testApp" ng-controller="testCtrl">
<div ng-repeat="mydata in data.ecuInfoList | orderBy:'ecuName'">
{{mydata.ecuName}}
</div>
</body>

want to display names separated by comma

here is the program for display book details.everything is working perfect but i dont know how to display authorname separated by comma(,).I want to display author name separated by comma(,) in home page.the third line is error.that I want to fix and display authornames.
home.html
<script type="text/ng-template" id="display">
<td>{{book.title}}</td>
errorline: <td>{{book.authorname}}</td>(Here i want to display author names separated by comma(,))
<td>{{book.price}}</td>
<td>
<i class="material-icons"><button type="button" data-ng-click="editBook(book)">create</button></i>
</td>
<td><i class="material-icons"><button type="button" data-ng-click="deleteBook(book)">delete_forever</button></i></td>
</script>
controllers.js
$scope.online_bookauthors= 'data/bookauthors.js';
$scope.loadbookauthorscadentials= function (file) {
$http.get(file)
.then(function (result) {
$scope.bookauthorsresult=result;
$scope.bookauthorslist=$scope.bookauthorsresult.data.bookauthorsdetails;
})
}
$scope.loadbookauthorscadentials($scope.online_bookauthors);
bookauthors.js
{
"bookauthors": {
"Id": 1,
"name": "Book Author Details"
},
"bookauthorsdetails": [{
"bookid": 1,
"title": "War and piece",
"price": 100,
"authors": [{
"authorid": 1,
"authorname": "Tolstoy"
}, {
"authorid": 2,
"authorname": "Herman melville"
}]
}, {
"bookid": 2,
"title": "moby Dick",
"price": 200,
"authors": [{
"authorid": 1,
"authorname": "Tolstoy"
}, {
"authorid": 2,
"authorname": "Herman melville"
}, {
"authorid": 3,
"authorname": "Jane Austen"
}]
}],
"selected": {}
}
<div ng-repeat="author in book.authors">{{ ($index !== book.authors.length-1) ? author.authorname+',' : author.authorname }}</div>

How to set Where Clause for a inner ng-repeat in angularJS

I'm having a two JSON array,
$scope.color = [
{
"cInstId": 1,
"cInstTitle": "Blue"
},
{
"cInstId": 2,
"cInstTitle": "Green"
},
{
"cInstId": 3,
"cInstTitle": "Red"
},
{
"cInstId": 4,
"cInstTitle": "Orange"
},
{
"cInstId": 5,
"cInstTitle": "Violet"
}
];
$scope.data = [
{
"id": 1,
"cTitle": "One",
"cInstId": 1
},
{
"id": 2,
"cTitle": "Two",
"cInstId": 2
},
{
"id": 3,
"cTitle": "Three",
"cInstId": 3
},
{
"id": 4,
"cTitle": "Four",
"cInstId": 4
},
{
"id": 5,
"cTitle": "Five",
"cInstId": 4
}
];
Now I need to print all the $scope.color with associated $scope.data with a common key value in cInstId
<div ng-repeat="col in color">
<p>{{ col.cInstTitle }}</p>
<ol>
<li ng-repeat="dataItem in data| **WHERE CLAUSE dataItem.cInstId = col.cInstId** ">
<div>{{ dataItem.cTitle }}</div>
</li>
</ol>
</div>
You could use just ng-if clause. Use this line -
<li ng-if="dataItem.cInstId=== col.cInstId" ng-repeat="dataItem in data">
You can use a filter as follows
<li ng-repeat="dataItem in data | filter : {cInstId: col.cInstId}">
<div>{{ dataItem.cTitle }}</div>
</li>
The following filter criteria will filter dataItem objects in data array based on cIntsId key.
filter : {cInstId: col.cInstId}
Plunker

Ng-option directive cant get access to nested array value

Help
I'm trying to output different class options(economy/business) with ng-options.
Here is the syntax and json information .
Cant get it working
<select ng-model="mySelect" ng-options="item for item in items ">
</select>
$scope.items = [
{
"id": 2,
"codeName": "class",
"friendlyName": "Class",
"options":
[
{
"id": 15,
"displayOrderNo": 0,
"optionName": "Economy"
},
{
"id": 16,
"displayOrderNo": 1,
"optionName": "Business"
},
{
"id": 36,
"displayOrderNo": 2,
"optionName": "First Class "
}
]
}
];

Grouping objects with AngularJS

I have a bunch of objects in an array and I am trying to figure out how to group them within an Angular repeater. For example I want to group the fruit items with a parentTag key to the Tag key of a parent. So Fruit has a tag of 1 and Apple has a parent tag with a value of 1, meaning Apple is grouped with Fruit.
so using this array...
[
{
"code":"Fruit",
"tag":1
},
{
"code":"Apple",
"tag":2,
"parentTag":1
},
{
"code":"Vegetable",
"tag":3
},
{
"code":"Meat",
"tag":4
},
{
"code":"Banana",
"tag":5,
"parentTag":1
},
{
"code":"Carrot",
"tag":6,
"parentTag":3
},
{
"code":"Chicken",
"tag":7,
"parentTag":4
}
]
I am trying to group the objects like this...
Fruit
Apple
Banana
Vegetable
Carrot
Meat
Chicken
So far I have a repeater that only displays the objects...
<div ng-repeat="product in products">
{{code}}
<span ng-if="product.tag != null">{{product.tag}}</span>
<span ng-if="product.parentTag > null">{{product.parentTag}}</span>
</div>
But I don't know how to use the groupBy in this case. any ideas?
Please see demo below
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.products = [{
"code": "Fruit",
"tag": 1
}, {
"code": "Apple",
"tag": 2,
"parentTag": 1
}, {
"code": "Vegetable",
"tag": 3
}, {
"code": "Meat",
"tag": 4
}, {
"code": "Banana",
"tag": 5,
"parentTag": 1
}, {
"code": "Carrot",
"tag": 6,
"parentTag": 3
}, {
"code": "Chicken",
"tag": 7,
"parentTag": 4
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="app">
<div ng-controller="homeCtrl">
<div ng-repeat="product in products | filter :{parentTag:'!'}">
<h3>{{product.code}}</h3>
<div ng-repeat="subproduct in products | filter :{parentTag:product.tag}">
<span>{{subproduct.code}}</span>
<span>{{subproduct.tag}}</span>
<span>{{subproduct.parentTag}}</span>
</div>
</div>
</div>
</body>

Resources