Bootstrap 3 - Expanding an Collapsing Nested Table Rows - javascript

I have a web page that uses Bootstrap 3. In this page, I'm trying to show the relationship between grandparent, parent, and child. To do this, I have table rows that can expand/collapse. I've setup a Bootply here. My HTML looks like this:
<div id="grandparent" class="list-group-item">
<div data-toggle="collapse" data-target="#grandparentContent" data-role="expander" data-group-id="grandparent">
<ul class="list-inline">
<li id="grandparentIcon">></li>
<li>Grandparent</li>
</ul>
</div>
<div class="collapse" id="grandparentContent" aria-expanded="true">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Created On</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse">
<td><div>></div></td>
<td>Parent 1</td>
<td>04/02/2017</td>
<td>04/04/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child A</td>
<td>04/01/2017</td>
<td>04/05/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child B</td>
<td>04/03/2017</td>
<td>04/04/2017</td>
</tr>
<tr data-toggle="collapse">
<td><div>></div></td>
<td>Parent 2</td>
<td>04/03/2017</td>
<td>04/10/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child X</td>
<td>04/10/2017</td>
<td>04/11/2017</td>
</tr>
</tbody>
</table>
</div>
</div>
When either a grandparent or parent is expanded, I'm trying to change the related icon from ">" to "v". However, this doesn't work. I don't understand why. Any help is appreciated.

You can do what you are trying to do by adding two things:
A collapsed class that toggles each time a grandparent or parent are clicked, to represent if it is expanded or collapsed.
Add CSS so that when the collapsed class is active it shows ">" and when it is not active (it is expanded) it shows a "v".
Updated Bootply Here
Your main issue is that you were missing data-target for your parent rows, and you also were only changing the grandparent icon with your jQuery.
Key jQuery
$('[data-toggle="collapse"]').on('click', function() {
$(this).toggleClass('collapsed');
});
Key CSS
.collapsed .icon-class:before {
content: '>';
}
.icon-class:before {
content: 'v';
}

Heres a fixed version, change the code to your own liking.
http://www.bootply.com/sCCEzKCLsI#
But essentially the
show.bs.collapse and hide.bs.collapse events are fired from the .collapse and not the the data-toggle="collapse" element.

Also to addition to WilomGfx's answer, you need to assign the data-target to the table rows.
Preview here
HTML
<div id="grandparent" class="list-group-item">
<div id="expander" data-toggle="collapse" data-target="#grandparentContent" data-role="expander" data-group-id="grandparent">
<ul class="list-inline">
<li id="grandparentIcon">></li>
<li>Grandparent</li>
</ul>
</div>
<div class="collapse" id="grandparentContent" aria-expanded="true">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Created On</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#childOne">
<td><div>></div></td>
<td>Parent 1</td>
<td>04/02/2017</td>
<td>04/04/2017</td>
</tr>
<tr class="collapse" id="childOne">
<td></td>
<td>Child A</td>
<td>04/01/2017</td>
<td>04/05/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child B</td>
<td>04/03/2017</td>
<td>04/04/2017</td>
</tr>
<tr data-toggle="collapse" data-target="#childTwo">
<td><div>></div></td>
<td>Parent 2</td>
<td>04/03/2017</td>
<td>04/10/2017</td>
</tr>
<tr class="collapse" id="childTwo">
<td></td>
<td>Child X</td>
<td>04/10/2017</td>
<td>04/11/2017</td>
</tr>
</tbody>
</table>
</div>
</div>
Script
$('.collapse').on('show.bs.collapse', function () {
var groupId = $('#expander').attr('data-group-id');
console.log(groupId);
if (groupId) {
$('#grandparentIcon').html('v');
}
});
$('.collapse').on('hide.bs.collapse', function () {
var groupId = $('#expander').attr('data-group-id');
console.log(groupId);
if (groupId) {
$('#' + groupId + 'Icon').html('>');
}
});

Related

jQuery DataTable multi rows header

