json to nested ul li jquery / javascript - javascript

I am creating dynamic json using javascript from a drag and drop builder, Now I am unable to convert the json to Nested Ul li. The json is below.
[
{
"id": "11",
"name": "BALANCE"
},
{
"id": "p1",
"name": "Conditions",
"nodes": [
{
"id": "p1-13",
"name": "SPINAL CORD INJURY",
"nodes": [
{
"id": "p1-13-12",
"name": "STROKE",
"nodes": [
{
"id": "p1-13-12-17",
"name": "REACHING"
}
]
}
]
}
]
},
{
"id": "p1-16",
"name": "STRETCHES"
},
{
"id": "p1-11",
"name": "BALANCE"
}
]

You can create a function and call recursively if there is nodes in item.
var json = [{"id":"11","name":"BALANCE"},{"id":"p1","name":"Conditions","nodes":[{"id":"p1-13","name":"SPINAL CORD INJURY","nodes":[{"id":"p1-13-12","name":"STROKE","nodes":[{"id":"p1-13-12-17","name":"REACHING"}]}]}]},{"id":"p1-16","name":"STRETCHES"},{"id":"p1-11","name":"BALANCE"}];
function createUl(data, $elm) {
data.forEach(function(item) {
var $li = $('<li><span>' + item.name + '</span></li>');
$elm.append($li);
if (item.nodes) {
var $ul = $('<ul></ul>');
$li.append($ul);
createUl(item.nodes, $ul);
}
});
};
createUl(json, $('ul'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>

Related

How to store object at a certain level in the JSON data by dynamically iterating through it? [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 5 years ago.
I have the following json:
{
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}
]
}]
}
I want to dynamically access the objects whose value of "children" is null and store the "name" of these objects in a variable. For example in this case either forest area or plantation. How can I do this using javascript or jquery?
You don't need jQuery for this, a simple for will do and, most likely, it's faster than anything else:
var childless = [],
checkForChildren = function(items){
for (var i = 0; i < items.length; i++) {
if (items[i].children)
checkForChildren(items[i].children);
else
childless.push(items[i]);
}
};
// test it:
var menu = [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},{
"name": "plantation",
"id": "1.1.2",
"children": null
}]
}]
}];
checkForChildren(menu);
console.log(childless);
Recursion comes to mind.
var childless = [];
var recursive_function = function(obj){
if(obj.children == null){
childless.push(obj);
} else {
$.each(obj.children, function(child){
recursive_function(child);
}
}
};
$.each(json_obj.menu, function(root_level){
recursive_function(root_level);
});
console.log(childless);
console.log($.map(childless, function(x){return x.name;}));
var test = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}]
}]
};
var hasNullChildren = [];
function checkChildren ( children ) {
//loop over all children
children.forEach(function(child){
//if no children, add name to list
if (!child.children) hasNullChildren.push(child.name);
//check nested children
else checkChildren(child.children);
});
}
//start the recursion loop
checkChildren(test.menu);
console.log(hasNullChildren);
Recursively iterating through the array and searching for the children = null, gives the array with all the names of objects.
const obj = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
},{
"name": "landuse",
"id": "1.1",
"children": null
}
]
}]
}
function getNameWithNullChildren(arr) {
let array = [];
arr.forEach(item => {
if(item.children === null) {
array.push(item.name);
} else {
array = getNameWithNullChildren(item.children);
}
});
return array;
}
console.log(getNameWithNullChildren(obj.menu));

Facing Issue on Getting First Level Of Data in JSON File

