JSFiddle - React, Tailwind, and code Playground
by der_robert
HTML
<table>
<thead>
<tr>
<th colspan="2">Row Change</th>
<th>Feld</th>
<th>vorher</th>
<th>nachher</th>
<th>Datum</th>
<th>Nutzer</th>
<th>Aktionen</th> <!-- Neue Spalte -->
</tr>
</thead>
<tbody>
<tr>
<td colspan="5">User Action XYZ</td>
<td>01.01.2000</td>
<td>Admin</td>
<td class="actions">
<button id="show-level-1">L1</button>
<button id="show-level-2">L2</button>
<button id="show-level-3">L3</button>
</td>
</tr>
</tbody>
<tbody class="hidden" data-hide-level="1">
<tr>
<td rowspan="8">Aktualisiert 1</td>
<td rowspan="8">Buchungsoption</td>
<td></td>
<td></td>
<td></td>
<td rowspan="8"></td>
<td rowspan="8"></td>
<td rowspan="8"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 1</td>
<td>vorher 1</td>
<td>nachher 1</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 2</td>
<td>vorher 2</td>
<td>nachher 2</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 3</td>
<td>vorher 3</td>
<td>nachher 3</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 4</td>
<td>vorher 4</td>
<td>nachher 4</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 5</td>
<td>vorher 5</td>
<td>nachher 5</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="3">
<td>Feld 6</td>
<td>vorher 6</td>
<td>nachher 6</td>
<td colspan="2"></td>
</tr>
<tr class="hidden" data-hide-level="2">
<td><strong>Offener Posten</strong></td>
<td><strong>vorher 1</strong></td>
<td><strong>nachher 1</strong></td>
...
CSS
.hidden{
display: none;
}
JavaScript
function toggleTbodyByLevel(level, visible) {
document.querySelectorAll(`tbody[data-hide-level="${level}"]`).forEach(tbody => {
tbody.classList.toggle('hidden', !visible);
const headerTr = [...tbody.querySelectorAll('tr')].find(tr =>
tr.querySelector('td')?.hasAttribute('rowspan')
);
if (headerTr) headerTr.classList.toggle('hidden', !visible);
});
}
function toggleTrByLevel(level, visible) {
const trs = document.querySelectorAll(`tr[data-hide-level="${level}"]`);
trs.forEach(tr => tr.classList.toggle('hidden', !visible));
const tbodySet = new Set([...trs].map(tr => tr.closest('tbody')));
tbodySet.forEach(tbody => {
const anyVisible = [...tbody.querySelectorAll(`tr[data-hide-level="${level}"]`)]
.some(tr => !tr.classList.contains('hidden'));
const headerTr = [...tbody.querySelectorAll('tr')].find(tr =>
tr.querySelector('td')?.hasAttribute('rowspan')
);
if (headerTr) headerTr.classList.toggle('hidden', !anyVisible);
});
}
function isVisible(level) {
const selector = level === 1 ? `tbody[data-hide-level="1"]` : `tr[data-hide-level="${level}"]`;
return [...document.querySelectorAll(selector)].some(el => !el.classList.contains('hidden'));
}
document.getElementById('show-level-1').addEventListener('click', () => {
const l1 = isVisible(1);
const l2 = isVisible(2);
const l3 = isVisible(3);
if (l1 && !l2 && !l3) {
// Nur L1 sichtbar → alles ausblenden
toggleTbodyByLevel(1, false);
} else {
// Sonst → nur L1 sichtbar
toggleTbodyByLevel(1, true);
toggleTrByLevel(2, false);
toggleTrByLevel(3, false);
}
});
document.getElementById('show-level-2').addEventListener('click', () => {
const l1 = isVisible(1);
const l2 = isVisible(2);
const l3 = isVisible(3);
if (l1 && l2 && !l3) {
// L1 + L2 sichtbar → alles ausblenden
toggleTbodyByLevel(1, false);
toggleTrByLevel(2, false);
} else {
//...