Tuesday, May 14, 2024
 Popular · Latest · Hot · Upcoming
147
rated 0 times [  152] [ 5]  / answers: 1 / hits: 24847  / 13 Years ago, mon, february 20, 2012, 12:00:00

I am trying to use use the following JSON data to create the following similar structure in a recursive inner function with not much luck, really need some help and so if anyone can assist please do. Thank you in advance.



<ul>
<li></li>
<li>
<a href=></a>
<div>
<ul>
<li>
<a href=></a>
<div>
....etc
</div>
</li>
</ul>
</div>
</li>
</ul>


the JSON data I am using is as follows:



    var JSON = {
menu: [
{id: '0',sub: [
{name: 'lorem ipsum 0-0',link: '0-0', sub: null},
{name: 'lorem ipsum 0-1',link: '0-1', sub: null},
{name: 'lorem ipsum 0-2',link: '0-2', sub: null}
]
},
{id: '1',sub: null},
{id: '2',sub: [
{name: 'lorem ipsum 2-0',link: '2-0', sub: null},
{name: 'lorem ipsum 2-1',link: '2-1', sub: null},
{name: 'lorem ipsum 2-2',link: '2-2', sub: [
{name: 'lorem ipsum 2-2-0',link: '2-2-0', sub: null},
{name: 'lorem ipsum 2-2-1',link: '2-2-1', sub: null},
{name: 'lorem ipsum 2-2-2',link: '2-2-2', sub: null},
{name: 'lorem ipsum 2-2-3',link: '2-2-3', sub: null},
{name: 'lorem ipsum 2-2-4',link: '2-2-4', sub: null},
{name: 'lorem ipsum 2-2-5',link: '2-2-5', sub: null},
{name: 'lorem ipsum 2-2-6',link: '2-2-6', sub: null}
]},
{name: 'lorem ipsum 2-3',link: '2-3', sub: null},
{name: 'lorem ipsum 2-4',link: '2-4', sub: null},
{name: 'lorem ipsum 2-5',link: '2-5', sub: null}
]
},
{id: '3',sub: null}
]
}


and the code I have created (incomplete, this is the brain teaser I need help on) is:



$(function(){

$.fn.dropdown = function(settings){
var that = this;
var settings = $.extend({}, $.fn.dropdown.defaults, settings);
var methods = {
isArray: function(o){
return Object.prototype.toString.call(o) === '[object Array]';
},
createDropdownCode: function(arr){
var menu = arr.menu;
var html = null;
var menusort = function(menu){
html = that;

that.find(li).each(function(idx){

var menuList = menu[idx].sub;
var baseContainer = $(this);
var count = -1;

var subsort = (function(){

count += 1;

return function(submenu, pb){

var subblock;
subblock = $(<div />).append('<ul />');

if(methods.isArray(submenu)){

for(var i=0;i<submenu.length;i++){

var l = $(<li />).append(<a href='+ submenu[i].link +'>+ submenu[i].name +</a>);

subblock.find('ul').append(l);

if(pb !== undefined && i == submenu.length-1){
pb.append(subblock)
}

if(methods.isArray(submenu[i].sub)){
subsort(submenu[i].sub, subblock.find('ul li').eq(i));
}

}
}
}
})()
subsort(menuList)
})
}
menusort(menu);
return null; //html !== null ? html.html() : null;
},
init: function(){

// filter through json
// create the div=>ul=>li
if(settings.jsonData === undefined || settings.jsonData === null){
console.warn('No JSON Data passed')
return;
}else{
if(!methods.isArray(settings.jsonData.menu)){
console.warn('No JSON Data passed')
return; // error, no data!
}
}


//var html = methods.createBlock(settings.jsonData.menu[0].sub);
var html = methods.createDropdownCode(settings.jsonData);
//console.log(html)
}
}

methods.init();

return that;

}

$.fn.dropdown.defaults = {
jsonData: null
}

})

$('#menu').dropdown({
jsonData: JSON
});


integrated code used, thanks to the individual that gave a close enough answer - Although will study the others.



$.fn.dropdown = function(settings){

var that = this;
var settings = $.extend({}, $.fn.dropdown.defaults, settings);

var methods = {
createDropDownCode: function(arr){

// loop through li's of primary menu
that.find(li).each(function(idx){

$(this).append( menusort(arr.menu[idx].sub) );

function menusort(data){
if(data !== null)
var html = <div><ul>;

for(item in data){
html += <li>;
if(typeof(data[item].sub) === 'object'){
html += <a href=' + data[item].link + '> + data[item].name + </a>;
if($.isArray(data[item].sub))
html += menusort(data[item].sub);
}
html += </li>
}
if(data !== null)
html += </ul></div>;
return html;
}
})
},
init: function(){
var html = methods.createDropDownCode(settings.jsonData);

}
}

methods.init();

}

More From » json

 Answers
30

You can try this recursive function I've just coded:



function buildList(data, isSub){
var html = (isSub)?'<div>':''; // Wrap with div if true
html += '<ul>';
for(item in data){
html += '<li>';
if(typeof(data[item].sub) === 'object'){ // An array will return 'object'
if(isSub){
html += '<a href=' + data[item].link + '>' + data[item].name + '</a>';
} else {
html += data[item].id; // Submenu found, but top level list item.
}
html += buildList(data[item].sub, true); // Submenu found. Calling recursively same method (and wrapping it in a div)
} else {
html += data[item].id // No submenu
}
html += '</li>';
}
html += '</ul>';
html += (isSub)?'</div>':'';
return html;
}


It returns the html for the menu, so use it like that: var html = buildList(JSON.menu, false);



I believe it is faster because it's in pure JavaScript, and it doesn't create text nodes or DOM elements for every iteration. Just call .innerHTML or $('...').html() at the end when you're done instead of adding HTML immediately for every menu.



JSFiddled: http://jsfiddle.net/remibreton/csQL8/


[#87334] Sunday, February 19, 2012, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
joaquin

Total Points: 150
Total Questions: 103
Total Answers: 113

Location: Saint Helena
Member since Tue, Nov 3, 2020
4 Years ago
;