angular child inside child - javascript

I have a problem with the recursion in angularJs.
I want to repeat all names from JSON file:
Here is my JSON file structure:
var data = {
"id": "580",
"name": "test",
"status": "ACTIVE",
"parentId": null,
"children": [
{
"id": "581",
"name": "test 2",
"status": "ACTIVE",
"parentId": "580",
"children": [{
"id": "594",
"name": "test 3",
"status": "ACTIVE",
"parentId": "581",
"children": []
}]
}
]
}
All I want is just to know how to make ng-repeat children in children?

You should use an ng-template in order to use it recursive.
<script type="text/ng-template" id="exampleTree">
{{ x.name }}
<ul ng-if="x.children">
<li ng-repeat="x in x.children" ng-include="'exampleTree'">
</li>
</ul>
</script>
To use this template and run it:
<ul>
<li ng-repeat="x in data" ng-include="'exampleTree'"></li>
</ul>
JSFiddle here

You can use ng-repeat with a template so it goes as far as you have data. Here is an example:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.child = {
"id": "580",
"name": "test",
"status": "ACTIVE",
"parentId": null,
"children": [{
"id": "581",
"name": "test 2",
"status": "ACTIVE",
"parentId": "580",
"children": [{
"id": "594",
"name": "test 3",
"status": "ACTIVE",
"parentId": "581",
"children": []
}]
}]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="MainCtrl">
<!-- This is the template that can be repeated in itself-->
<script type="text/ng-template" id="childView">
{{child.name}}
<ul>
<li ng-repeat="child in child.children" ng-include="'childView'"></li>
</ul>
</script>
<!-- This is the initial use for the template-->
<div ng-include="'childView'"></div>
</body>
I had to put child 594 in an array so it would work.

Related

Loop through Javascript object with children in Angular template

I have the following js object:
{
"id": "1554038371930_ajhnms9ft",
"name": "CPS",
"nodes": [
{
"id": "1554038905938_le34li2cg",
"name": "Consumer Journey",
"nodes": [
{
"id": "1554039157958_kwab8rj5f",
"name": "Average Rating",
"nodes": []
},
{
"id": "1554039174126_p47ugwkbv",
"name": "Product Quality",
"nodes": [
{
"id": "1554039298091_ewdyefkql",
"name": "Performance",
"nodes": []
},
{
"id": "1554039306834_qf54k1dqe",
"name": "Reliability",
"nodes": []
},
{
"id": "1554039320002_vfkenjmct",
"name": "Comfort",
"nodes": []
}
]
},
{
"id": "1554039197951_ajvv8587d",
"name": "Supply & Delivery",
"nodes": []
},
{
"id": "1554735679177_g5tini7ga",
"name": "Behind Product",
"nodes": [
{
"id": "1554736595466_nt4owp9in",
"name": "Influencers",
"nodes": []
},
{
"id": "1554736608593_58yomqpya",
"name": "Brand Confidence",
"nodes": []
}
]
},
{
"id": "1554736413715_jhro1oh0r",
"name": "Economical Value",
"nodes": [
{
"id": "1554736664421_wng97pbz8",
"name": {
"en": "Price"
},
"nodes": []
},
{
"id": "1554736676408_d4kiy2wv8",
"name": "Promotion & Reward",
"nodes": []
}
]
}
]
}
]
}
I want to loop through it in my angular HTML template so I can have the following list:
CPS
Consumer Journey
Average Rating
Product Quality
Performance
Reliability
Comfort
Supply & Delivery
Behind Product
Influencers
Brand Confidence
Economical Value
Price
Promotion & Reward
PS: I have an unknown number of levels!
I tried to implement that but my solution works only if I have a known number of levels:
<div *ngFor="let item of data">
<p>{{ item.name }}</p>
<div *ngIf="item.nodes.length">
<div *ngFor="let subItem of item.nodes">
<p>{{ subItem.name }}</p>
<div *ngIf="subItem.nodes.length">
<div *ngFor="let child of subItem.nodes">
{{ child.name }}
</div>
</div>
</div>
</div>
</div>
you need a recursive component to loop through n levels:
#Component({
selector: 'recursive-list',
template: `
<div *ngFor="let item of data">
<p>{{ item.name }}</p>
<recursive-list *ngIf="item.nodes.length" [data]="item.nodes"></recursive-list>
</div>
`
})
export class RecursiveListComponent {
#Input() data;
}

JSON data into nice GUI tables

