Reputation: 51
I need a little help with collapsing and expanding nested rows. Currently my code below expands and collapses as desired at the first level but the subsequent levels also show.
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent()
.parent()
.next('tbody')
.toggleClass('collapsed');
});
});
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody class="collapsed">
<tr>
<td>Level 1</td>
</tr>
<tr>
<td>Level 2</td>
</tr>
</tbody>
</table>
I am trying to achieve that Level 1 expands when "collapseTitle" is clicked and that only when "collapseAccount" is clicked, does Level 2 expand. Now I know that my code should look something like the below, but I am struggling...
<table>
<thead>
<tr>
<td class="collapseTitle">Title</td>
</tr>
</thead>
<tbody>
<tr class="collapsed account">
<td class="collapseAccount">Level 1</td>
</tr>
<tr class="collapsed level">
<td>Level 2</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(e) {
$('.collapseTitle').click(function() {
$(this).parent().parent().next('tbody tr').toggleClass('account');
});
});
$(document).ready(function(e) {
$('.collapseAccount').click(function() {
$(this).next('tr').toggleClass('level');
});
});
</script>
Any help would be greatly appreciated.
Upvotes: 3
Views: 2325
Reputation: 5486
Your jQuery selectors are just a bit off for the toggleClass. You can use the class names of the row to toggle. Also you should create a class to be toggled that displays the row/hides it. For example:
edit:
I now created the titles and rows dynamically to give you a better idea of how this can be done using data-
attributes.
You will have a title td and a row td that match on a data-
attribute, so when you click a title and corresponding tr will be shown. So for example if you click title 1 (with a data-index=1
) then the tr with the attribute data-rowindex=1
will be shown.
$(document).ready(function(e) {
createTable();
$('.collapseTitle').click(function() {
// grab the data-index value from the clicked title
let index = $(this).attr("data-index");
// find a tr that has the attribute data-rowindex and it matches index
$("tr[data-rowindex='" + index + "']").toggleClass("collapsed");
});
});
function createTable(){
// create the titles and the level rows
for(let i = 0; i < 3; i++){
// create the title row
let $trTitle = $('<tr>');
let $tdTitle = $('<td>', {class: "collapseTitle", text: "Title " + i});
$tdTitle.attr("data-index", i);
let $finalTitleRow = $trTitle.append( $tdTitle );
// create the level row
let $trLevel = $('<tr>', {class: "collapsed account"} );
$trLevel.attr("data-rowindex", i);
let $tdLevel = $('<td>', {text: "Level " + i});
let $finalLevelRow = $trLevel.append( $tdLevel );
// add the title and level row pairs to the head and body
$("#myTableHead").append($finalTitleRow[0]);
$("#myTableBody").append($finalLevelRow[0]);
}
}
.collapsed {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead id="myTableHead">
</thead>
<tbody id="myTableBody">
</tbody>
</table>
Upvotes: 1
Reputation: 181
The following code should do it. I hope it helps with what you want to achieve:
account
row when clicking on it (until the next account
row)The only thing you need to do is add the class account
to the higher level rows. You can do this pretty easily when you're displaying these with a loop.
.collapsed {
/* using visibility, since display causes layout issues */
/* due to empty rows rows/columns collapsing */
visibility: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Title1</td>
<td>Title2</td>
</tr>
</thead>
<tbody>
<tr class="account">
<td class="collapsed">Account Summary - Account A</td>
<td class="collapsed">Account Summary - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account A</td>
<td class="collapsed">Account Details Part I - Account A</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part II - Account A</td>
<td class="collapsed">Account Details Part II - Account A</td>
</tr>
<tr class="account">
<td class="collapsed">Account Summary - Account B</td>
<td class="collapsed">Account Summary - Account B</td>
</tr>
<tr class="collapsed">
<td class="collapsed">Account Details Part I - Account B</td>
<td class="collapsed">Account Details Part I - Account B</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(() => {
/* the following handlers expand/collapse the columns */
$('thead > tr > td').each((i, el) => {
$(el).click(() => {
const colIndex = $(el).index() + 1;
const nRows = $('tbody > tr').length;
for (let j = 0; j < nRows; j += 1) {
let cellSelector = `tbody > tr:nth-child(${j+1})`
cellSelector += `> td:nth-child(${colIndex})`;
$(cellSelector).toggleClass('collapsed');
}
})
})
/* the following handlers expand/collapse the account-details rows */
$('tbody > tr.account').each((i, el) => {
$(el).click(() => {
$(el).nextUntil('.account').each((j, ele) => {
$(ele).toggleClass('collapsed');
})
})
})
});
</script>
Upvotes: 2
Reputation: 51
I managed to find the answer I was looking for... Thank you to "stackoverfloweth", Answer To My Question
The snippet of code which has helped me thus far is below,
$('.parent-row').click(function(){
var $element = $(this).next();
while(!$element.hasClass('parent-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });
$('.child-row.has-children').click(function(){
var $element = $(this).next();
while($element.hasClass('child-child-row')){
$element.toggle();
if($element.next().length >0){
$element = $element.next();
}
else{
return;
}
} });
Upvotes: -2