I am trying to add data based on the parent row to the child row. When I click on expand all, I want to be able to add data to the child based on the parent. When I click on the button all the rows open but the container is only added to the first row with the information of the last row on the current page of the datatable
Here is my example:
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>Full name:</td>'+
'<td>'+d.name+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extension number:</td>'+
'<td>'+d.extn+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extra info:</td>'+
'<td>And any further details here (images etc)...</td>'+
'</tr>'+
'</table>';
}
$(document).ready(function() {
var table = $('#example').DataTable({
'ajax': 'https://gyrocode.github.io/files/jquery-datatables/objects.json',
'columns': [
{
'className': 'details-control',
'orderable': false,
'data': null,
'defaultContent': ''
},
{ 'data': 'name' },
{ 'data': 'position' },
{ 'data': 'office' },
{ 'data': 'salary' }
],
'order': [[1, 'asc']]
} );
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function(){
var tr = $(this).closest('tr');
var row = table.row( tr );
if(row.child.isShown()){
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
// Handle click on "Expand All" button
// Handle click on "Expand All" button
$('#btn-show-all-children').on('click', function(){
let containers, user_name;
table.rows().every(function(){
if(!this.child.isShown()){
$('#example tbody>tr').each(function() {
user_name = $(this).find('.sorting_1').text();
containers = document.createElement('div');
containers.setAttribute('id', `container_${user_name.replace(' ', '_')}`);
$(`#container_${user_name.replace(' ', '_')}`).text(user_name);
});
this.child(containers).show();
$(this.node()).addClass('shown');
}
});
});
// Handle click on "Collapse All" button
$('#btn-hide-all-children').on('click', function(){
// Enumerate all rows
table.rows().every(function(){
// If row has details expanded
if(this.child.isShown()){
// Collapse row details
this.child.hide();
$(this.node()).removeClass('shown');
}
});
});
});
td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_close.png') no-repeat center center;
}
<link rel='stylesheet' type='text/css' href='https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<button id="btn-show-all-children" type="button">Expand All</button>
<button id="btn-hide-all-children" type="button">Collapse All</button>
<hr>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
As you can see, when you click on expand all
. Each of the rows is supposed to have a container with the name in the parent. In the screenshot below you can see Airi Satou
's child div has the name Cedric Kelly
. Why is that happening?
As you have use .each
loop inside your every(..
loop its iterating twices i.e : if every..
loop is getting first row then .each
loop is iterating through whole table(every tr in row) that's why only last value is shown inside div
.
But , here there is no need to use each
loop because you can get that name
value by using this.data()
it will return you JSON Object with all data from your row .So, just use .name
to get name value and then add that value to the generated div using .innerHTML
.
Demo code :
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Full name:</td>' +
'<td>' + d.name + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + d.extn + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extra info:</td>' +
'<td>And any further details here (images etc)...</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function() {
var table = $('#example').DataTable({
'ajax': 'https://gyrocode.github.io/files/jquery-datatables/objects.json',
'columns': [{
'className': 'details-control',
'orderable': false,
'data': null,
'defaultContent': ''
},
{
'data': 'name'
},
{
'data': 'position'
},
{
'data': 'office'
},
{
'data': 'salary'
}
],
'order': [
[1, 'asc']
]
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function() {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
// Handle click on "Expand All" button
// Handle click on "Expand All" button
$('#btn-show-all-children').on('click', function() {
let containers, user_name;
var count = 0;
table.rows().every(function() {
//get data from row this will return values in json object..
var d = this.data();
if (!this.child.isShown()) {
containers = document.createElement('div');
containers.setAttribute('id', `container_${d.name.replace(' ', '_')}`);
containers.innerHTML = d.name;//add value in inside div crated
this.child(containers).show();
$(this.node()).addClass('shown');
}
});
});
// Handle click on "Collapse All" button
$('#btn-hide-all-children').on('click', function() {
// Enumerate all rows
table.rows().every(function() {
// If row has details expanded
if (this.child.isShown()) {
// Collapse row details
this.child.hide();
$(this.node()).removeClass('shown');
}
});
});
});
td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_close.png') no-repeat center center;
}
<link rel='stylesheet' type='text/css' href='https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<button id="btn-show-all-children" type="button">Expand All</button>
<button id="btn-hide-all-children" type="button">Collapse All</button>
<hr>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</tfoot>
</table>