Grouping objects with AngularJS - 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>

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>

AngularJS filter field according to values of an array

I have an Array and this array contains some Id's.
I would like to filter my result according to Id's.
For Example please see the below code snippet.
How can I show the records which 'StatusId' located in the 'ids' array?
According to my example, I want to list only:
AAA
BBB
CCC
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
angular.module('myApp', []).controller('ctrl', function ($scope) {
$scope.ids = [{
"id": 1
}, {
"id": 2
}, {
"id": 3
}]
$scope.records = [
{
"Name": "AAA",
"StatusId": 1
},
{
"Name": "BBB",
"StatusId": 1
},
{
"Name": "CCC",
"StatusId": 2
},
{
"Name": "DDD",
"StatusId": 4
},
{
"Name": "EEE",
"StatusId": 4
},
]
});
</script>
<body>
<div id="idctrl" ng-app="myApp" ng-controller="ctrl">
<ul>
<li ng-repeat="x in records">
{{ x.Name }}
</li>
</ul>
</div>
</body>
</html>
You can use the javascript 'filter' function:
records = $scope.records.filter((record) => {
return record.StatusId === 1
});
This will return a new array that only contains records with a StatusId of 1. You can these use this updated array to display your desired records.

Show JSON data as selected in Select AngularJS

I don' have a lot of knowledge about AngularJS. I have a JSON with all the data and first I created a select and according to the selected option I show some data or others according to the value, which are the IDs in the json
JSON
$scope.players = [
{
"player": {
"info": {
"position": "D",
"shirtNum": 4,
"positionInfo": "Centre/Right Central Defender"
},
"nationalTeam": {
"isoCode": "BE",
"country": "Belgium",
"demonym": "Belgian"
},
"age": "27 years 139 days",
"name": {
"first": "Toby",
"last": "Alderweireld"
},
"id": 4916,
"currentTeam": {
"name": "Tottenham Hotspur",
"teamType": "FIRST",
"shortName": "Spurs",
"id": 21
}
},
"stats": [
{
"name": "goals",
"value": 5
},
{
"name": "losses",
"value": 20
},
{
"name": "wins",
"value": 48
},
{
"name": "draws",
"value": 23
},
{
"name": "fwd_pass",
"value": 1533
},
{
"name": "goal_assist",
"value": 2
},
{
"name": "appearances",
"value": 80
},
{
"name": "mins_played",
"value": 6953
},
{
"name": "backward_pass",
"value": 308
}
]
},
...];
HTML
<select id="select-players" ng-model="Jugador" ng-options="jugador as (jugador.player.name.first + ' ' + jugador.player.name.last) for jugador in players track by jugador.player.id " ng-change="show()">
<option value="">Select a player...</option>
</select>
And I want to show the details of the player
<div class="content-player">
<div class="img-team"><span class="img-escudo"><img src="img/tottenham.png" /></span></div>
<p class="name-player">{{jugador.player.name.first}} {{jugador.player.name.last}} <span class="pos-player">{{jugador.info.positionInfo}}</span></p>
<div class="cont-desc-player">
<div class="desc-player">
<span class="txt-estadistics">{{jugador.stats.name}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
</div>
</div>
I don't know if I need to create in the controller one switch or using only if and else if is good and how can call it in HTML to show the details.
Thanks
You are using the iterated current object jugador in place of using the Model name Jugador. Try using Jugador.player.name.first instead of jugador.player.name.first and it should work fine if rest of the things are ok.
I also don't see the need of ng-change="show()" in your case. Model changes automatically as you change the select value and you can use it.
You use the iterated object name jugador while doing ng-repeat.

Complicated sorting with tabs in ng-repeat?

I have the following JSON object:
$scope.projects = [
{
"_id": "58ab1cb6edf5430e9014e2bc",
"name": "Project 1",
"issues": [
{
"status": 0,
"name": "Hart Cummings"
},
{
"status": 1,
"name": "Kinney Leach"
},
{
"status": 2,
"name": "Blake Mclaughlin"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 2",
"issues": [
{
"status": 0,
"name": "Vargas Gordon"
},
{
"status": 1,
"name": "Bobbie Church"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 3",
"issues": [
{
"status": 0,
"name": "WWWWW"
},
{
"status": 1,
"name": "SFSF"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
}
];
I use ng-repeat to display this object in template:
<div ng-app="app">
<div ng-controller="TodoListController">
<div ng-repeat="project in projects">
<br>
<br>
<div><b> {{project.name}}</b></div>
<div class="tabs">
<div style="display:inline" ng-click="sort(1, $index);">Active</div> |
<div style="display:inline" ng-click="sort(0, $index);">Deactivated</div>
</div>
_____________________________________
<div ng-repeat="issue in project.issues | filter: (filterObject.index | filterObject.status)">
<div>{{issue.name}}</div>
</div>
</div>
</div>
</div>
So, as you can see I have two nested ng-repeat.
Issue is:
When I click on any tab and call method sort() I need to sort issue in project.issues by status field.
This is real sample that I want to reach.
https://jsfiddle.net/at6kw67g/
Problem is in this code:
<div ng-repeat="issue in project.issues | filter:filterObject.index : {status : filterObject.status}">
Since the links should sort the issues of a specific project, you should pass the project as argument to your sort() function.
And JavaScript arrays have a sort() method, so just use it.
Since one link should sort issues in ascanding order, and the other one in descending order, you should also pass this information to your sort() function.
So it boils down to
$scope.sortIssuesByStatus = function(project, descending) {
project.issues.sort(function(issue1, issue2) {
var result = issue1.status - issue2.status;
if (descending) {
result = -result;
}
return result;
});
}
and
<div ng-repeat="project in projects">
<div class="tabs">
<button ng-click="sortIssuesByStatus(project, true)">Active</button>
<button ng-click="sortIssuesByStatus(project, false)">Deactivated</button>
</div>
<div ng-repeat="issue in project.issues">
<div>{{issue.name}} - {{ issue.status }}</div>
</div>
</div>
Here's a plunkr implementing it.

AngularJS: How to develop master with nested details using ng-repeat

i have read this post https://stackoverflow.com/a/18295177/6188148
but my json looks bit different. here is my json.
[{"ID":1,"Name":"Suzy","ParentID":0},
{"ID":2,"Name":"Somi","ParentID":1},
{"ID":3,"Name":"Romi","ParentID":2},
{"ID":4,"Name":"Jumi","ParentID":3},
{"ID":5,"Name":"Gargi","ParentID":0},
{"ID":6,"Name":"Sujoy","ParentID":5},
{"ID":7,"Name":"Kamal","ParentID":6},
{"ID":8,"Name":"Joy","ParentID":0},
{"ID":9,"Name":"Sumana","ParentID":8},
{"ID":10,"Name":"Alex","ParentID":0}]
in my case relation establish with ID and ParentID. the relation can be nested upto nth level. so tell me how to use ng-repeat to show parent and child data.
this way i tried
<div ng-app="myApp">
<ul class="nav nav-pills" data-ng-controller= "MasterDetails" >
<li
data-ng-repeat="parent in details | filter: { ParentID: 0 }" >
{{ parent.Name }}
<ul>
<li data-ng-repeat="child in details | filter: { ParentID: parent.ID }">
{{ child.Name }}
</li>
</ul>
</li>
</ul>
</div>
angular.module("myApp", []).
controller("MasterDetails", ['$scope', function($scope) {
$scope.details = [{"ID":1,"Name":"Suzy","ParentID":0},
{"ID":2,"Name":"Somi","ParentID":1},
{"ID":3,"Name":"Romi","ParentID":2},
{"ID":4,"Name":"Jumi","ParentID":3},
{"ID":5,"Name":"Gargi","ParentID":0},
{"ID":6,"Name":"Sujoy","ParentID":5},
{"ID":7,"Name":"Kamal","ParentID":6},
{"ID":8,"Name":"Joy","ParentID":0},
{"ID":9,"Name":"Sumana","ParentID":8},
{"ID":10,"Name":"Alex","ParentID":0}];
}]);
here is jsfiddle https://jsfiddle.net/tridip/s0svpaev/2/
the above code is working but not getting right output. hierarchy should be look like this way
Suzy
Somi
Romi
Jumi
Gargi
Sujoy
Kamal
Joy
Sumana
Alex
where i made the mistake in code for which i am not getting right output. thanks
Based on your link, I created this plnkr with some modifications to fit your needs.
I just added the getSubPeople function in the controller to get a sub array that represent the elder parents and pass them immediately to the directive for sub rendering:
Our partial:
<ul>
<li ng-repeat="p in peoples">
{{p}}
<div ng-switch on="p.ParentID > 0">
<div ng-switch-when="true">
<div ng-init="peoples = getSubPeople(p.ParentID);" ng-include="'partialPeoples.html'"></div>
</div>
</div>
</li>
</ul>
Our Controller :
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.peoples = [{"ID":1,"Name":"Suzy","ParentID":0},
{"ID":2,"Name":"Somi","ParentID":1},
{"ID":3,"Name":"Romi","ParentID":2},
{"ID":4,"Name":"Jumi","ParentID":3},
{"ID":5,"Name":"Gargi","ParentID":0},
{"ID":6,"Name":"Sujoy","ParentID":5},
{"ID":7,"Name":"Kamal","ParentID":6},
{"ID":8,"Name":"Joy","ParentID":0},
{"ID":9,"Name":"Sumana","ParentID":8},
{"ID":10,"Name":"Alex","ParentID":0}];
$scope.getSubPeople = function(parentId) {
var arr = [];
for(var i=parentId; i>0 ; i--){
arr.push($scope.peoples[i-1]);
}
return arr;
}
});
Presume include jQuery and not care dom opt perfomance too much, This anwser can match your requirement.
angular.module('app', [])
.controller('appCtrl', function($scope) {
$scope.data = [{
"ID": 1,
"Name": "Suzy",
"ParentID": 0
}, {
"ID": 2,
"Name": "Somi",
"ParentID": 1
}, {
"ID": 3,
"Name": "Romi",
"ParentID": 2
}, {
"ID": 4,
"Name": "Jumi",
"ParentID": 3
}, {
"ID": 5,
"Name": "Gargi",
"ParentID": 0
}, {
"ID": 6,
"Name": "Sujoy",
"ParentID": 5
}, {
"ID": 7,
"Name": "Kamal",
"ParentID": 6
}, {
"ID": 8,
"Name": "Joy",
"ParentID": 0
}, {
"ID": 9,
"Name": "Sumana",
"ParentID": 8
}, {
"ID": 10,
"Name": "Alex",
"ParentID": 0
}];
})
.directive('tree',function($filter){
return {
restrict:'EA',
scope:{
data:'='
},
link:function(scope,element,attrs){
scope.data = $filter('orderBy')(scope.data,'ParentID');
var html = $('<ul id="tree-outer-0"></ul>');
element.append(html);
angular.forEach(scope.data,function(val,index){
var tree = $('<li id="tree-inner-'+val.ID+'">'+val.Name+'</li>');
var parent = $('ul#tree-outer-'+val.ParentID);
if(parent.length){
parent.append(tree);
}else{
var parents = $('li#tree-inner-'+val.ParentID);
var parent = $('<ul id="tree-outer-'+val.ParentID+'"></ul>');
parent.appendTo(parents).append(tree);
}
});
}
}
});
<script src="//cdn.bootcss.com/angular.js/1.5.5/angular.min.js"></script>
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
<div ng-app="app" ng-controller="appCtrl">
<tree data="data"></tree>
</div>

Resources