<table id="nested">
<thead><tr><th>123</th><th>456</th><th>789</th></tr></thead>
<tbody>
<tr class="parent"><td>1</td><td>1</td><td>1</td></tr>
<tr class="sub-1"><td>2</td><td>2</td><td>2</td></tr>
<tr class="parent sub-1"><td>2</td><td>2</td><td>2</td></tr>
<tr class="sub-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="sub-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="parent sub-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="sub-3"><td>4</td><td>4</td><td>4</td></tr>
<tr class="sub-2"><td>3</td><td>3</td><td>3</td></tr>
<tr><td>1</td><td>1</td><td>1</td></tr>
<tr class="parent"><td>1</td><td>1</td><td>1</td></tr>
<tr class="sub-1"><td>2</td><td>2</td><td>2</td></tr>
</tbody>
</table>
<br />
<table id="nn">
<thead><tr><th>123</th><th>456</th><th>789</th></tr></thead>
<tbody>
<tr class="pp"><td>1</td><td>1</td><td>1</td></tr>
<tr class="ss-1"><td>2</td><td>2</td><td>2</td></tr>
<tr class="pp ss-1"><td>2</td><td>2</td><td>2</td></tr>
<tr class="ss-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="ss-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="pp ss-2"><td>3</td><td>3</td><td>3</td></tr>
<tr class="ss-3"><td>4</td><td>4</td><td>4</td></tr>
<tr class="ss-2"><td>3</td><td>3</td><td>3</td></tr>
<tr><td>1</td><td>1</td><td>1</td></tr>
<tr class="pp"><td>1</td><td>1</td><td>1</td></tr>
<tr class="ss-1"><td>2</td><td>2</td><td>2</td></tr>
</tbody>
</table>
table {
border: 1px solid black;
border-collapse: collapse
}
th,td {
border: 1px solid black;
}
$(window).on('load',function () {
prepareTableNested('nested','parent','sub');
prepareTableNested('nn','pp','ss');
})
$('tbody').on('click', 'tr', (el) => {tableNested(el,'parent','sub')})
$('tbody').on('click', 'tr', (el) => {tableNested(el,'pp','ss')})
function prepareTableNested (nested,parent,sub) {
$('.'+parent+'').css('cursor','pointer')
$('[class*="'+sub+'"]').hide()
$('#'+nested+' thead tr').prepend('<th></th>').css('border','none')
$('tr.'+parent).css('box-shadow','0 2px 4px rgba(0,0,0,0.35), 0 1px 2px rgba(0,0,0,0.32)')
tr = $('#'+nested+' tbody')
tr.children('tr').not('tr.'+parent).prepend('<td style="border:none"> </td>')
tr.children('tr.'+parent).prepend('<td style="border:none">˅</td>')
}
function tableNested (el,parent,sub) {
el = $(el.currentTarget)
let tf,b,a,c
if (el.hasClass(parent)){
if (el.is('[class*='+sub+'-]')) {
tf = true
b = el.attr('class').split(' ')
b = parseInt($.grep(b,function(e,n){
if(e.includes(sub+'-')){return true}
}).toString().split(sub+'-')[1])
} else {tf = false}
if (el.hasClass('show')) {
el.removeClass('show').children('td:first-child').text(function(index,value){
return value.replace('˄','˅')
})
a = el.next()
while (a.is('tr') && (!a.is('tr[class*='+parent+']') || a.is('tr[class*='+sub+'-]'))) {
if (tf) {
if (a.is('[class*='+sub+'-]')) {
c = a.attr('class').split(' ')
c = parseInt($.grep(c,function (el,n) {
if(el.includes(sub+'-')) {return true}
}).toString().split(sub+'-')[1])
if (c>b) {
if (a.is('[class*='+sub+'-]')) {
a.hide('fast')
if (a.hasClass('show')){
a.removeClass('show')
a.children('td:first-child').text(function(index,value) {
return value.replace('˄','˅')
})}}}}
} else {
if(a.is('[class*='+sub+'-]')) {
a.hide('fast')
if (a.hasClass('show')){
a.removeClass('show')
a.children('td:first-child').text(function(index,value) {
return value.replace('˄','˅')
})}}}
a = a.next()
}
} else {
el.addClass('show').children('td:first-child').text(function(index,value){
return value.replace('˅','˄')
})
a = el.next()
while (a.is('tr') && !a.is('tr[class='+parent+']')) {
if (tf) {
if (a.hasClass(sub+'-'+(b+1))){
a.css('background','rgb('+(210-(b*20))+','+(210)+','+(210-(b*20))+')').show('fast')
}
a = a.next()
} else {
if (a.hasClass(sub+'-1')){a.css('background','rgb(210,210,210)').show('fast')}
a = a.next()
}
}
}
}
}
This Pen doesn't use any external CSS resources.