Comment créer une table de l'arbre en effondrement dans html / css / js?

J'ai quelques données à afficher qui sont à la fois tabulaires et hiérarchiques. J'aimerais que l'utilisateur puisse étendre et réduire les nœuds.

Un peu comme ceci, sauf fonctionnel:

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

Quelle serait la meilleure façon d'aborder cela? Je ne suis pas défavorable à l'utilisation d'un plug-in hors-site.

SlickGrid possède cette fonctionnalité, voir la démo de l' arborescence .

Si vous souhaitez créer votre propre, voici un exemple ( jsFiddle demo ): Créez votre table avec un attribut de data-depth pour indiquer la profondeur de l'élément dans l'arborescence (les classes CSS de levelX sont juste pour l'indentation de style):

 <table id="mytable"> <tr data-depth="0" class="collapse level0"> <td><span class="toggle collapse"></span>Item 1</td> <td>123</td> </tr> <tr data-depth="1" class="collapse level1"> <td><span class="toggle"></span>Item 2</td> <td>123</td> </tr> </table> 

Ensuite, lorsqu'un lien de bascule est cliqué, utilisez Javascript pour cacher tous les éléments <tr> jusqu'à ce qu'un <tr> d'une profondeur égale ou inférieure soit trouvé (à l'exclusion de ceux déjà effondrés):

 $(function() { $('#mytable').on('click', '.toggle', function () { //Gets all <tr>'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 <tr> 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; }); }); 

Jquery est votre ami ici.

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

Si vous voulez faire votre propre choix, voici quelques conseils de haut niveau:

Affichez toutes vos données comme <ul /> éléments avec les données internes comme nested <ul /> , puis utilisez jquery:

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

Je crois que c'est correct. Quelque chose comme ca.

MODIFIER:

Voici un exemple complet.

 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> </head> <body> <ul> <li><span class="Collapsable">item 1</span><ul> <li><span class="Collapsable">item 1</span></li> <li><span class="Collapsable">item 2</span><ul> <li><span class="Collapsable">item 1</span></li> <li><span class="Collapsable">item 2</span></li> <li><span class="Collapsable">item 3</span></li> <li><span class="Collapsable">item 4</span></li> </ul> </li> <li><span class="Collapsable">item 3</span></li> <li><span class="Collapsable">item 4</span><ul> <li><span class="Collapsable">item 1</span></li> <li><span class="Collapsable">item 2</span></li> <li><span class="Collapsable">item 3</span></li> <li><span class="Collapsable">item 4</span></li> </ul> </li> </ul> </li> <li><span class="Collapsable">item 2</span><ul> <li><span class="Collapsable">item 1</span></li> <li><span class="Collapsable">item 2</span></li> <li><span class="Collapsable">item 3</span></li> <li><span class="Collapsable">item 4</span></li> </ul> </li> <li><span class="Collapsable">item 3</span><ul> <li><span class="Collapsable">item 1</span></li> <li><span class="Collapsable">item 2</span></li> <li><span class="Collapsable">item 3</span></li> <li><span class="Collapsable">item 4</span></li> </ul> </li> <li><span class="Collapsable">item 4</span></li> </ul> <script type="text/javascript"> $(".Collapsable").click(function () { $(this).parent().children().toggle(); $(this).toggle(); }); </script> 

Dans les navigateurs modernes, il vous suffit de coder très peu pour créer un arbre pliable:

 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'); } }); } 
 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: '-'; } 
 <ul class="tree"> <li><a href="#">Part 1</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> <li><a href="#">Part 2</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> <li><a href="#">Part 3</a> <ul> <li><a href="#">Item A</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item B</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item C</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item D</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> <li><a href="#">Item E</a> <ul> <li><a href="#">Sub-item 1</a></li> <li><a href="#">Sub-item 2</a></li> <li><a href="#">Sub-item 3</a></li> </ul> </li> </ul> </li> </ul> 

Je jetterai jsTree dans l'anneau aussi. Je l'ai trouvé assez adaptable à votre situation particulière. Il est emballé comme un plugin jQuery.

Il peut fonctionner à partir d'une variété de sources de données, mais mon préféré est une simple liste imbriquée, tel que décrit par @joe_coolish ou ici:

 <ul> <li> Item 1 <ul> <li>Item 1.1</li> ... </ul> </li> ... </ul> 

Cette structure échoue gracieusement dans un arbre statique lorsque JS n'est pas disponible dans le client et est assez facile à lire et à comprendre d'un point de vue codé.

HTML 5 permet une balise récapitulative, élément de détail. Cela peut être utilisé pour afficher ou masquer (effondrer / développer) une section. Lien

Vous pouvez essayer jQuery treegrid ( http://maxazan.github.io/jquery-treegrid/ ) ou jQuery treetable ( http://ludo.cubicphuse.nl/jquery-treetable/ )

Les deux utilisent le format d'étiquette HTML <table> et l'arborescence sous forme de style.

Le fichier jQuery arborescent utilise data-tt-id et data-tt-parent-id pour déterminer le parent et l'enfant de l'arbre. Exemple d'utilisation:

 <table id="tree"> <tr data-tt-id="1"> <td>Parent</td> </tr> <tr data-tt-id="2" data-tt-parent-id="1"> <td>Child</td> </tr> </table> $("#tree").treetable({ expandable: true }); 

Pendant ce temps, jQuery treegrid n'utilise que la classe pour le coiffage de l'arbre. Exemple d'utilisation:

 <table class="tree"> <tr class="treegrid-1"> <td>Root node</td><td>Additional info</td> </tr> <tr class="treegrid-2 treegrid-parent-1"> <td>Node 1-1</td><td>Additional info</td> </tr> <tr class="treegrid-3 treegrid-parent-1"> <td>Node 1-2</td><td>Additional info</td> </tr> <tr class="treegrid-4 treegrid-parent-3"> <td>Node 1-2-1</td><td>Additional info</td> </tr> </table> <script type="text/javascript"> $('.tree').treegrid(); </script>