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

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>

Related

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

angular.forEach() not working

Hi friend I'm beginner in angular and getting stuck by using angular.forEach() function. I just want to call data from a nested array in data.json file. Please check my code below... ****I want to call data from --users-- key****
HTML
<div class="user-container" ng-controller="users">
<ul class="list">
<li ng-repeat="(key, value) in items">
{{key}} <p> {{value}}
</li>
</ul>
</div>
Problems with current code
When run my code in browser Its giving me only 2 <li> in ng-repeat then in {{Key}} I'm getting 0 in first <li> and 1 in second <li>
and in {{value}} I'm getting whole user list in first <li> and in second <li> their is no data
data.json
{
"data": {
"new": true,
"show_page": false,
"status": "signedin",
"users": [{
"Michele": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
"Gerry": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
}]
},
"success": true
}
Controller.js
var myApp = angular.module('app', []);
myApp.service('userData', ['$http', function($http){
return{
userslist : function(){
return $http({'url' : 'data.json', 'method' : 'GET'}).then(function(response){
return response.data;
}, function(data){
console.log(data)
})
}
}
}]);
myApp.controller('users', ['$scope', '$http', 'userData', function($scope, $http, userData){
userData.userslist().then(function(data){
//var provideDataKey = Object.keys(data.users)[0];
$scope.items = [];
angular.forEach(data, function(item){
//console.log(item.users);
$scope.items.push(item.users)
})
console.log($scope.items)
})
}]);
response is the HTTP response, with its body (data), headers, etc.
So response.data is the body, which looks like this:
{
"data": {
"new": true,
"show_page": false,
"status": "signedin",
"users": [{
"Michele": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
"Gerry": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
}]
},
"success": true
}
What you want is to access the users field of the data field of this body. So what you want is
userData.userslist().then(function(data){
$scope.items = data.data.users;
console.log($scope.items)
})
$scope. items is an array, not an object. You want to display the elements of this array. So the syntax is:
{{ user }}
Your JSON is awful, because each user is an object with a single field, and you have no way of knowing the name of that field. You'd better change it to
"users": [
{
"name": "Michele",
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
{
"name": "Gerry",
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
]
That way you could just do:
<li ng-repeat="user in items">
{{ user.name }}, active since {{ user.active_since }}.
use this
myApp.controller('users', ['$scope', '$http', 'userData', function($scope, $http, userData){
userData.userslist().then(function(data){
//var provideDataKey = Object.keys(data.users)[0];
$scope.items = [];
angular.forEach(data.users[0], function(item){
$scope.items.push(item);
})
console.log($scope.items)
})
}]);
you were iterating over data and not on users.

Reading nested json in Angularjs

I am newbie to AngularJS. I have JSON file which I have to fetch using angularjs!
JSON File
{
"records": [
{
"students": [
{
"id": 1,
"name": "Bill",
},
{
"id": 2,
"name": "Steve",
}
],
"exstudent": [
{
"id": 1,
"name": "Woz",
},
{
"id": 2,
"name": "Jonathan",
}
]
}
]
}
Controller part snippet -
$http.get('json/somedata.json').success(function (data){
$scope.name = data.records.student.name;
$scope.exname = data.records.exstudent.name;
});
}])
HTML
<div class="panel-body" ng-repeat = "browse in name">
{{browse.student.name}}
</div>
Which part I am doing wrong? I think the problem is with ng-repeat!
Need Help
You can't use data.records.students.name as students is an Array.
You can however store its data into your $scope and use it in the ng-repeat:
$http.get('json/config.json').success(function (data){
$scope.students = data.records.students;
$scope.exstudents = data.records.exstudent;
});
Then in your HTML use the ng-repeat like this:
<div class="panel-body" ng-repeat="student in students">
{{student.name}}
</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 Multiple filter with single ng-model / input

How to make a single Search to filter multiple objects value ??
For e.g: if i search '1' OR 'one' then the result should come........
I've tried it so far:
HTML:
<input type="text" ng-model="model_search">
<ul>
<li ng-repeat="obj_data in data | filter:{id:model_search, text:model_search}">{{obj_data.id}}-->{{obj_data.text}}</li>
</ul>
JS:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.data = [{
"id": 1,
"text": 'one'
}, {
"id": 2,
"text": 'two'
}, {
"id": 3,
"text": 'three'
}, {
"id": 4,
"text": 'four'
}, {
"id": 5,
"text": 'five'
}];
});
DEMO PLUNKR
You were close, just change the filter to look like this:
<li ng-repeat="obj_data in data | filter:model_search">{{obj_data.id}}-->{{obj_data.text}}</li>
Working plunkr below
http://plnkr.co/edit/0jeA0u8oaz16cYnsZjfw?p=preview

Resources