I have an external JSON file called movie.json and is like following format
{
"action":
[
{ "id": "1001", "name": "Matrix" },
{ "id": "1002", "name": "IP Man" },
{ "id": "1003", "name": "Revenge" }
],
"comedy":
[
{ "id": "2001", "type": "Iceman" },
{ "id": "2002", "type": "Pat & Mat" },
{ "id": "2003", "type": "Sugar" }
],
"animation":
[
{ "id": "3001", "type": "Frozen" },
{ "id": "3002", "type": "Tangled" },
{ "id": "3003", "type": "Croods" }
]
}
in my HTML I have a bootstrap Tab component like
<ul class="nav nav-tabs" role="tablist">
</ul>
can you please let me know how I can get access to upper level of JSON file (action, comedy, animation and populate them as li in .nav-tabs dynamically
I already tried
$.getJSON('data.json', function (data) {
for (i = 0; i < data.length; i++) {
$('.nav-tabs').append('<li role="presentation" >'+data[0]+'</li>')
}
});
but it is not doing the job. Can you please let me know how to fix this? Thanks
You can use $.each() to iterate the data. key will be the "top level" and val the content
$.getJSON('data.json', function (data) {
$.each( data, function( key, val ) {
$('.nav-tabs').append('<li role="presentation" >'+key+'</li>')
});
});
You treating object like an array, its a simple object Use for-in loop
The for...in statement iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.
var data = {
"action": [{
"id": "1001",
"name": "Matrix"
},
{
"id": "1002",
"name": "IP Man"
},
{
"id": "1003",
"name": "Revenge"
}
],
"comedy": [{
"id": "2001",
"name": "Iceman"
},
{
"id": "2002",
"name": "Pat & Mat"
},
{
"id": "2003",
"name": "Sugar"
}
],
"animation": [{
"id": "3001",
"name": "Frozen"
},
{
"id": "3002",
"name": "Tangled"
},
{
"id": "3003",
"name": "Croods"
}
]
};
for (var i in data) {
$('.nav-tabs').append('<li><strong>' + i + '<strong></li>')
for (var j = 0; j < data[i].length; j++) {
var obj = data[i][j];
$('.nav-tabs').append('<li>' + obj.name + '</li>')
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="nav nav-tabs" role="tablist">
</ul>
// jsonObj is your json object
jQuery.each(jsonObj, function(key,val) {
//key will have action,comedy and animation
console.log(key,val)
});

Populate parent Object by comparing parent Array

Am having an arrray of Objects which again contains the id's of the parent Object:
eg:-
$scope.result=[
{
"id": 1,
"name": ABC,
"type": PQR,
"parentId": 2
},
{
"id": 2,
"name": ABC,
"type": PQR,
"parentId": 1
}]
I would like to convert this JSON in to the following wherin I will be having the parentObject in place of parentId's
$scope.result=[
{
"id": 1,
"name": ABC,
"type": a,
"parentId": {
"id": 2,
"name": PQR,
"type": b,
"parentId": 1
}
},
{
"id": 2,
"name": PQR,
"type": b,
"parentId": {
"id": 1,
"name": ABC,
"type": a
}
}
]
Can anybody help me with this conversion..
Assuming parentId will reference to one element
angular.forEach($scope.result, function(result) {
var obj = $scope.result.filter(function(ele) {
return result.parentId === ele.id;
})[0];
result.parentId = obj;
});
Since your tags doesn't contain angularjs, I'm using Array.prototype.forEach here
$scope.result.forEach(function(result) {
var obj = $scope.result.filter(function(ele) {
return result.parentId === ele.id;
})[0];
result.parentId = obj;
});
Will do 2 loops first one to fill a hash with keys of the ids, second will loop to replace parent id with actual object:
$scope = {}
$scope.result=[
{
"id": 1,
"name": "ABC",
"type": "PQR",
"parentId": 2
},
{
"id": 2,
"name": "ABC",
"type": "PQR",
"parentId": 1
}]
parents = {}
for(i=0;i<$scope.result.length;i++){
parents[$scope.result[i]["id"]] = jQuery.extend({}, $scope.result[i]); // Clone object
}
for(i=0;i<$scope.result.length;i++){
$scope.result[i]["parentId"] = parents[$scope.result[i]["parentId"]]
}
$scope.result

Compare two JSON Arrays and rearrange new JSON Array format

Here is the my first JSON Array format...
[
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
]
and here is another JSON Array Format
[
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
]
The above mentioned Two JSON Arrays, i need to compare each one with Id and need to format a new JSON Array with caption and value using javascript.
[
[
{
"caption" : "caption1",
"value":"value11"
},
{
"caption" : "caption2",
"value":"value12"
},
{
"caption" : "caption3",
"value":"value13"
}
],
[
{
"caption" : "caption1",
"value":"value21"
},
{
"caption" : "caption2",
"value":"value22"
},
{
"caption" : "caption3",
"value":"value23"
}
]
]
Please help me out.
You can do it in many ways. Below I show two variants:
Option 1: Pure JavaScript
In this example the program preindex first array for faster access to it data, and then loops over second array with map() function to create new array of arrays:
// Create index version of first array
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
// Loop over array of arrays
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
}
});
Option 2: Using special SQL library (Alasql)
Here, you can JOIN to arrays automatically with special SQL statement:
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] \
FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
You can try these variants in working snippet below or play with it in jsFiddle.
(Disclaimer: I am the author of Alasql)
var arr1 = [
{
"id": "1234",
"caption": "caption1"
},
{
"id": "2345",
"caption": "caption2"
},
{
"id": "3456",
"caption": "caption3"
}
];
var arr2 = [
[
{
"id": "1234",
"value": "value11"
},
{
"id": "2345",
"value": "value12"
},
{
"id": "3456",
"value": "value13"
}
],
[
{
"id": "1234",
"value": "value21"
},
{
"id": "2345",
"value": "value22"
},
{
"id": "3456",
"value": "value23"
}
]
];
// JavaScript version
var aix = {};
for(var i=0;i<arr1.length;i++) {
aix[arr1[i].id] = arr1[i].caption;
}
var res1 = arr2.map(function(arr22){
return arr22.map(function(a){
return {caption:aix[a.id], value:a.value};
});
});
document.getElementById("res1").textContent = JSON.stringify(res1);
// Alasql version
var res2 = arr2.map(function(a){
return alasql('SELECT arr1.caption, a.[value] FROM ? a JOIN ? arr1 USING id',[a,arr1]);
});
document.getElementById("res2").textContent = JSON.stringify(res2);
<script src="http://alasql.org/console/alasql.min.js"></script>
<p>Varian 1: JavaScript</p>
<div id="res1"></div>
<p>Variant 2: Alasql</p>
<div id="res2"></div>

