Dynamic nested ul\li list from json data using Javascript - javascript

I need to create a dynamic nested ul\li list from json array.
NOTE! I can do that transformation my self using jQuery, but in this case i need to work with a string, since it's node.js and i don't have access to DOM.
Also the array can have different depth.
This is json data i work with and how it should look after transformation.
var data = [{"id": "1", "name": "name_1", "parent_id": "0", "depth": "0"},
{"id": "2", "name": "name_2", "parent_id": "0", "depth": "0"},
{"id": "3", "name": "name_3", "parent_id": "1", "depth": "1"},
{"id": "4", "name": "name_4", "parent_id": "3", "depth": "2"}];
<ul>
<li>name_1</li> //depth 0
<li>name_2 //depth 0
<ul>
<li>name_3 //depth 1
<ul>
<li>name_3</li> //depth 2
</ul>
</li>
</ul>
</li>
</ul>
I hope this is clear. If not please ask any questions in the comment.
Thank you in advanced.

Try this:
var data = [{"id": "1", "name": "name_1", "parent_id": "0", "depth": "0"},
{"id": "2", "name": "name_2", "parent_id": "0", "depth": "0"},
{"id": "3", "name": "name_3", "parent_id": "1", "depth": "1"},
{"id": "4", "name": "name_4", "parent_id": "3", "depth": "2"}];
var initLevel = 0;
var endMenu =getMenu("0");
function getMenu( parentID ){
return data.filter(function(node){ return ( node.parent_id === parentID ) ; }).map(function(node){
var exists = data.some(function(childNode){ return childNode.parent_id === node.id; });
var subMenu = (exists) ? '<ul>'+ getMenu(node.id).join('') + '</ul>' : "";
return '<li>'+node.name + subMenu + '</li>' ;
});
}
console.log( '<ul>'+endMenu.join('')+ '</ul>');
However, I think the correct output based on your data will be something like:
<ul>
<li>name_1
<ul>
<li>name_3
<ul>
<li>name_4</li>
</ul>
</li>
</ul>
</li>
<li>name_2</li>
</ul>
Here is the JSFiddle sample
Updated Version:
http://jsfiddle.net/LqES7/47/

I'd first convert the flat data to hierarchical json, using something like this, so it's more iterable. Then recursively iterate the JSON and add every element to a string.

If i understand the question correctly you are trying to genereat a list in html from a array of objects.
So if your not using JQuery, probably one of these will help you out:
Create ul and li elements in javascript.
Create a UL and fill it based on a passed array
And if your using JQuery, probably this will help you out:
How to generate UL Li list from string array using jquery?

Related

Dynamically load JSON information in HTML tags

I'm trying to show all categories from my JSON file in a menu. Can anyone help me with the JavaScript code for this? I have tried a couple of things but all in vain.
HTML: (static)
<ul class="cd-faq-categories" id="onderwerp">
<li><a class="selected" href="#algemeen">Test</a></li>
<li>Test2</li>
<li>Test3</li>
<li>Test4</li>
<li>Test5</li>
</ul> <!-- cd-faq-categories -->
JSON structure:
{
"id": 3,
"category": "Eten",
"question": "Vis",
"answer": "Ham",
"date": "29-11-18"
}
Can anyone help me with this? I'm trying to have the name and href the same in the HTML tag, so for example:
<li>$c{category}</li>
Here is working solution:
var data =[
{
"id": 3,
"category": "Eten",
"question": "Vis",
"answer": "Ham",
"date": "29-11-18"
},
{
"id": 3,
"category": "Eten 2",
"question": "Vis",
"answer": "Ham",
"date": "29-11-18"
},
{
"id": 3,
"category": "Eten 3",
"question": "Vis",
"answer": "Ham",
"date": "29-11-18"
}
]
const liTemplate = (category) => `${category}`
data.forEach(item => {
var child = document.createElement('li');
child.innerHTML = liTemplate(item.category);
document.querySelectorAll('.cd-faq-categories')[0].appendChild(child);
})
The solution is taking Json object. Iterate through all items and append to DOM li elements with simple vanilla JS appendChild method.
JSON file is a just a text file, so in order javascript to understand it like an obj. you must parse it. You must use JSON.parse() function.
var data = JSON.parse('{
"id": 3,
"category": "Eten",
"question": "Vis",
"answer": "Ham",
"date": "29-11-18"
},');
<li>$c{data.category}</li>

AngularJs appending options to select box

