JSFiddle - React, Tailwind, and code Playground
by Denis Tverdokhlebov
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>
...
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;
}
}
}