Reputation: 793
Im loading row detail information in a bootstrap table via an Ajax call with the id as parameters .
This details show within a collapsible row using a glyph icon button.
However,clicking back on the button to collapse the row end up in distorting the display.
I've been struggling to find a fix to it although the code seems correct.
May you find the jsFiddle here
var parentsData = {
"success": true,
"parents": [{
"id": 1531,
"Firstname": "Austin",
"Surname": "Ana\u00eblle",
"schoolId": "046039",
"schoolName": "ARCAMBAL",
"commune": "ARCAMBAL"
}, {
"id": 2032,
"Firstname": "Ramos",
"Surname": "L\u00e8i",
"schoolId": "046043",
"schoolName": "J CALVET",
"commune": "CAHORS"
}, {
"id": 3036,
"Firstname": "Baker",
"Surname": "Salom\u00e9",
"schoolId": "046043",
"schoolName": "Z LAFAGE",
"commune": "CAHORS"
}, {
"id": 1724,
"Firstname": "Berry",
"Surname": "Marl\u00e8ne",
"schoolId": "046044",
"schoolName": "J CALVET",
"commune": "CAHORS"
}]
};
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
if (!$(this).closest('tr').next('tr').hasClass('expand-child')) {
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
$(".expand-child").slideUp();
var $this = $(this).closest('tr');
var rowId = $(this).data('id');
var newRow = '<tr class="expand-child">' + '<td colspan="12" id="collapse' + rowId +
'">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th >FirstName</th>' +
'<th >School Id</th>' +
'<th >School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function(parentsData) {
if (parentsData.parents) {
var parents = parentsData.parents;
$.each(parents, function(i, parent) {
newRow = newRow + '<tr scope="row">' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune +
'</td>' +
'</tr>';
});
newRow = newRow + '</tbody></table></td></tr>';
}
$(newRow).insertAfter($this);
}
});
} else {
$(this).closest('tr').slideToggle();
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
$detailRow.style.visibility.toggle('table-row collapse');
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<container>
<table class="table table-striped table-hover js-table">
<thead>
<tr>
<th>Training</th>
<th>Title</th>
<th>Date</th>
<th>End date</th>
<th>Description</th>
<th>nb of Applicants</th>
<th>Actions</th>
</tr>
</thead>
<tr data-toggle="collapse" data-target="#collapse4039" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 16/10/2016</td>
<td>16/oct./2016</td>
<td>13/oct./2016</td>
<td>Sequelae of viral hepatitis</td>
<td>15</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/edsa-AgrementEPS/app_dev.php/formation/4039/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse4095" class="clickable">
<td>Activités nautiques</td>
<td> Activités nautiques - 24/10/2016</td>
<td>24/oct./2016</td>
<td>21/oct./2016</td>
<td>Severe pre-eclampsia, third trimester</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group hidden" role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4095 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon " aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Valider les candidats">
<a href="/valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 24/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse3188" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 29/10/2016</td>
<td>29/oct./2016</td>
<td>26/oct./2016</td>
<td>Other secondary chronic gout</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
</table>
</container>
Upvotes: 2
Views: 4905
Reputation: 6766
The main problem is that you attached the ID for collapsing on the wrong element. It should be attached to the tr.expand-child
element and not the .expand-child td
element.
I would build the .expand-child
row in its entirety only once you have an AJAX response.
And it's a good habit to cache elements that you will be re-using.
Here's how I would revise your code:
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
// cache elements
var $btn = $(e.target), $row = $btn.closest('tr'),
// find next immediate .expand-child
$nextRow = $row.next('tr.expand-child');
// toggle button
$btn.toggleClass('glyphicon-eye-close glyphicon-eye-open');
// if .expand-child row exist already, toggle
if ($nextRow.length) {
// show or hide .expand-child row if eye button is open or not, respectively
$nextRow.toggle($btn.hasClass('glyphicon-eye-open'));
// if not, create .expand-child row
} else {
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function (parentsData) {
var newRow = '<tr class="expand-child" id="collapse' + $btn.data('id') + '">' +
'<td colspan="12">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th>FirstName</th>' +
'<th>School Id</th>' +
'<th>School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
if (parentsData.parents) {
$.each(parentsData.parents, function(i, parent) {
newRow += '<tr>' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune + '</td>' +
'</tr>';
});
}
newRow += '</tbody></table></td></tr>';
$row.after(newRow);
}
});
}
});
For demo purposes, I have commented out the AJAX call.
Upvotes: 3
Reputation: 10879
There are several things wrong in your else
block. First of all,
$(this).closest('tr').slideToggle();
is going to slide up your parent row, which is not what you want - you want to hide the child row.
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
hasClass()
will return a boolean, you cannot use it to filter a jQuery collection. What you are trying to do is select the next <tr>
that has the class .expand-child
, like this:
var $detailRow = $(this).closest('tr').next('tr.expand-child');
The next line makes absolutely no sense.
$detailRow.style.visibility.toggle('table-row collapse');
I guess you want to toggle the classes of that row instead:
$detailRow.toggleClass('table-row collapse');
These changes will make the first showing/hiding work. But then there's a problem in your if
block as well:
$(".expand-child").slideUp();
This will select all elements with the class .expand-child
in the DOM. But you'll probably want to only select the child row of the current parent row.
I am, however, not going to debug this whole code for you. I think, I have made some of the main issues clear (see this updated fiddle: https://jsfiddle.net/r7sgL7vy/2/) and you'll hopefully be able to go on from here yourself.
One more tipp: For performance, store jQuery collections that you use more than once in variables instead of querying them every time you need them. You already do this with $detailRow
for example, and with $this = ...
- but it's not used consequently. Why not select and declare all the needed dom elements at the start of the click event handler and then use them everywhere? Besides the performance factor, it also makes your code much cleaner, easier to understand (for you and for others) and easer to spot any mistakes in your logic.
Upvotes: 2