Reputation: 199
I have tried this but it doesn't work. I'm trying to make Dynamic Menu from jQuery json data. I have insert preview below.
I'm working on fully custom UI, so I plan not to use jQuery.UI.
var data = {
menu: [{
name: 'Women Cloth',
link: '0',
sub: null
},{
name: 'Men Cloth',
link: '1',
sub: [{
name: 'Arsenal',
link: '0-0',
sub: null
}, {
name: 'Liverpool',
link: '0-1',
sub: null
}, {
name: 'Manchester United',
link: '0-2',
sub: null
}]
}]};
var getMenuItem = function (itemData) {
var item = $("<li>", {
class: 'has-children',
id: itemData.id
}).append(
$("<a>", {
href: itemData.link,
html: itemData.name,
id: itemData.id + '-links',
}));
if (itemData.sub) {
var subMenuItem = $("<li>", {
class: 'has-icon'
}).append(
$("<a>", {
href: itemData.link,
class: 'submenu-title',
}));
var subList = $("<ul>", {
class: 'secondary-dropdown',
});
$.each(itemData.sub, function () {
subList.append(subMenuItem(this));
});
item.append(subList);
}
return item;
};
var $menu = $("#Menu");
$.each(data.menu, function () {
$menu.append(
getMenuItem(this)
);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="Menu"></ul>
Below is the output I needed.
<li class="has-children" id="ID">
<a id="ID-links" href="links">Women Clothing</a>
<ul class="cd-secondary-dropdown is-hidden">
<li class="go-back"><a>Back</a></li>
<li class="has-icon"><a class="submenu">submenu 1</a></li>
<li class="has-icon"><a class="submenu">submenu 2</a></li>
<li class="has-icon"><a class="submenu">submenu 3</a></li>
<li class="has-icon"><a class="submenu">submenu 4</a></li>
<li class="has-icon"><a class="submenu">submenu 5</a></li>
</ul>
</li>
<li class="has-children" id="ID">
<a id="ID-links" href="links">Men Clothing</a>
<ul class="cd-secondary-dropdown is-hidden">
<li class="go-back"><a>Back</a></li>
<li class="has-icon"><a class="submenu">submenu 1</a></li>
<li class="has-icon"><a class="submenu">submenu 2</a></li>
<li class="has-icon"><a class="submenu">submenu 3</a></li>
<li class="has-icon"><a class="submenu">submenu 4</a></li>
<li class="has-icon"><a class="submenu">submenu 5</a></li>
</ul>
</li>
Upvotes: 2
Views: 1297
Reputation: 14570
You were not using $.each
function as you were supposed. you are passing this
as args
to your function. this
will undefined
in the function getMenuItem
In you $.each function you need to have args as index and data. Index
return the number of each key
in you JSON
& data
is the one you need to pass to your function.
Also in your cd-secondary-dropdown
you need to add ul
only once and not in $.each
.
I have fixed up your code
and is exactly working as you wanted in your output above.
Run snippet below to see it working.
var data = {
menu: [{
name: 'Women Cloth',
link: '0',
sub: null
}, {
name: 'Men Cloth',
link: '1',
sub: [{
name: 'Arsenal',
link: '0-0',
sub: null
}, {
name: 'Liverpool',
link: '0-1',
sub: null
}, {
name: 'Manchester United',
link: '0-2',
sub: null
}]
}]
};
var getMenuItem = function(itemData) {
var item = $("<li>", {
class: 'has-children',
id: itemData.id
}).append(
$("<a>", {
href: itemData.link,
html: itemData.name,
id: itemData.id + '-links',
}));
if (itemData.sub) {
//Add UL once only
var subList = $("<ul>", {
class: 'secondary-dropdown',
});
//Append go back
var goBack = $("<li>", {}).append(
$("<a>", {
href: '',
html: 'Go back',
class: 'go-back',
}));
//Append go back
subList.append(goBack);
$.each(itemData.sub, function(index, data) {
//Sub menu
var subMenuItem = $("<li>", {
class: 'has-icon'
}).append(
$("<a>", {
href: data.link,
html: data.name,
class: 'submenu-title',
}));
subList.append(subMenuItem);
});
item.append(subList);
}
return item;
};
var $menu = $("#Menu");
$.each(data.menu, function(index, data) {
$menu.append(getMenuItem(data));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="Menu"></ul>
Upvotes: 2
Reputation: 99
is this what you are trying to do? if yes, this is a way of doing it without jQuery
let data = {
menu: [{
name: 'Women Cloth',
link: '0',
sub: null
},{
name: 'Men Cloth',
link: '1',
sub: [{
name: 'Arsenal',
link: '0-0',
sub: null
}, {
name: 'Liverpool',
link: '0-1',
sub: null
}, {
name: 'Manchester United',
link: '0-2',
sub: null
}]
}]};
const MENU_COMPONENT = document.querySelector('#Menu');
for (const field in data.menu) {
const LI= document.createElement('li');
LI.setAttribute('class', 'has-children');
MENU_COMPONENT.appendChild(LI);
const LINK = document.createElement('a');
LINK.setAttribute('href', data.menu[field].link);
LINK.innerText = data.menu[field].name;
LI.appendChild(LINK);
const UL = document.createElement('ul');
UL.setAttribute('class', 'cd-secondary-dropdown is-hidden');
LI.appendChild(UL);
let SUBLEVEL_DATA = data.menu[field].sub;
for (const sub in SUBLEVEL_DATA) {
const SECOND_LEVEL_LI = document.createElement('li');
SECOND_LEVEL_LI.setAttribute('class', 'has-icon');
UL.appendChild(SECOND_LEVEL_LI);
const SECOND_LEVEL_LINK = document.createElement('a');
SECOND_LEVEL_LINK.setAttribute('href', SUBLEVEL_DATA[sub].link);
SECOND_LEVEL_LINK.className = 'submenu';
SECOND_LEVEL_LINK.innerText = SUBLEVEL_DATA[sub].name;
SECOND_LEVEL_LI.appendChild(SECOND_LEVEL_LINK);
}
}
<ul id="Menu"></ul>
Upvotes: 1