I used jQuery DataTable to show some data.
Here is my code.
I tried to add collapse/expand using bootstrap collapse functionality.
So I made two rows.
But if you see console it throws an javascript error so code below it not running.
How can I fix this?
Here is html code:
<table id="taskTable">
<thead class="bg-light text-capitalize">
<tr>
<th>Subject</th>
<th>Name</th>
<th>Duration</th>
<th>User</th>
</tr>
<tr style="display:none;">
<th></th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#demo1">
<td>Subject1</td>
<td>Name1</td>
<td>Duration1</td>
<td>User1</td>
</tr>
<tr id="demo1">
<td>aaa</td>
</tr>
<tr data-toggle="collapse" data-target="#demo2">
<td>Subject2</td>
<td>Name2</td>
<td>Duration2</td>
<td>User2</td>
</tr>
<tr id="demo2">
<td>aaa</td>
</tr>
</tbody>
</table>
Not feeling good using this approach:
Because of search, the sort, etc will break the concept of <tr> as header and it's next <tr> as content.
Maybe you can achieve the same thing using a different approach, like you can have child rows like here. But you can also fix the above problem as below:
JS Fiddle
HTML
<table id="taskTable">
<thead class="bg-light text-capitalize">
<tr>
<th>Subject</th>
<th>Name</th>
<th>Duration</th>
<th>User</th>
</tr>
<tr style="display:none;">
<th colspan="4"></th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#demo1">
<td>Subject1</td>
<td>Name1</td>
<td>Duration1</td>
<td>User1</td>
</tr>
<tr id="demo1">
<td colspan="4">aaa</td>
<td style="display: none;"></td>
<td style="display: none;"></td>
<td style="display: none;"></td>
</tr>
<tr data-toggle="collapse" data-target="#demo2">
<td>Subject2</td>
<td>Name2</td>
<td>Duration2</td>
<td>User2</td>
</tr>
<tr id="demo2">
<td colspan="4">aa2</td>
<td style="display: none;"></td>
<td style="display: none;"></td>
<td style="display: none;"></td>
</tr>
</tbody>
</table>
JS
$("#taskTable").dataTable({
"ordering": false
});

Bootstrap 3 - Expanding and Collapsing Table Rows

I have a table in a web page with Bootstrap. This table has rows that I want to expand/collapse. It is intended to act like a hierarchy. You can see the table in this Bootply. You can see that it successfully expands / collapses the "grandparent" content. However, it doesn't expand/collapse each "parent" element's content as needed.
How do I expand / collapse the child rows in this table? Here is my HTML:
<div class="list-group-item" id="grandparent">
<div id="expander" data-target="#grandparentContent" data-toggle="collapse" data-group-id="grandparent" data-role="expander">
<ul class="list-inline">
<li id="grandparentIcon">></li>
<li>Grandparent</li>
</ul>
</div>
<div class="collapse" id="grandparentContent" aria-expanded="true">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Created On</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse">
<td><div>></div></td>
<td>Parent 1</td>
<td>04/02/2017</td>
<td>04/04/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child A</td>
<td>04/01/2017</td>
<td>04/05/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child B</td>
<td>04/03/2017</td>
<td>04/04/2017</td>
</tr>
<tr data-toggle="collapse">
<td><div>></div></td>
<td>Parent 2</td>
<td>04/03/2017</td>
<td>04/10/2017</td>
</tr>
<tr class="collapse">
<td></td>
<td>Child X</td>
<td>04/10/2017</td>
<td>04/11/2017</td>
</tr>
</tbody>
</table>
</div>
</div>
Here is working example with based on classes Demo
This will show all matched childs.
Demo
You must add the data-target="#collapseContent1" data-toggle="collapse" attributes to Parent 1 and Parent 2 just like you have done it for Grandparent.
And then give the id to target.
<div class="list-group-item" id="grandparent">
<div id="expander" data-target="#grandparentContent" data-toggle="collapse" data-group-id="grandparent" data-role="expander">
<ul class="list-inline">
<li id="grandparentIcon">></li>
<li>Grandparent</li>
</ul>
</div>
<div class="collapse" id="grandparentContent" aria-expanded="true">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Created On</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<tr >
<td data-target="#collapseContent1" data-toggle="collapse" data-group-id="grandparent" data-role="expander"><div>></div></td>
<td>Parent 1</td>
<td>04/02/2017</td>
<td>04/04/2017</td>
</tr>
<tr class="collapse" id="collapseContent1" aria-expanded="true">
<td></td>
<td>Child A</td>
<td>04/01/2017</td>
<td>04/05/2017</td>
</tr>
<tr>
<td data-target="#collapseContent2" data-toggle="collapse" data-group-id="grandparent" data-role="expander"><div>></div></td>
<td>Parent 2</td>
<td>04/03/2017</td>
<td>04/10/2017</td>
</tr>
<tr class="collapse" id="collapseContent2" aria-expanded="true">
<td></td>
<td>Child B</td>
<td>04/03/2017</td>
<td>04/04/2017</td>
</tr>
</tbody>
</table>
</div>
</div>
But you won't get animation for tr elements.
This appears to be a longstanding pre-existing issue with animating tr elements - my recommendation is to not do it. But if you are still looking for a workaround here is a demo that might help:
DEMO

