Complicated sorting with tabs in ng-repeat? - angularjs

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.

Related

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.

Json Object in ng-repeat

response object like
$scope.list= [
Object {
cid=74,
date="2016-08-25T00:00:00.000+0530",
optkey="key",
optvalue="{
value:{
'name':test,
'gender':male
}
}"
},
Object {
cid=75,
date="2016-08-25T00:00:00.000+0530",
optkey="key",
optvalue="{
value:{
'name':test2,
'gender':female
}
}"
}},
Object {
cid=77,
date="2016-08-26T00:00:00.000+0530",
optkey="key",
optvalue="{
value:{
'name':test1,
'gender':female
}
}"
}]
and in html page used ng-repeat
<div ng-repeat="item in list">
{{item.date}} -- works fine
</div>
here how to display json value in object optvalue, done some code like.
<div ng-repeat="item in list">
{{item.optvalue.value}} -- but it is undefined
</div>
but it is not working can any one give hint for this
Just because your optvalue is a String but not a object. It should be :
optvalue = {
value:{
'name':test1,
'gender':female
}
}
In JSON, an object should NOT be in the parenthese.
Try this working example, please check the object created.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.list=
[
{
cid:74, date:"2016-08-25T00:00:00.000+0530", optkey:"key", optvalue:{value:{'name':'test','gender':'male'}}
},
{
cid:75, date:"2016-08-25T00:00:00.000+0530", optkey:"key", optvalue:{value:{'name':'test','gender':'male'}}
},
{
cid:76, date:"2016-08-25T00:00:00.000+0530", optkey:"key", optvalue:{value:{'name':'test','gender':'male'}}
}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="item in list">
{{item.optvalue.value.name}}
</div>
</div>
The response JSON is not valid :
Strings should be wrapped in double quotes.
Expecting colon, not = in key value pairs.
Invalid characters found.
Invalid number.
Issue Capture :
Valid JSON :
[
{
"cid": 74,
"date": "2016-08-25T00:00:00.000+0530",
"optkey": "key",
"optvalue": {
"value": {
"name": "test",
"gender": "male"
}
}
},
{
"cid": 75,
"date": "2016-08-25T00:00:00.000+0530",
"optkey": "key",
"optvalue": {
"value": {
"name": "test2",
"gender": "female"
}
}
},
{
"cid": 77,
"date": "2016-08-26T00:00:00.000+0530",
"optkey": "key",
"optvalue": {
"value": {
"name": "test1",
"gender": "female"
}
}
}
]
In your case {{item.optvalue.value}} is giving undefined because optvalue is a string not an object.So, it should be an object.
"optvalue": {
"value": {
"name": "test1",
"gender": "female"
}
}
thanks for your answers,i have resolved it using--
angular.toJson and angular.fromJson
while send to server used
angular.toJson(stringOfJson)
and when got the response object the using
angular.fromJson(value)
and set to object field,it is working fine.
you need to change your code to this
<div ng-repeat="item in list">
{{item.optvalue.value.name}}
</div>

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>

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>

Angular JS orderBy not working using dropdown

i am trying to do orderBy using dropdown value, but its not working :(
CODE:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.datas = [{
"id": "1",
"name": "name area 1"
}, {
"id": "2",
"name": "name area 2"
}, {
"id": "3",
"name": "name area 3"
}, {
"id": "4",
"name": "name area 4"
}];
$scope.dropdown = [{
"title": "Newest first",
"value": "true"
}, {
"title": "Oldest first",
"value": "reverse"
}];
});
HTML:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul ng-repeat="rows in datas | orderBy: 'id':orderByData">
<li>{{rows.id}} : {{rows.name}}</li>
</ul>
<select ng-model="orderByData" ng-options="x.value as x.title for x in dropdown"></select>
</div>
</div>
DEOM JS BIN
Why you use reverse?
Please use false instead reverse and it should work fine.
$scope.dropdown = [{
"title": "Newest first",
"value": "true"
}, {
"title": "Oldest first",
"value": "false"
}];
You don't need reverse parameter here. Instead you can do something like this:
<ul ng-repeat="rows in datas | orderBy: getSort()">
<li>{{rows.id}} : {{rows.name}}</li>
</ul>
Where getSort is defined as:
$scope.getSort = function() {
return $scope.orderByData ? 'id' : '-id';
};
Basically you want sort part to look like orderBy: 'id' or orderBy: '-id'.
Demo: http://jsbin.com/pepureta/1/edit?html,js,output

Resources