I have created a table in which whenever a user clicks the row it expands its next hidden row. to do that I have used the below script in which the next element of the class row-details
is targeted as a hidden element. The issue here is to use an id or class to target each div inside the row.
If I use normal div elements then the script can use this.nextElementSibling;
to identify the next div element which can be hidden and when the first div is clicked it will expand.
var tableRow = document.getElementsByClassName('row');
for (var i = 0; i < tableRow.length; i ) {
tableRow[i].addEventListener('click', function () {
var tableContent = document.querySelector('.row-details');
if (tableContent.style.maxHeight) {
tableContent.style.maxHeight = null;
} else {
tableContent.style.maxHeight = tableContent.scrollHeight 'px';
}
});
}
In the below code there are 2 rows each with a hidden row containing details. I have used the same class for both hidden rows. What I am trying to achieve is to expand the hidden row without defining any Id or class. min-height
property is not working on tr
tags.
var tableRow = document.getElementsByClassName('row');
for (var i = 0; i < tableRow.length; i ) {
tableRow[i].addEventListener('click', function () {
var tableContent = this.nextElementSibling;
if (tableContent.style.maxHeight) {
tableContent.style.maxHeight = null;
} else {
tableContent.style.maxHeight = tableContent.scrollHeight 'px';
}
});
}
.row-details{
max-height: 0;
overflow: hidden;
transition: all 300ms ease;
}
table {
border-collapse: unset;
}
<table>
<tr>
<th>Date</th>
<th>Data-1</th>
<th>Data-2</th>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
</table>
Changed Code:
const table = document.querySelector('table');
table.addEventListener('click', (e) => {
let header_row = e.target.closest('tr.row');
let details_row = header_row.nextElementSibling;
details_row.classList.add('show');
var tableContent = document.querySelector('tr.show .row-details');
if (tableContent.style.maxHeight) {
tableContent.style.maxHeight = null;
details_row.classList.remove('show');
} else {
tableContent.style.maxHeight = tableContent.scrollHeight 'px';
}
});
.row-details {
max-height: 0;
overflow: hidden;
transition: all 300ms ease;
}
table {
border-collapse: unset;
}
tr.row {
cursor: pointer;
}
<table>
<tr>
<th>Date</th>
<th>Data-1</th>
<th>Data-2</th>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
</table>
CodePudding user response:
Here I just have one event listener for the entire table. When clicked, I find the closest tr.row
and toggle a class name on the nextElementSibling
. With a selector I can then control the <div>
.
If you are using the max-height technique you can just put a max-height that is larger then the content.
const table = document.querySelector('table');
table.addEventListener('click', e => {
let header_row = e.target.closest('tr.row');
let details_row = header_row.nextElementSibling;
details_row.classList.toggle('show');
});
.row-details {
max-height: 0;
overflow: hidden;
transition: all 300ms ease;
}
tr.show .row-details {
max-height: 3em;
}
table {
border-collapse: unset;
}
tr.row {
cursor: pointer;
}
<table>
<tr>
<th>Date</th>
<th>Data-1</th>
<th>Data-2</th>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
<tr >
<td>Lorem</td>
<td>ipsum</td>
<td>dolor sit amet.</td>
</tr>
<tr>
<td colspan="3">
<div >
<span>Lorem, ipsum.</span>
</div>
</td>
</tr>
</table>