I am new to AngularJs. I am having problem in appending options to select boxes created by javascript. Following is my code.
var inputElements = $('<div><label style="float:left;">' + i + '</label><select ng-model="object" class="form-control sel" style="width:300px; float:right; margin-right:75px;"> <option>select</option></select></div></br></br>');
var temp = $compile(inputElements)($scope);
$('#projOrder').append(temp);
$scope.object = object;
//for(var opt=0; opt<selOptLabels.length; opt++) {
$('.sel').append('<option ng-repeat="obj in object" value="'+
{{obj.value}}+'">'+{{obj.value}}+'</option>');
I am getting this error:- SyntaxError: invalid property id
Hi, I am posting json example. This is just a small part of json in my case.
"ProjectOrder": {
"Connect direct required": {
"value": "N",
"id": "STR_15523_62"
},
"Cores": {
"value": ".5",
"id": "NUM_15523_50"
},
"Permanent data in GB": {
"value": "100",
"id": "NUM_15523_56"
},
"Description": {
"value": "AZBNL azbngb",
"id": "STR_15523_2"
},
"Order Id": {
"value": "15523",
"id": "INT_15523_96"
},
"Project cost center": {
"value": "N",
"id": "STR_15523_66"
},
"Project debitor": {
"value": "N",
"id": "STR_15523_64"
},
"Project OE": {
"value": "N",
"id": "STR_15523_57"
},
"Project SITE": {
"value": "N",
"id": "STR_15523_59"
},
"Project Status": {
"value": "RFC",
"id": "STR_15523_54",
"dropdown": [
{
"value": "IW",
"label": "In Work"
},
{
"value": "RFC",
"label": "Ready for Creation"
},
{
"value": "CR",
"label": "Created"
},
{
"value": "FC",
"label": "Failed"
}
]
},
"Project Type (paas, miner)": {
"value": "paas",
"id": "STR_15523_37",
"dropdown": [
{
"value": "paas",
"label": "PaaS Project"
},
{
"value": "miner",
"label": "Miner Project"
}
]
},
"WORK data in GB": {
"value": "100",
"id": "NUM_15523_55"
}
}
Now I have to create input fields and dropdown menus(if there is a dropdown menu) with json data
You really should not be hand-constructing HTML like that. It's best if you use a template and let the template engine handle the heavy lifting.
I also noticed that you're using object as the ng-model. Instead you should have a separate variable which will hold the selected value.
Here's a better way of doing this--in an .html file:
<div ng-repeat="object in listOfObjects"
<label style="float: left">{{ $index }}</label>
<select ng-model="selectedValues[$index]" class="form-control sel"
style="width:300px; float:right; margin-right:75px;"
ng-options="obj.value for obj in object"></select>
</div>
Then in whatever controller you have set up in JavaScript:
// this will be the list of selected values
$scope.selectedValues = new Array(list.length);
// this would be the array that each `object` is part of
$scope.listOfObjects = list;
This isn't the most elegant solution, but basically what I've done is construct an array that is the same length as the list of objects. Angular templates have a special variable $index when you're in an ng-repeat which tracks the current index of the array you're looping through.
So when a user changes the selected value of the 3rd select box (index 2), $scope.selectedValues[2] would be set to the selected option.
EDIT: on transforming the JSON to an array:
var list = Object.keys(json).map(function(jsonKey) {
return {
name: jsonKey,
label: json[jsonKey].label,
value: json[jsonKey].value
};
});`
So.. there are a number of reasons why that won't work. The provided code wouldn't even work because of the template brackets that you are trying to append to your html string...
$('.sel').append('<option ng-repeat="obj in object" value="' +{{obj.value}}+'">'+{{obj.value}}+'</option>');
Is there a reason that you are trying build your markup in js?
It's also advised not to use jquery inside angular controllers. If you have jquery loaded the jQuery object is available through angular.element, otherwise angular uses jQuery light.
Rather than enumerate on the other issues here, I put together this basic example of how a select works in Angular
https://codepen.io/parallaxisjones/pen/BRKebV
Also, you should consult the angular documentation before posting questions to stack overflow. The docs provide a pretty clear example of how to use ng-repeat in a select. https://docs.angularjs.org/api/ng/directive/select
EDIT: I updated my codepen with an example of fetching JSON data with an HTTP GET request
EDIT: updated codepen with provided data example, iterating over object with (key, value) in json syntax in ng-repeat

angularjs - ng repeat with json

how can i use ng-repeat for below json
$scope.prlists = {
"1": [{
"id": "1",
"name": "One",
"qty": 2,
"amount": "1.00",
"cat": "1.00"
}],
"3": [{
"id": "3",
"name": "backit",
"qty": 3,
"amount": "2.00",
"cat": "2.00"
}]
}
<div ng-repeat="pro in prlists">
name : pro.name
</div>
can not able to get the name due to inner array. How to solve
ngRepeat can iterate over object properties. So, you can do something like
<div ng-repeat="(key, pro) in prlists">
name: {{pro[0].name}}
</div>
See the documentation at: https://docs.angularjs.org/api/ng/directive/ngRepeat
Note that this will not guarantee the order in Angular version >= 1.4, since it will depend on the browser's ordering. You might be able to sort it using the orderBy filter
<div ng-repeat="(key, pro) in prlists | orderBy:key">
name: {{pro[0].name}}
</div>
See: https://docs.angularjs.org/api/ng/filter/orderBy
If the inner arrays are not just a single element, you may have to nest a second ngRepeat inside the first div.
As I have already commented:
try pro[0].name
Reason:
In you code, for every iteration, $data(pro) will have
[{
"id": "1",
"name": "One",
"qty": 2,
"amount": "1.00",
"cat": "1.00"
}]
Now as you see, this is not an object, so you have to go to its first and only child. Also you are missing {{}}. name : pro.name this will print pro.name as text and not parse it.
Working demo.

Displaying JSON with ng repeat

I have a JSON data in the format
[
{
"_1": {
"id": 4,
"cost": 45.0,
"measure": 4,
"NoOfUnits": 677,
"hours": null
},
"_2": {
"id": 1,
"name": "Truck",
"description": "Test"
}
},
{
"_1": {
"id": 1,
"cost": 1120.0,
"measure": 1,
"NoOfUnits": 500,
"hours": null
},
"_2": {
"id": 7,
"name": "PC300",
"description": null
}
},
]
I'm not able to display the data that I have store in a $scope variable say
$scope.result
This is my ng repeat functionality
<div ng-repeat="data in result">{{data.name}}{{data.description}}</div>
your $scope.result is contains 2 objects, with in one object u have set of object properties like _1,_2 , and then these properties are again objects like
"_1": {
"id": 4,
"cost": 45.0,
"measure": 4,
"NoOfUnits": 677,
"hours": null
}
, then u have the properties u need to print.
<ul>
<li ng-repeat="x in result"> // repeats objects
<ul ng-repeat="obj in x"> // repeat object properties '_1',"_2" , these are again objects
{{obj.name}}{{obj.description}}
<ul>
</li>
</ul>
With your data structure... You cannot access name and description directly from first ng-repeat.
Even if you have nested ng-repeat you are not guaranteed with name and description. You need to flatten the object after first ng-repeat and then you can access all the properties. Assuming that _1, _2 object properties are related.
Two loops are required---
<div ng-repeat="data in result">
<div ng-repeat="obj in data">
{{obj.cost}}{{obj.name}}
</div>
</div>
Demo: http://jsfiddle.net/HB7LU/8254/

separate a JSON array [duplicate]

This question already has answers here:
Parse JSON in JavaScript? [duplicate]
(16 answers)
Closed 8 years ago.
I have this JSON array with a lot of person data every one with a type like "hr" or "accounting".
the JSON array looks like this:
{
"0": {
"id": "2",
"name": "blabla",
"type": "hr"
},
"1": {
"id": "3",
"name": "bub",
"type": "hr"
},
"2": {
"id": "4",
"name": "ula",
"type": "accounting"
},
"3": {
...
}
}
I want to display them in an ul like this:
<ul>
<li><p>hr</p>name: blabla<p></li>
<li><p>hr</p>name: bub<p></li>
<li><p>hr</p>......</li>
</ul>
<ul>
<li><p>accounting</p>name: ula<p></li>
<li><p>accounting</p>......</li>
</ul>
but i have no clue how to separate the JSON array or how to properly loop through it to display it like that.
Try this:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div class="container"></div>
<script>
var json={
"0": {
"id": "2",
"name": "blabla",
"type": "hr"
},
"1": {
"id": "3",
"name": "bub",
"type": "hr"
},
"2": {
"id": "4",
"name": "ula",
"type": "accounting"
}
};
var previous_type=json[0].type;
var _html="<ul>";
$.each(json, function(index,key) {
if (previous_type!=key.type) {
_html+="</ul><ul>";
}
previous_type=key.type;
_html+="<li><p>"+key.type+"</p><p>name: "+key.name+"</p></li>";
});
_html+="</ul>";
$('.container').html(_html);
</script>
</body>
</html>
It creates a new ul for every different type.
Output of container:
<div class="container">
<ul>
<li>
<p>hr</p>
<p>name: blabla</p>
</li>
<li>
<p>hr</p>
<p>name: bub</p>
</li>
</ul>
<ul>
<li>
<p>accounting</p>
<p>name: ula</p>
</li>
</ul>
</div>
this will basically do what you want for one department. You can use it for each department by putting an if in the each loop and checking it against value.type
var new_html = "<ul>";
$.each('name_of_json_array', function(key, value){
new_html+="<li><p>"+value.type+"</p><p>name: "+value.name+"</p></li>";
});
new_html+="</ul>";
$('#some_container_element').append(new_html);

Categories