getJSON displays [object Object] rather than actual values

I have a JSON and I need to get this JSON and put in the html as a ul li list. It gets the value as object and displays [object Object] in html. If I modify the json then it works. so there is probably something wrong in my script where I am not able to loop throught he json file properly. Can some one help please:
MY JSON IS:
[
{
"us":"USA"
},
{
"fr":"FRANCE"
},
{
"es":"Spain"
},
{
"sa":"South Africa"
}
]
AND JS IS
<script>
$.getJSON('jsonfile', function(data) {
var items = [];
$.each(data ,function(key,val) {
items.push('<li id="'+ key +'">' + val +'</li>');
});
$('<ul />' , {
'class':'new-div',
html:items.join('')
}).appendTo('body');
});
</script>
UPDATED JSON:
[
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
}
}
]
The data you're looping over is the array, which has objects. So your key will be 0, 1, etc., and the val will be the object at that position in the array.
Your JSON structure actually makes it a bit of a pain to output, because each of your objects only has one property, but the property name varies from object to object. You can do it, by looping over the object properties even though there's only one of them:
var items = [];
$.each(data ,function(outerKey, outerVal) { // <== Loops through the array
$.each(outerVal, function(key, val) { // <== "Loops" through each object's properties
items.push('<li id="'+ key +'">' + val +'</li>');
});
});
...but I'd change the JSON structure instead. For instance, assuming the keys are unique, your original code would work with this structure:
{
"us":"USA",
"fr":"FRANCE",
"es":"Spain",
"sa":"South Africa"
}

Categories