JSFiddle - React, Tailwind, and code Playground
HTML
<button onclick="SwapAll(false);">Свернуть все</button></a>
<button onclick="SwapAll(true);">Развернуть все</button></a>
<br><br>
<table class="treetable">
<thead>
<tr><th>ФИО</th> <th>Проект</th> <th>Задача</th> <th>План</th> <th>Факт</th> </tr>
</thead>
<tr class="lev1"> <td><label><input type="checkbox"><a onclick="sh(this)">Иванов</a></label></td> <td></td> <td></td> <td></td> <td></td> </tr>
<tr class="lev2"> <td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Проект 1</a></label></td> <td></td> <td></td> <td></td> </tr>
<tr class="lev3"> <td></td> <td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Задача 1_1</a></label></td> <td></td> <td></td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>10</td> <td>20</td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>20</td> <td>40</td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>30</td> <td>60</td> </tr>
<tr class="lev3"> <td></td><td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Задача 1_2</a></label></td> <td></td><td></td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>90</td> <td>99</td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>80</td> <td>88</td> </tr>
<tr class="lev2"> <td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Проект 2</a></label></td> <td></td><td></td><td></td> </tr>
<tr class="lev3"> <td></td> <td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Задача 2_1</a></label></td> <td></td> <td></td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>12</td> <td>12</td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>15</td> <td>15</td> </tr>
<tr class="lev3"> <td></td> <td></td> <td><label><input type="checkbox"><a onclick="sh(this)">Задача 2_2</a></label></td> <td></td> <td></td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>22</td> <td>22</td> </tr>
<tr class="lev4"> <td></td> <td></td> <td></td> <td>25</td> <td>25</td> </tr>
<tr...
CSS
.treetable {
border-collapse:collapse;
}
.treetable th {
background:#4682B4;
color:#FFFFFF;
}
.treetable td, th {
padding:3px;
border:1px solid #D3D3D3;
width:200px;
}
.treetable label a{
cursor:pointer;
color:#FFFFFF;
font-weight:bold;
padding-left:16px;
}
.treetable tr {
display:none;
}
.treetable thead tr {
display:table-row;
}
.treetable .lev1 {
background:#6E9ECA;
display:table-row;
}
.lev2 {
background:#708090;
}
.lev3 {
background:#8FA0B0;
}
input[type="checkbox"]{
display:none;
}
input + a {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAIAAAAmzuBxAAAACXBIWXMAAAsSAAALEgHS3X78AAAAkElEQVQYlXWOvRWDQAyDv/DYK2wQSro8OkpGuRFcUjJCRmEE0TldCpsjPy9qzj7Jki62Pgh4vnqbbbEWuN+use/PlArwHccWGg780psENGFY6W4YgxZIAM339WmT3m397YYxxn6aASslFfVotYLTT3NwcuTKlFpNR2sdEak4acdKeafPlE2SZ7sw/1BEtX94AXYTVmyR94mPAAAAAElFTkSuQmCC)
no-repeat 0px 5px;
}
input:checked + a{
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAIAAAAmzuBxAAAACXBIWXMAAAsSAAALEgHS3X78AAAAeklEQVQYlX2PsRGDMAxFX3zeK9mAlHRcupSM4hFUUjJCRpI70VHIJr7D8BtJ977+SQ9Zf7isVG16WSQC0/D0OW/FqoBlDFkIVJ2xAhA8sI/NHbcYiFrPfI0fGklKagDx2F4ltdtaM0J9L3dxcVxi+zv62E+MwPs7c60dClRP6iug7wUAAAAASUVORK5CYII=)
no-repeat 0px 5px;
}
td+td+td+td {text-align:right;}
JavaScript
function ResetAll() {
var cs = document.getElementsByTagName('input');
for (i=0; i < cs.length; i++) {
if (cs[i].type == 'checkbox') {
cs[i].checked = false;
}
}
}
function ShowLevel(row,lv) {
var tBody = row.parentNode;
var i = row.rowIndex;
row = tBody.rows[i]; // Попытка перейти к следующей строке
while (row && row.className.substring(3)*1 > lv) {
if (row.className.substring(3)*1 == lv+1) {
row.style.display = 'table-row';
if ((row.querySelector('td input')) && row.querySelector('td input').checked) {
ShowLevel(row,lv+1);
}
}
i+=1;
row = tBody.rows[i];
}
}
function HideLevel(row,lv) {
var i = row.rowIndex;
var tBody = row.parentNode;
row = tBody.rows[i]; // Попытка перейти к следующей строке
while (row && row.className.substring(3)*1 > lv) {
row.style.display = 'none';
i+=1;
row = tBody.rows[i];
}
}
function sh(el) {
var row = el.parentNode.parentNode.parentNode;
var lv = row.className.substring(3)*1; // Уровень строки, циферка после 'lev'
if (row.querySelector('td input').checked) {
HideLevel(row,lv);
} else {
ShowLevel(row,lv);
}
}
function SwapAll(b) {
var tbl = document.getElementsByClassName('treetable')[0];
for (i=1; i < tbl.rows.length; i++) {
if (tbl.rows[i].className != 'lev1') {
if (b) {tbl.rows[i].style.display = 'table-row';}
else {tbl.rows[i].style.display = 'none';}
}
if (tbl.rows[i].querySelector('td input')) {tbl.rows[i].querySelector('td input').checked = b;}
}
}