Three Level Accordion - Uncollapse 3rd Level by clicking the 1st level

I created a 3 Level Accordion. It almost works fine... But if the 3rd level is collapsed and i try to uncollapse(?) the 1st level, my 2nd level items will get invisible and my 3rd level items are still visible
Here the code:
<table class="table table-condensed" style="border-collapse:collapse;">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Description</th>
<th>Credit</th>
<th>Debit</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#demo1" class="accordion-toggle">
<td>1</td>
<td>05 May 2013</td>
<td>Credit Account</td>
<td class="text-success">$150.00</td>
<td class="text-error"></td>
<td class="text-success">$150.00</td>
</tr>
<tr data-toggle="collapse" data-target="#demo11" class="accordion-toggle">
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo1"> Demo1 </div> </td>
</tr>
<tr>
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo11"> Demo11 </div> </td>
</tr>
<tr data-toggle="collapse" data-target="#demo2" class="accordion-toggle">
<td>2</td>
<td>05 May 2013</td>
<td>Credit Account</td>
<td class="text-success">$11.00</td>
<td class="text-error"></td>
<td class="text-success">$161.00</td>
</tr>
<tr data-toggle="collapse" data-target="#demo21" class="accordion-toggle">
<td colspan="6" class="hiddenRow"><div id="demo2" class="accordian-body collapse">Demo2</div></td>
</tr>
<tr>
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo21"> Demo21 </div> </td>
</tr>
</tbody>
JSFiddle Example
Would be nice if someone has an idea.
Thank you :)
its because your data-target="#demo1" which is pointed so when u click the target it will check the demo1 id but the second option is outside of the div so it wont close the div so u have to change the structure u have to move the 3 level inside the demo1 id.
<tr data-toggle="collapse" data-target="#demo11" class="accordion-toggle">
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo1"> Demo1 </div> </td>
</tr>
<tr>
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo11"> Demo11 </div> </td>
</tr>
change to
<tr data-toggle="collapse" data-target="#demo11" class="accordion-toggle">
<td colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo1"> Demo1
<div>
<div colspan="6" class="hiddenRow"><div class="accordian-body collapse" id="demo11"> Demo11 tytjtyty</div> </div>
</div>
</div> </td>
</tr>
for refrence https://plnkr.co/edit/S39oZfRWuWf4YiKFRCRE?p=preview

Using JQuery to select all <tr> elements with a specific class

The basic structure is a table with a few rows. I would like the top half of the table showing and the bottom half collapsed until a user clicks on the READ MORE cell. I have that functionality working but I can't get the JQuery right that selects all of the ".collapseThis" rows and hides them on page load.
Here is the table
<div id="tables">
<table class="expandableTable">
<tr>
<td></td>
<td></td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td></td>
<td></td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td></td>
<td></td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td></td>
<td></td>
</tr>
</table>
</div>
Here is the JQuery.
$(document).ready(function () {
function getCollapsable($row) {
var children = [];
while ($row.next().hasClass('collapseThis')) {
children.push($row.next());
$row = $row.next();
}
return children;
}
function hideTableRows($row) {
children = getCollapsable($row);
$.each(children, function () {
$(this).toggle();
});
}
$('#tables').each($('expandableTable'), function () {
hideTableRows($(this).children().hasClass('.accordion'));
});
You can just use css to set the display value, there is no need to use jQuery to set the initial state.
If you want to use jQuery, use a simple selector like $('#tables .expandableTable .collapseThis').hide().
$(document).ready(function() {
//if you don't want to use css
//$('#tables .expandableTable .collapseThis').hide();
});
#tables .expandableTable .collapseThis {
display: none;
}
<div id="tables">
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
</div>

Open page with a pre expanded table row

I have a bootstrap table with expandable rows, what I want is, opening the page with an already expanded row (say first row).
Below is the table I am using.
<table class="table no-padding-table">
<thead>
<tr>
<th>Date</th>
<th>Date2</th>
<th>Date3</th>
</tr>
<tbody>
<tr data-toggle="collapse" data-target="#extend{{$index}}"
ng-repeat-start="date in dates">
<td>
<p>{{date}}</p>
</td>
<td>
<p>{{date}}</p>
</td>
<td>
<p>{{date}}</p>
</td>
</tr>
<tr ng-repeat-end="">
<td colspan="3" class="hiddenRow">
<div class="accordian-body collapse">
TEST
</div>
</td>
</tr>
</tbody>

Categories