I am very new to front end development,I have JSON file which I want to display in a nice GUI or html.
so far I tried to use bootstrap , angular , datatables looks like i am getting lost so if you can help me out that will be great.
MyJOSN file sample
{
"transactions": [{
"txn": {
"request": [{
"Field": "000",
"length": "004",
"value": "0100"
}, {
"Field": "005",
"length": "016",
"value": "11110010 00111100 "
}
],
"response": [{
"Field": "000",
"length": "004",
"value": "0110"
}, {
"Field": "001",
"length": "008",
"value": "00110010"
}]
}
}]
}
The Way i want to display the data is as below
Txn--( when click expand)
--Request --( when click and expand )
Field Length Value ( from the request array and the values from array)
--Response ( when click and expand )
Field Length value ( the values from the resposne array)
Note : the "transactions" array can have multiple "txn"
please guide one simple direction how can i achieve the above,any code will be great.
here is a sample of what you expect, pure Angular, no additional JavaScript .
I've added some transactions to the transactions Array and many different txn which I suppose to be transactions numbers.
index.html
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="script.js"></script>
<style>
strong {cursor: pointer;}
</style>
</head>
<body>
<div ng-controller="ExampleController">
<ul>
<li ng-repeat="t in data.transactions">
<ul>
<li ng-repeat="(key, value) in t" ng-if="key!='__opened'">
<strong ng-click="t.__opened=!t.__opened">{{key}} --</strong>
<ul ng-if="t.__opened">
<li>
<strong ng-click="value.request.__opened=!value.request.__opened">--Request</strong>
<ul ng-if="value.request.__opened">
<li ng-repeat="re in value.request">
{{re.Field}} {{re.length}} {{re.value}}
</li>
</ul>
</li>
<li>
<strong ng-click="value.response.__opened=!value.response.__opened">--Response</strong>
<ul ng-if="value.response.__opened">
<li ng-repeat="re in value.response">
{{re.Field}} {{re.length}} {{re.value}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
script.js
angular.module('app', []);
angular.module('app')
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
"transactions": [{
"ABC-123": {
"request": [{
"Field": "000",
"length": "004",
"value": "0100"
},
{
"Field": "005",
"length": "016",
"value": "11110010 00111100 "
}
],
"response": [{
"Field": "000",
"length": "004",
"value": "0110"
},
{
"Field": "001",
"length": "008",
"value": "00110010"
}
]
},
"DEF-456": {
"request": [{
"Field": "111",
"length": "006",
"value": "0145"
},
{
"Field": "555",
"length": "036",
"value": "22210010 00111100 "
}
],
"response": [{
"Field": "333",
"length": "765",
"value": "5112"
},
{
"Field": "088",
"length": "009",
"value": "00220022"
}
]
}
}, {
"GHI-123": {
"request": [{
"Field": "000",
"length": "004",
"value": "0100"
},
{
"Field": "005",
"length": "016",
"value": "11110010 00111100 "
}
],
"response": [{
"Field": "000",
"length": "004",
"value": "0110"
},
{
"Field": "001",
"length": "008",
"value": "00110010"
}
]
},
"JKF-456": {
"request": [{
"Field": "111",
"length": "006",
"value": "0145"
},
{
"Field": "555",
"length": "036",
"value": "22210010 00111100 "
}
],
"response": [{
"Field": "333",
"length": "765",
"value": "5112"
},
{
"Field": "088",
"length": "009",
"value": "00220022"
}
]
}
}]
}
}]);
And a working plunker to play with : https://plnkr.co/edit/mokM1ILRY8HbF7BAVa5R?p=preview
Hope it helps !

Applying filter on parent if it has been applied on children AngularJS

I have a list with items and have applied filter on those items by value from text box. I want to get new filtered list with parent and its children if parent has at least one filtered item.If doesn't, that parent should not be displayed.
For an example: If I enter "3D" in the text box I don't want to get "Day parts" and "Week parts" listed below as they don't have children anymore after filtering.
<div ng-controller="Ctrl">
<input type="text" data-ng-model="inputValue.name"/>
<ul data-ng-repeat="condition in conditions">
<div data-ng-click="setHeadingStatus(condition)">
<div>
{{condition.name}}
</div>
<li ng-repeat="item in condition.items | filter:inputValue">
<div class="custom-typeahead-list-title">{{item.name}}</div>
<div class="custom-typeahead-list-desc">{{item.description}}</div>
</li>
</div>
</ul>
function Ctrl($scope , $filter){
$scope.countryCode = 1;
$scope.conditions = [
{
"id": 1,
"name": "Experiences",
"expanded": false,
"items": [
{
"id": 1,
"name": "3D"
},
{
"id": 2,
"name": "Imax"
},
{
"id": 3,
"name": "D-Box"
},
{
"id": 4,
"name": "THX"
}
]
},
{
"id": 2,
"name": "Day parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Early Bird"
},
{
"id": 2,
"name": "Matinee"
},
{
"id": 3,
"name": "Last Night"
}
]
},
{
"id": 3,
"name": "Week parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Monday"
},
{
"id": 2,
"name": "Wednesday"
},
{
"id": 3,
"name": "Weekend"
}
]
}
]
}
Here is the example of it
http://jsfiddle.net/KJ3Nx/48/
You can put an ng-show on the div that displays each block, and set the expression to the filtered length;
<div data-ng-show="(condition.items | filter:inputValue).length > 0" data-ng-click="setHeadingStatus(condition)">
Updated fiddle

