如何用jquery折叠多个表行



我正在尝试使用jQuery在表中折叠表行。

表中有3个"级别",头、子、子。

由于我正在处理tr,我对ul and li的正常方法不起作用,因为表行没有嵌套。我正在从服务中消费tr,不幸的是不能将其更改为ul/li父/子关系。下一个挑战我也没有父-id和子-id的关系。我只是得到一些css classesdata-attributes行的原始列表。

在我的代码下面折叠头(0级)工作良好。问题发生在1级(点击例如Sub 1.4),其中一些标头(0级)也会被折叠,而不是只有子(2级)。

下面是我的代码:

$(".collapse").click(function() { // attach click handler to .collapse css class
const level = $(this).parent("tr").data("level"); // 0 header, 1 sub, 2 child

var state = "";
$(this).find("span").text(function(_, value) {
state = (value == '-' ? '+' : '-');
return state;
});
console.log(level);
var rows;

if (level == 0) { // a header row (level=0) was clicked. collapse every tr until another header row is reached
rows = $(this).parent("tr").nextUntil("[data-level='0']");
} 
else { // a sub row (level=1) was clicked. 
rows = $(this).parent("tr").nextUntil("[data-level='" + level + "']"); // ## incorrect statement - what to do here to get the correct siblings "below" the sub?
}
// if state == - (expanded), then show, otherwise hide
_ = state == "-" ? rows.show() : rows.hide();
});
body {font-family:'Open Sans';font-size:20px}
th {border:solid 1px #000;text-align:left;font-weight:normal}
[data-level="0"] th {font-weight:bold;}
[data-level="1"] th {padding-left:20px;}
[data-level="2"] th {padding-left:40px;}
.collapse {cursor:pointer}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<table>
<tr data-level="0">
<th scope="row" class="collapse"><span>-</span> Header 1</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 1.1</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 1.2</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 1.3</th>
</tr>
<tr data-level="2">
<th scope="row">Child 1.3.1</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 1.4</th>
</tr>    
<tr data-level="0">
<th scope="row" class="collapse"><span>-</span> Header 2</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 2.2</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 2.2</th>
</tr>
<tr data-level="2">
<th scope="row">Child 2.2.1</th>
</tr>
<tr data-level="0">
<th scope="row" class="collapse"><span>-</span> Header 3</th>
</tr>
<tr data-level="1">
<th scope="row" class="collapse"><span>-</span> Sub 3.1</th>
</tr>
<tr data-level="2">
<th scope="row">Child 3.1.1</th>
</tr>    
</table>
</body>

JSFiddle here: https://jsfiddle.net/cLnmragy/2/

技巧是在.nextUntil([selector])过滤器中执行OR操作,生成以下解决方案:

rows = $(this).parent("tr").nextUntil("[data-level='1'],[data-level='0']");

javascript:

$(".collapse").click(function() { // attach click handler to .collapse css class
const level = $(this).parent("tr").data("level"); // 0 header, 1 sub, 2 child

var state = "";
$(this).find("span").text(function(_, value) {
state = (value == '-' ? '+' : '-');
return state;
});
console.log(level);
var rows;

if (level == 0) { // a header row (level=0) was clicked. collapse every tr until another header row is reached
rows = $(this).parent("tr").nextUntil("[data-level='0']");
} 
else { // a sub row (level=1) was clicked. 
rows = $(this).parent("tr").nextUntil("[data-level='1'],[data-level='0']");
}
// if state == - (expanded), then show, otherwise hide
_ = state == "-" ? rows.show() : rows.hide();
});

最新更新