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>