¿Cómo crear una tabla de árbol colapsable en html / css / js?

Tengo algunos datos para mostrar que son tanto tabulares como jerárquicos. Me gustaría que el usuario pueda expandir y colapsar los nodos.

Más o menos así, excepto funcional:

http://www.maxdesign.com.au/articles/tree-table/

¿Cuál sería la mejor manera de abordar esto? No soy adverso al uso de un complemento estándar.

SlickGrid tiene esta funcionalidad, vea la demostración en árbol .

Si quiere construir el suyo, aquí tiene un ejemplo ( demostración de jsFiddle ): cree su tabla con un atributo de data-depth para indicar la profundidad del elemento en el árbol (las clases CSS de levelX son solo para el estilo de la sangría):

 
Item 1 123
Item 2 123

Luego, cuando se hace clic en un enlace de alternar, use Javascript para ocultar todos los elementos

hasta que se encuentre un

de igual o menor profundidad (excluidos los que ya se colapsaron):

 $(function() { $('#mytable').on('click', '.toggle', function () { //Gets all 's of greater depth below element in the table var findChildren = function (tr) { var depth = tr.data('depth'); return tr.nextUntil($('tr').filter(function () { return $(this).data('depth') <= depth; })); }; var el = $(this); var tr = el.closest('tr'); //Get  parent of toggle button var children = findChildren(tr); //Remove already collapsed nodes from children so that we don't //make them visible. //(Confused? Remove this code and close Item 2, close Item 1 //then open Item 1 again, then you will understand) var subnodes = children.filter('.expand'); subnodes.each(function () { var subnode = $(this); var subnodeChildren = findChildren(subnode); children = children.not(subnodeChildren); }); //Change icon and hide/show children if (tr.hasClass('collapse')) { tr.removeClass('collapse').addClass('expand'); children.hide(); } else { tr.removeClass('expand').addClass('collapse'); children.show(); } return children; }); }); 

En los navegadores modernos, solo necesita muy poco para codificar para crear un árbol colapsible:

 var tree = document.querySelectorAll('ul.tree a:not(:last-child)'); for(var i = 0; i < tree.length; i++){ tree[i].addEventListener('click', function(e) { var parent = e.target.parentElement; var classList = parent.classList; if(classList.contains("open")) { classList.remove('open'); var opensubs = parent.querySelectorAll(':scope .open'); for(var i = 0; i < opensubs.length; i++){ opensubs[i].classList.remove('open'); } } else { classList.add('open'); } e.preventDefault(); }); } 
 body { font-family: Arial; } ul.tree li { list-style-type: none; position: relative; } ul.tree li ul { display: none; } ul.tree li.open > ul { display: block; } ul.tree li a { color: black; text-decoration: none; } ul.tree li a:before { height: 1em; padding:0 .1em; font-size: .8em; display: block; position: absolute; left: -1.3em; top: .2em; } ul.tree li > a:not(:last-child):before { content: '+'; } ul.tree li.open > a:not(:last-child):before { content: '-'; } 
  

jquery es tu amigo aquí.

http://docs.jquery.com/UI/Tree

Si quieres hacer tu propia, aquí hay una guía de alto nivel:

Visualice todos sus datos como elementos

    con los datos internos nesteds

      , y luego use el jquery:

       $('.ulClass').click(function(){ $(this).children().toggle(); }); 

      Yo creo que eso es correcto. Algo como eso.

      EDITAR:

      Aquí hay un ejemplo completo.

              
      • item 1
        • item 1
        • item 2
          • item 1
          • item 2
          • item 3
          • item 4
        • item 3
        • item 4
          • item 1
          • item 2
          • item 3
          • item 4
      • item 2
        • item 1
        • item 2
        • item 3
        • item 4
      • item 3
        • item 1
        • item 2
        • item 3
        • item 4
      • item 4

      Lanzaré jsTree al ring, también. Lo encontré bastante adaptable a su situación particular. Está empaquetado como un plugin jQuery.

      Puede ejecutarse desde una variedad de fonts de datos, pero mi favorito es una simple lista anidada, como se describe en @joe_coolish o aquí:

       
      • Item 1
        • Item 1.1
        • ...
      • ...

      Esta estructura falla con gracia en un árbol estático cuando JS no está disponible en el cliente, y es fácil de leer y comprender desde una perspectiva de encoding.

      HTML 5 permite la etiqueta de resumen, elemento de detalles. Eso se puede usar para ver u ocultar (contraer / expandir) una sección. Enlazar

      Puede probar jQuery treegrid ( http://maxazan.github.io/jquery-treegrid/ ) o jQuery treetable ( http://ludo.cubicphuse.nl/jquery-treetable/ )

      Ambos utilizan el formato de etiqueta HTML

      y diseñaron el árbol como.

      La tabla en árbol de jQuery usa data-tt-id y data-tt-parent-id para determinar el padre y el hijo del árbol. Ejemplo de uso:

       
      Parent
      Child
      $("#tree").treetable({ expandable: true });

      Mientras tanto, jQuery treegrid usa solo una clase para diseñar el árbol. Ejemplo de uso:

       
      Root nodeAdditional info
      Node 1-1Additional info
      Node 1-2Additional info
      Node 1-2-1Additional info