Javascript 使用嵌套行展开/折叠表格行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11574586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:22:30  来源:igfitidea点击:

Expand/Collapse table rows with nested rows

javascriptjqueryhtml

提问by amit

I want to create a table with the following structure:
Row1 datacolumn1 datacolumn2 datacolumn2
SubRow1 datacolumn1 datacolumn2 datacolumn2
SubRow2 datacolumn1 datacolumn2 datacolumn2
SubRow3 datacolumn1 datacolumn2 datacolumn2

我想创建一个具有以下结构的表:
Row1 datacolumn1 datacolumn2 datacolumn2
SubRow1 datacolumn1 datacolumn2 datacolumn2
SubRow2 datacolumn1 datacolumn2 datacolumn2
SubRow3 datacolumn1 datacolumn2 datacolumn2

I want to the subrows to expand/collapse on click. I just cant seem to make it work with tables. I know lists would be a better option but tables are much easier to maintain.

我想让子行在点击时展开/折叠。我似乎无法让它与表格一起工作。我知道列表会是一个更好的选择,但表格更容易维护。

<tbody>
    <tr class="row1 head1">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row1 head2 closed">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row1 head3">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row1 head4">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row1 head5">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row2 head1">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>

    <tr class="row2 head4">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr class="row2 head5">
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr>
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>
    <tr>
        <td>Cash and Equivalents</td>
        <td>000,000</td>
        <td>000,000</td>

    </tr>

</tbody>

on row click, i call the following function:

在行单击时,我调用以下函数:

holdingsTree: function(that){
    var stack = '',
        classes = ba.splitClasses(that.attr('class')),
        nextRow = ba.getClassNumber(classes[1], "head");

    if (that.next().hasClass('head'+nextRow)){
        if (that.next().hasClass(classes[0]) && that.next().hasClass('open')){
            that.nextUntil('.head1').hide().addClass('closed').removeClass('open');
        } else if (that.next().hasClass(classes[0])){
            stack = that.nextUntil('.head1');
            $.each(stack, function(i, item){ if ($(item).hasClass('head' + (nextRow))){ $(this).show().addClass('open').removeClass('closed'); } });
        }
    } else if (that.next().hasClass('head'+ (nextRow+1))){
        if (that.next().hasClass(classes[0]) && that.next().hasClass('open')){
            that.nextUntil('.head1').hide().addClass('closed').removeClass('open');
        } else if (that.next().hasClass(classes[0])){
            stack = that.nextUntil('.head1');
            $.each(stack, function(i, item){ if ($(item).hasClass('head' + (nextRow+1))){ $(this).show().addClass('open').removeClass('closed'); } });
        }
    } else if (that.next().hasClass('head'+ (nextRow+2))){
        if (that.next().hasClass(classes[0]) && that.next().hasClass('open')){
            that.nextUntil('.head1').hide().addClass('closed').removeClass('open');
            return;
        } else if (that.next().hasClass(classes[0])){
            stack = that.nextUntil('.head'+ (nextRow+3));
            $.each(stack, function(i, item){ if ($(item).hasClass('head' + (nextRow+2))){ $(this).show().addClass('open').removeClass('closed'); } });
            //stack.find('.head'+(nextRow+2)).show().addClass('open').removeClass('closed');
        }
    } else if (that.next().hasClass('head'+ (nextRow+3))){
        if (that.next().hasClass(classes[0]) && that.next().hasClass('open')){
            that.nextUntil('.head1').hide().addClass('closed').removeClass('open');
        } else if (that.next().hasClass(classes[0])){
            stack = that.nextUntil('.head1');
            $.each(stack, function(i, item){ if ($(item).hasClass('head' + (nextRow+3))){ $(this).show().addClass('open').removeClass('closed'); } });
        }
    } else if (that.next().hasClass('head'+ (nextRow+4))){
        if (that.next().hasClass(classes[0]) && that.next().hasClass('open')){
            that.nextUntil('.head1').hide().addClass('closed').removeClass('open');
        } else if (that.next().hasClass(classes[0])){
            that.nextUntil('.head1').show().addClass('open').removeClass('closed');
        }
    } 

},

