Reputation: 35
Ive tried a lot of the answers to creating nested ul/li, but cant seem to get create one. Im very new to js.
the data is grabbed after the page loads, and comes in a format like this
data = {
"key1": ["value1", value2", "value3"],
"key2": ["value4", "value5", "value6"],
"key2": ["value7"]
}
As a bonus, I was hoping to click on a key and drop down (expand) to show the values. But ive failed to get the data to load in the structure below. There can be any number of keys, with values(lists) of any length. also, the keys can be named anything.
<ul>
<li>
key1
<ul>
<li>value1</li>
<li>value2</li>
<li>value3</li>
</ul>
</li>
<li>
key2
<ul>
<li>value4</li>
<li>value5</li>
<li>value6</li>
</ul>
</li>
<li>
key3
<ul>
<li>value7</li>
</ul>
</li>
</ul>
i updated adding the jquery code ive been attempting. I did not include it because ive tried many variants to get the data in the nested structure above and am probably doing it wrong.
jQuery(document).ready(function($) {
$.get('url', function(data){
var $ul = $('<ul></ul>');
function getList(item, $list) {
$.each(item, function (key, value) {
var $li = $('<li />');
$li.append($('<a href="#">' + key + '</a>'));
var $subul = $("<ul/>");
$.each(value, function(i) {
var subli = $('<li/>')
.text(value[i])
.appendTo(subli);
});
$subul.append(subli);
$li.append($subul)
});
}
getList(data, $ul);
$ul.appendTo("div_containing_ul");
});});
Upvotes: 1
Views: 3382
Reputation: 341
A short recursive version giving good results:
function buildList(data) {
var $ul = $('<ul></ul>');
for (const key in data) {
var $child = $('<li></li>');
$ul.append($child)
if (typeof data[key] === 'object') {
$child.text = $child.text(key);
$child.append(buildList(data[key]));
} else {
$child.text = $child.text(key + ' : ' + data[key]);
}
}
return $ul;
}
I feed my function with an array of objects containing a timestamp, a Partner object, and the Partner object containing a Company object; the result looks like this:
0
timestamp : 1587732029600
partner
id : 0
name : Name1
email : [email protected]
company
id : 0
name : SomeCompany1
1
timestamp : 1587732029600
partner
id : 1
name : Name2
email : [email protected]
company
id : 1
name : SomeCompany2
Upvotes: 1
Reputation: 2489
The problem is recursion. You don't know if that data will always be like that, if the nested levels will only be ever 2 levels deep.
I rewrote your example with recursion that takes in account an endless of levels of menus.
jQuery(document).ready(function ($) {
function caller(data) {
var $ul = $('<ul></ul>');
recursiveCaller(data, $ul);
return $ul;
}
function recursiveCaller(subdata, $parent) {
if( typeof subdata === 'object' ) {
for(var key in subdata) {
$parent.text(key)
var $sublist = $('<ul></ul>');
recursiveCaller(subdata[key], $sublist);
}
} else {
var $child = $('<li></li>');
$child.text(subdata)
$parent.append($child);
}
}
$.get('url', function () {
var $menu = caller(data);
$('#div_containing_ul').append($menu);
});
});
This could easily deal with a structure like
var data = {
'key1': ['val1', 'val2', 'val3'],
'key2': [
{'key2': ['val4', 'val5', 'val6']},
'val5',
'val6'],
'key3': [
{
'key2':
{
'key2': [
'val4',
{
'key2': ['val4', 'val5', 'val6']
},
'val6'],
0: 'val5',
1: 'val6'
}
}]
};
Good luck
Upvotes: 1
Reputation: 196002
An error and a missing append.
The .appendTo(subli);
should really be .appendTo($subul);
and at the end of the function you need to add the $li
to the $list
.
data = {
"key1": ["value1", "value2", "value3"],
"key2": ["value4", "value5", "value6"],
"key3": ["value7"]
}
jQuery(document).ready(function($) {
var $ul = $('<ul></ul>');
function getList(item, $list) {
$.each(item, function(key, value) {
var $li = $('<li />');
$li.append($('<a href="#">' + key + '</a>'));
var $subul = $("<ul/>");
$.each(value, function(i) {
var subli = $('<li/>')
.text(value[i])
.appendTo($subul); // you need to append it to the $subul not the $subli
});
$li.append($subul).appendTo($list); // you need to append the $li to the $list
});
}
getList(data, $ul);
$ul.appendTo("#div_containing_ul");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div_containing_ul"></div>
Upvotes: 1