Converting Multidimensional JSON key-value pairs into an Angular Menu (no Angular knowledge required)

I asked this question here:
Working With Dynamic Multidimensional key-value pairs in JSON
But it's become a bit more involved and I can't get where I'm going from that answer. If I have a data object that looks like this:
{
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
How can I convert that into an Angular menu? The menu would need to list all of the services, and then if the service has an associated item in "fields" that item should be listed underneath it. So for instance "svc1" and its description should be listed on a line (got that working) but then "Product1" and "Product2" with their descriptions should appear on the next two lines because you can see that "svc1" is listed in the "services" field for "Products." Similarly, "svc4" should appear on a line, and then "Wines" and its description on the next line because "svc4" appears in the "services" field of "Wines."
I think the best way is to unpack and re-pack this JSON object in sequential order in the Angular controller and then push this data out to the Angular view but there might be a solution using only the logic available from the view. I've tried a bunch of nested fors and ifs along these lines (very much not working):
var i, j;
var listArray = [];
for (i = 0; i < $scope.svcs.length; i++) {
var littleArray = [$scope.svcs[i].status, $scope.svcs[i].name, $scope.svcs.desc];
listArray.push[littleArray1];
for (j=0; j < $scope.jFA.length; j++) {
if ($scope.jFA[j] == $scope.svcs[i].name) {
if ($scope.jFA[j] == $scope.svcs[i].fields)
littleArray = [$scope.jFA[j].fields] //...etc
}
}
...but that logic just keeps getting more and more dense and isn't working no matter now I try to use it. I liked the simplicity in the answer to the other question but have not had success in replicating it.
So if someone can help me figure out how to get the data into the right sequence using JS I can handle the Angular part. Or if you're an Angular whiz and have an answer along those lines, even better.
So it was a little hard understanding your question, but I gave it my best shot. Does this fiddle show what you are trying to achieve? http://jsfiddle.net/arknr6qz/1/
JS:
var app = angular.module('TestApp',[]);
app.controller('TestController', function($scope)
{
$scope.checkService = function(service, fieldServices)
{
if (fieldServices.indexOf(service) != -1) return true;
return false;
};
$scope.data = {
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
});
HTML:
<div ng-app="TestApp">
<div ng-controller="TestController">
<div ng-repeat="service in data.custom.services">
{{ service.name }}
<div class="indent" ng-repeat="fields in data.custom.fields">
<span ng-if="checkService(service.name, fields.services)">
{{fields.services.values}}
<span ng-repeat="value in fields.values">
{{value.name}} - {{value.desc}}<br>
</span>
</span>
</div>
</div>
</div>
</div>
and finally css:
.indent {
margin-left:10px;
}

JSON and AngularJS (trying to figure out the ng-repeat part)

So I have this on my JSON file:
[{
"title": "Secondary Containment",
"products": {
"product": [
{
"id": "1001",
"name": "one"
},
{
"id": "1002",
"name": "two"
},
{
"id": "1003",
"name": "three"
}
]
}
}, {
"title": "Another Title",
"products": {
"product": [
{
"id": "1011",
"name": "alpha"
},
{
"id": "1012",
"name": "beta"
},
{
"id": "1013",
"name": "gamma"
}
]
}
}]
What would I include in my ng-repeat to repeat the id's of the products in a list?
I have ng-repeat="category in categories" in my outer container which is repeating the different titles {{category.title}} but it's not repeating the inner array and nothing shows up when i try outputting {{category.products.product.id}}
Any ideas?
You need nested ng-repeat
<div ng-repeat="category in categories">
<div ng-repeat="product in category.products.product">
{{product.id}}
</div>
</div>
Your html should be
<div data-ng-repeat="category in categories">
<div data-ng-repeat="product in category.products.product">
{{product.id}}
</div>
</div>
You can do as nikhil said. But you need nested ng-repeat. But I personally suggest to use data-ng-repeat instead ng-repeat. The only main reason to use data-ng-* is The data-ng-* allows the HTML to be validated through validators that do not understand Angular

Categories

Resources