2009-07-04 36 views
14

Me gustaría generar un árbol HTML (preferiblemente UL-LI) del ejemplo JSON a continuación. ¿Alguien tiene una simple, función JS recursiva (no un marco) que puede manejar esta estructura específica? ¡Gracias por tu ayuda!Convertir JSON en Árbol HTML

{ "folder" : [ { 
    "title" : "1", 
    "folder" : [ { 
     "title" : "1.1", 
     "folder" : [ { 
      "title" : "1.1.1", 
     } , { 
      "title" : "1.1.2", 
     } ] 
    } ] 
} , { 
    "title" : "2", 
} ] } 

Respuesta

7
function to_ul (obj) { 
    // --------v create an <ul> element 
    var f, li, ul = document.createElement ("ul"); 
    // --v loop through its children 
    for (f = 0; f < obj.folder.length; f++) { 
    li = document.createElement ("li"); 
    li.appendChild (document.createTextNode (obj.folder[f].title)); 
    // if the child has a 'folder' prop on its own, call me again 
    if (obj.folder[f].folder) { 
     li.appendChild (to_ul (obj.folder[f].folder)); 
    } 
    ul.appendChild (li); 
    } 
    return ul; 
} 

Advertencia: No hay error comprobando! Si falta un 'título' o 'carpeta', todo podría explotar.

Saludos,

+0

También es falta añadir el li en el ul. Agregue un ul.appendChild (li) antes de que for-loop se cierre y debería funcionar. –

+1

También hay un problema con la validez: el título de la UL se acaba de anexar. Esto es algo que no es muy útil. – Boldewyn

+0

¡Bien, resuelto! No hay título para ir con la UL. – Boldewyn

0

@Boldewyn: Creo que también se puede utilizar un bucle for ... in en lugar de un bucle regular para acortar el código un poco. Por supuesto, no tengo mucha experiencia en el uso de este tipo de bucle, así que por favor revisa mi fragmento de código.

for (var i in obj.folder) { 
    li = document.createElement ("li"); 
    li.appendChild (document.createTextNode (i.title)); 
    // if the child has a 'folder' prop on its own, call me again 
    if (i.folder) { 
     li.appendChild (to_ul (i.folder)); 
    } 
} 
+0

Sí, eso también lo haría. – Boldewyn

+0

Lo incluí en mi respuesta, ¡gracias! – Boldewyn

+0

No, lo sacó de nuevo. El i contendría el rango 0..n y no los elementos de la matriz. – Boldewyn

6

que tuvimos un problema con mi navegador para aceptar la estructura de datos presentado por la OP, pero aquí es un ejemplo completamente de trabajo que he dibujado para mis propios fines similares. Además de la función, proporciono la estructura de datos también, con nombre/ramas en lugar de título/carpeta.

<html> 
<head> 
<script> 
function to_ul(branches) { 
    var ul = document.createElement("ul"); 

    for (var i=0, n=branches.length; i<n; i++) { 
     var branch = branches[i]; 
     var li = document.createElement("li"); 

     var text = document.createTextNode(branch.name); 
     li.appendChild(text); 

     if (branch.branches) { 
      li.appendChild(to_ul(branch.branches)); 
     } 

     ul.appendChild(li); 
    } 

    return ul; 
} 

function renderTree() { 
    var treeEl = document.getElementById("tree"); 

    var treeObj = {"root": [{ 
     "name": "George & Sarah Trede", 
     "branches": [{ 
      "name": "George & Frances Trede", 
      "branches" : [{ 
       "name": "Mary (Trede) Jempty" 
      },{ 
       "name": "Carol (Trede) Moeller" 
      }] 
     },{ 
      "name": "Mary (Trede) Sheehan" 
     },{ 
      "name": "Ward Trede" 
     }] 
    }]}; 

    treeEl.appendChild(to_ul(treeObj.root)); 
} 
</script> 
</head> 

<body onload="renderTree()"> 
<div id="tree"></div> 
</body> 

</html> 
3

He usado PURE con cierto éxito en el pasado por este tipo de cosas.

2

Mira el plugin jquery JSON2HTML, es un poco más fácil de usar que PURE y lo he usado en un par de sitios que he creado.

http://json2html.com

+0

error en el enlace, actualice el enlace – wilsonrufus

2
function to_li(obj, name) { 
    var li = document.createElement("li"); 
    if (typeof(name) != "undefined") { 
     var strong = document.createElement("strong"); 
     strong.appendChild(document.createTextNode(name + ": ")); 
     li.appendChild(strong); 
    } 
    if (typeof(obj) != "object"){ 
     li.appendChild(document.createTextNode(obj)); 
    } else { 
     var ul = document.createElement ("ul"); 
     for (var prop in obj){ 
      ul.appendChild(to_li(obj[prop],prop)); 
     } 
     li.appendChild(ul); 
    } 
    return li; 
}