Reputation: 73
I have created a script to add a menu to a site that I am working on, it pulls the menu data from a JSON file and inserts it into the page. When the page loads, the sub-menu doesn't open when clicked :|
So I added one to the HTML file to see if there was an issue there and that one works perfectly.
I have the dev site live here https://ketchup.dev.danielcoates.co.uk/ (No longer available 30/03/17) if you need to see more of the code.
The Menu HTML
<div class="side-content">
<ul class="nav-main">
<li id="menu-0">
<a class="nav-submenu" data-toggle="nav-submenu" href="#">
<i class="si si-user"></i>
<span class="sidebar-mini-hide">User Profile</span>
</a>
<ul>
<li>
<a href="base_pages_profile.html">Profile</a>
</li>
<li>
<a href="base_pages_profile_v2.html">Profile v2</a>
</li>
<li>
<a href="base_pages_profile_edit.html">Profile Edit</a>
</li>
</ul>
</li>
</ul>
</div>
The Menu Code
$(document).ready(function() {
$.getJSON('/menu/menu.json', function(data) {
// convert json into array
var menu = [];
$.each(data, function(k, v){
for (var i = 0; i < v.length; i++) {
menu.push(v[i]);
};
});
for(var i=0; i < menu.length; i++) {
if(menu[i]['type'] == 'item') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<a href="' + menu[i]['link'] + '">\
<i class="' + menu[i]['icon'] + '"></i>\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</a>'
);
} else if(menu[i]['type'] == 'header') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<li class="nav-main-heading">\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</li>'
);
} else if(menu[i]['type'] == 'submenu') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<a class="nav-submenu" data-toggle="nav-submenu" href="#">\
<i class="' + menu[i]['icon'] + '"></i>\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</a>'
)
} else if(menu[i]['type'] == 'submenu-item') {
$('#menu-' + menu[i]['parent']).append('<ul><li><a href="/test">Test</a></ul>');
};
};
});
});
The JSON
{
"menu":
[
{ "id": 1,
"parent": 0,
"type": "item",
"active": false,
"title": "Dashboard",
"icon": "si si-speedometer",
"link": "/dashboard"
},
{ "id": 2,
"parent": 0,
"type": "header",
"active": false,
"title": "Pocurement",
"icon": false,
"link": false
},
{ "id": 3,
"parent": 0,
"type": "item",
"active": false,
"title": "Suppliers",
"icon": "si si-notebook",
"link": "/suppliers"
},
{ "id": 4,
"parent": 0,
"type": "item",
"active": true,
"title": "Duty Calculator",
"icon": "si si-calculator",
"link": "/app/duty_calculator"
},
{ "id": 5,
"parent": 0,
"type": "header",
"active": false,
"title": "Products",
"icon": false,
"link": false
},
{ "id": 6,
"parent": 0,
"type": "submenu",
"active": false,
"title": "Manage Products",
"icon": "si si-tag",
"link": "#"
},
{ "id": 7,
"parent": 6,
"type": "submenu-item",
"active": false,
"title": "List Products",
"icon": false,
"link": "/products/list"
}
]
}
Upvotes: 2
Views: 197
Reputation: 73
I have found a solution, tho not an elegant one :/
The problem seems to come from the functionality for the sub menu opening residing inside a function called uiNav
inside the main \assets\js\app.js
file. I think this is being initialised before the JSON menu is loaded.
By placing that code inside the menu.js
call back and placing it in the uiNav
function it solves the issue.
The final code that resides in the app.js
file is
var uiNav = function() {
$.getJSON('/menu/menu.json', function(data) {
// convert json into array
var menu = [];
$.each(data, function(k, v){
for (var i = 0; i < v.length; i++) {
menu.push(v[i]);
};
});
for(var i=0; i < menu.length; i++) {
if(menu[i]['type'] == 'item') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<a href="' + menu[i]['link'] + '">\
<i class="' + menu[i]['icon'] + '"></i>\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</a>'
);
} else if(menu[i]['type'] == 'header') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<li class="nav-main-heading">\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</li>'
);
} else if(menu[i]['type'] == 'submenu') {
$('.nav-main').append('<li id="menu-' + menu[i]['id'] + '"></li>');
$('#menu-' + menu[i][['id']]).append('\
<a class="nav-submenu" data-toggle="nav-submenu" href="#">\
<i class="' + menu[i]['icon'] + '"></i>\
<span class="sidebar-mini-hide">' + menu[i]['title'] + '</span>\
</a>'
)
} else if(menu[i]['type'] == 'submenu-item') {
$('#menu-' + menu[i]['parent']).append('<ul><li><a href="/test">Test</a></ul>');
};
};
// When a submenu link is clicked
jQuery('[data-toggle="nav-submenu"]').on('click', function(e){
// Get link
var $link = jQuery(this);
// Get link's parent
var $parentLi = $link.parent('li');
if ($parentLi.hasClass('open')) { // If submenu is open, close it..
$parentLi.removeClass('open');
} else { // .. else if submenu is closed, close all other (same level) submenus first before open it
$link
.closest('ul')
.find('> li')
.removeClass('open');
$parentLi
.addClass('open');
}
// Remove focus from submenu link
if ($lHtml.hasClass('no-focus')) {
$link.blur();
}
return false;
});
});
};
Upvotes: 1
Reputation: 469
You are trying to iterate over the value
of each array's key, instead of its length
.
Try replacing for (var i = 0; i < v.length; i++)
by for (var i = 0; i < data.length; i++)
in order to loop on the whole array.
Let me know if that worked! I could have missed something :)
Upvotes: 0