简体   繁体   English

如何在 html/css/js 中创建一个折叠树表?

[英]How to create a collapsing tree table in html/css/js?

I have some data to display that is both tabular and hierarchical.我有一些数据要显示,既是表格又是分层的。 I'd like to let the user be able to expand and collapse the nodes.我想让用户能够展开和折叠节点。

Sort of like this, except functional:有点像这样,除了功能:

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

What would be the best way to approach this?解决这个问题的最佳方法是什么? I'm not adverse to using an off-the-shelf plugin.我不反对使用现成的插件。

SlickGrid has this functionality, see the tree demo . SlickGrid具有此功能,请参阅树演示

If you want to build your own, here is an example ( jsFiddle demo ): Build your table with a data-depth attribute to indicate the depth of the item in the tree (the levelX CSS classes are just for styling indentation):如果您想构建自己的,这里有一个示例( jsFiddle 演示):使用data-depth属性构建您的表以指示树中项目的深度( levelX CSS 类仅用于样式缩进):

<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>

Then when a toggle link is clicked, use Javascript to hide all <tr> elements until a <tr> of equal or less depth is found (excluding those already collapsed):然后被点击肘杆时,使用Javascript来隐藏所有<tr>直到一个元素<tr>等于或小于深度的被发现(不包括已经崩溃):

$(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;
    });
});

In modern browsers, you need only very little to code to create a collapsible tree :在现代浏览器中,您只需要编写很少的代码即可创建可折叠树:

 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: '-'; }
 <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>

(see also this Fiddle ) (另见这个小提琴

jquery is your friend here. jquery 是你的朋友。

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

If you want to make your own, here is some high level guidance:如果您想自己制作,这里有一些高级指南:

Display all of your data as <ul /> elements with the inner data as nested <ul /> , and then use the jquery:将所有数据显示为<ul />元素,将内部数据显示为嵌套的<ul /> ,然后使用 jquery:

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

I believe that is correct.我相信这是正确的。 Something like that.类似的东西。

EDIT:编辑:

Here is a complete example.这是一个完整的例子。

 $(".Collapsable").click(function () { $(this).parent().children().toggle(); $(this).toggle(); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <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>

I'll throw jsTree into the ring, too.我也会把jsTree扔进戒指。 I've found it fairly adaptable to your particular situation.我发现它非常适合您的特定情况。 It's packed as a jQuery plugin.它被打包为一个 jQuery 插件。

It can run from a variety of data sources, but my favorite is a simple nested list, as described by @joe_coolish or here:它可以从各种数据源运行,但我最喜欢的是一个简单的嵌套列表,如@joe_coolish 或此处所述:

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

This structure fails gracefully into a static tree when JS is not available in the client, and is easy enough to read and understand from a coding perspective.当 JS 在客户端不可用时,这种结构会优雅地失败为静态树,并且从编码的角度来看很容易阅读和理解。

HTML 5 allows summary tag, details element. HTML 5 允许摘要标签、细节元素。 That can be used to view or hide (collapse/expand) a section.这可用于查看或隐藏(折叠/展开)一个部分。 Link关联

You can try jQuery treegrid ( http://maxazan.github.io/jquery-treegrid/ ) or jQuery treetable ( http://ludo.cubicphuse.nl/jquery-treetable/ )您可以尝试jQuery treegrid ( http://maxazan.github.io/jquery-treegrid/ ) 或jQuery treetable ( http://ludo.cubicphuse.nl/jquery-treetable/ )

Both are using HTML <table> tag format and styled the as tree.两者都使用 HTML <table>标记格式并将样式设置为树。

The jQuery treetable is using data-tt-id and data-tt-parent-id for determining the parent and child of the tree. jQuery 树表使用data-tt-iddata-tt-parent-id来确定树的父级和子级。 Usage example:用法示例:

<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 });

Meanwhile, jQuery treegrid is using only class for styling the tree.同时, jQuery treegrid只使用类来设置树的样式。 Usage example:用法示例:

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM