I failed to find appropriate implementation, so here is mine. Relies on FontAwesome but can be easily done standalone.
<script>
function* get_child_rows(parent_row) {
let current_row = parent_row
let parent_depth = parseInt(parent_row.dataset.depth)
while((current_row = current_row.nextElementSibling) && parseInt(current_row.dataset.depth) > parent_depth) {
yield current_row
}
}
function toggle_parent_row(toggle_icon) {
let parent_row = toggle_icon.closest('tr')
if(toggle_icon.classList.toggle('fa-caret-down')) {
// expand
let first_level_children_depth = parseInt(parent_row.dataset.depth) + 1
for(let child_row of get_child_rows(parent_row)) {
if(parseInt(child_row.dataset.depth) > first_level_children_depth) {
continue
}
child_row.style.display = ''
}
}
if(toggle_icon.classList.toggle('fa-caret-right')) {
// collapse
for(let child_row of get_child_rows(parent_row)) {
let expanded_child_toggle_icon = child_row.querySelector('i.fa-caret-down')
if(expanded_child_toggle_icon) {
expanded_child_toggle_icon.classList.remove('fa-caret-down')
expanded_child_toggle_icon.classList.add('fa-caret-right')
}
child_row.style.display = 'none'
}
}
}
</script>
<table>
<tr data-depth="0">
<td style="white-space: nowrap">
<i class="fa fa-caret-down fa-fw" onclick="toggle_parent_row(this)"></i>
Node with children
</td>
</tr>
<tr data-depth="1">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-caret-down fa-fw" onclick="toggle_parent_row(this)"></i>
Child
</td>
</tr>
<tr data-depth="2">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
Grandchild
</td>
</tr>
<tr data-depth="1">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
Child 2
</td>
</tr>
<tr data-depth="0">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
Node with no children
</td>
</tr>
</table>
<script>
function* get_child_rows(parent_row) {
let current_row = parent_row
let parent_depth = parseInt(parent_row.dataset.depth)
while((current_row = current_row.nextElementSibling) && parseInt(current_row.dataset.depth) > parent_depth) {
yield current_row
}
}
function toggle_parent_row(toggle_icon) {
let parent_row = toggle_icon.closest('tr')
if(toggle_icon.classList.toggle('fa-caret-down')) {
// expand
let first_level_children_depth = parseInt(parent_row.dataset.depth) + 1
for(let child_row of get_child_rows(parent_row)) {
if(parseInt(child_row.dataset.depth) > first_level_children_depth) {
continue
}
child_row.style.display = ''
}
}
if(toggle_icon.classList.toggle('fa-caret-right')) {
// collapse
for(let child_row of get_child_rows(parent_row)) {
let expanded_child_toggle_icon = child_row.querySelector('i.fa-caret-down')
if(expanded_child_toggle_icon) {
expanded_child_toggle_icon.classList.remove('fa-caret-down')
expanded_child_toggle_icon.classList.add('fa-caret-right')
}
child_row.style.display = 'none'
}
}
}
</script>
<table>
<tr data-depth="0">
<td style="white-space: nowrap">
<i class="fa fa-caret-down fa-fw" onclick="toggle_parent_row(this)"></i>
Node with children
</td>
</tr>
<tr data-depth="1">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-caret-down fa-fw" onclick="toggle_parent_row(this)"></i>
Child
</td>
</tr>
<tr data-depth="2">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
Grandchild
</td>
</tr>
<tr data-depth="1">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
<i class="fa fa-fw"> </i>
Child 2
</td>
</tr>
<tr data-depth="0">
<td style="white-space: nowrap">
<i class="fa fa-fw"> </i>
Node with no children
</td>
</tr>
</table>
Комментариев нет:
Отправить комментарий