splitClasses: function(names){
    var names = names.split(' ');
    return names;
},

getClassNumber: function(name, pretext){
    var result = name.split(pretext);
    console.log(parseInt(result[1]) + 1);
    return parseInt(result[1]) + 1;
}

ITs very bad. I know. :)

这很糟糕。我知道。:)

回答by Angel

You can have a class for the rows you call parents, and a class for the rows you call children, and toggle their display.

您可以为称为父项的行创建一个类,为称为子项的行创建一个类,并切换它们的显示。

Here's how:

就是这样:

$(document).ready(function() {

    function getChildren($row) {
        var children = [];
        while($row.next().hasClass('child')) {
             children.push($row.next());
             $row = $row.next();
        }            
        return children;
    }        

    $('.parent').on('click', function() {

        var children = getChildren($(this));
        $.each(children, function() {
            $(this).toggle();
        })
    });

})

Check this fiddle for the complete running code http://jsfiddle.net/T8t2r/3/And please accept the answer if this solves your problem!

检查此小提琴以获取完整的运行代码http://jsfiddle.net/T8t2r/3/如果这解决了您的问题,请接受答案!

Good luck!

祝你好运!

EDIT: to work on more levels one way is to have a level attribute. So here is the updated version which should work on any number of levels. http://jsfiddle.net/T8t2r/9/

编辑:在更多级别上工作的一种方法是拥有级别属性。所以这里是更新的版本,它应该可以在任意数量的级别上工作。http://jsfiddle.net/T8t2r/9/

$(document).ready(function() {

    function getChildren($row) {
        var children = [], level = $row.attr('data-level');
        while($row.next().attr('data-level') > level) {
             children.push($row.next());
             $row = $row.next();
        }            
        return children;
    }        

    $('.parent').on('click', function() {

        var children = getChildren($(this));
        $.each(children, function() {
            $(this).toggle();
        })
    });

})

回答by Alex Ball

You could do this:

你可以这样做:

$('.mySelectorOfNOTSubRow').toggle(
    function(){
        $(this).nextUntil('.mySelectorOfNOTSubRow').show();
    }, function(){
        $(this).nextUntil('.mySelectorOfNOTSubRow').hide();
});

HTML:

HTML:

<table>
<tbody>
<tr class="head"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
<tr class="head"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
<tr class="head"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
     <tr class="sub"><td></td></tr>
...
</tbody>
</table>

CSS:

CSS:

.sub{display: none;}

Fiddle

小提琴

回答by John - Not A Number

It's hard to make out what you are trying to do from that example.

很难从那个例子中弄清楚你想要做什么。

What you are trying to do should be fairly simple - what I'd do is rewrite from scratch, using the following concepts:

您尝试做的应该相当简单 - 我要做的是使用以下概念从头开始重写:

  1. Give each clickable item (row) it's own ID, but have them all in one 'clickable' class
  2. Give each sub row a class based off of the ID of the clickable parent - such as '[id]-sub'
  3. Set up a click event on the 'clickable' class, where you determine the clicked Item ID, and use that to toggle (hide/show) all rows with class '[clicked ID]-sub'
  1. 为每个可点击的项目(行)赋予它自己的 ID,但将它们全部放在一个“可点击”类中
  2. 根据可点击父行的 ID 为每个子行指定一个类 - 例如“[id]-sub”
  3. 在“clickable”类上设置一个点击事件,您可以在其中确定单击的项目 ID,并使用它来切换(隐藏/显示)类“[clicked ID]-sub”的所有行

Doing it that way, you should have much less code, and it should be much more readable.

这样做,你应该有更少的代码,它应该更具可读性。

Hope this helps...

希望这可以帮助...

回答by DKSan

As you are already using jQuery, you could go with the plugin datatales.

由于您已经在使用 jQuery,您可以使用插件datatales

As you can see in the example section of the page, theres exactly what you are trying to achieve with your code.

正如您在页面的示例部分所看到的,这正是您试图用代码实现的目标。