I would like this demo to work with the filter, not removing entries whose children have the data that you are filtering for.
E.g. in the example if you filter for 5407 Airi Satou does not get deleted and maybe even the child data gets expanded.
HTML and JS
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<div class="slider">'+
'<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>'+
'</div>';
}
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": "/examples/ajax/data/objects.txt",
"columns": [
{
"class": '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
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}
else {
// Open this row
row.child( format(row.data()), 'no-padding' ).show();
tr.addClass('shown');
$('div.slider', row.child()).slideDown();
}
} );
} );
CSS
td.details-control {
background: url('/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('/examples/resources/details_close.png') no-repeat center center;
}
div.slider {
display: none;
}
table.dataTable tbody td.no-padding {
padding: 0;
}
SOLUTION
In order for jQuery DataTables to search child rows you need to add data displayed in the child rows to the main table as hidden columns.
For example, you can add hidden column for extn data property using columns.visible option as shown below:
JavaScript:
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" },
{ "data": "extn", "visible": false }
],
HTML:
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
<th>Extn.</th>
</tr>
</thead>
DEMO
See this jsFiddle for code and demonstration.
Related
I have a Datatable with childrow:
$(document).ready(function () {
var table = $('#example').DataTable({
ajax: 'static/ajax/data/data.json',
columns: [
{
className: 'dt-control',
orderable: false,
data: null,
defaultContent: '',
},
{ data: 'Value1' },
{ data: 'Value2' },
{ data: 'Value3' },
],
order: [[1, 'asc']],
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.dt-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');
}
});
How can I make the child row always open without a performance hit and remove the default green cross? I'm using ajax as a data source.
To create a DataTable with all child data always displayed, you can take the standard approach (for example, using the demo shown here), and then make the following changes:
1 - remove the first (empty) column from the header <th></th> - and also from the footer if needed.
2 - remove the first body column also, as defined in the DataTable itself:
{
className: 'dt-control',
orderable: false,
data: null,
defaultContent: '',
},
The above 2 changes ensure there still the same number of body columns as there are header (and footer) columns.
3 - remove the event listener code (it is no longer needed):
$('#example tbody').on('click', 'td.dt-control', function () { ... });
4 - Add an initComplete section to the DataTable:
initComplete: function( settings, json ) {
this.api().rows().every( function () {
this.child( format(this.data()) ).show();
});
}
The following example shows the above approach, but it uses a small JavaScript-sourced data set instead of Ajax data.
That does not make a difference to the above steps. Just replace my data: dataSet, option with your ajax option.
var dataSet = [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": "2011/04/25",
"office": "Zürich",
"extn": "5421"
},
{
"id": "57",
"name": "Donna Snider",
"position": "Customer Support",
"salary": "$112,000",
"start_date": "2011/01/25",
"office": "New York",
"extn": "4226"
}
];
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<table class="cell-border" 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( {
data: dataSet,
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "salary" }
],
initComplete: function( settings, json ) {
this.api().rows().every( function () {
this.child( format(this.data()) ).show();
});
}
} );
} );
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
</tr>
</thead>
</table>
</div>
</body>
</html>
I am using to Jquery datables to create a table with row details . Everything working fine Only the number of entries
The current logic is counting the parents row + child rows. I want to count only parents rows which are 4. My result should be Showing 1 to 10 of 4 entries.
In my Json file, I have recordsTotal: 16 which is the total rows parents + child. When I change to 4 which is number of parents rows the table will show me only first record (Ticket id 1 + its 3 child rows ) as it's counted as 4 entries.
Any suggestions please how can I update ? Thank you.
$(document).ready(function() {
function format ( d ) {
d.Items.sort(function compare(a,b) {
if (a.Line_No < b.Line_No)
return -1;
if (a.Line_No > b.Line_No)
return 1;
return 0;
});
var x = '<table class="nowrap table table-bordered table-hover" cellspacing="0" width="100%"><thead><tr><th>Line No</th><th>Line Level Issue</th><th>Created Date</th><th>Created By</th></tr></thead><tbody>' ;
$.each(d.Items, function( index, value ) {
x += '<tr><td>' + d.Items[index].Line_No + '</td><td>' + d.Items[index].Line_Level_Issue + '</td><td>' + d.Items[index].Created_Date + '</td><td>' + d.Items[index].Created_By + '</td></tr>';
});
x +='</tbody></table>';
return x;
}
var dt = $('#example').DataTable( {
"processing": true,
"serverSide": true,
"deferRender": true,
"lengthChange": true,
"pageLength": 10,
"language": { "emptyTable": "No matching records found",
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
"zeroRecords": "No matching records found" },
"ajax": "https://api.myjson.com/bins/vwjfc",
"columns": [
{
"class": "details-control",
"data": "Ticket_id"
,render : function(data, type, row) {
return ' ' + data;
}
},
{ "data": "Order_Level_Issue" },
{ "data": "Geo" },
{ "data": "Region" },
{ "data": "Territory" },
{ "data": "Market" },
{ "data": "Country" },
{ "data": "SoldTo_Number" },
{ "data": "SoldTo_Name" },
{ "data": "Order_Numer" }
],
"order": [[0, 'asc'],[1, 'asc']]
} );
var detailRows = [];
$('#example tbody').on( 'click', 'tr td.details-control', function () {
var tr = $(this).closest('tr');
var row = dt.row( tr );
var idx = $.inArray( tr.attr('id'), detailRows );
if ( row.child.isShown() ) {
tr.removeClass( 'details' );
row.child.hide();
detailRows.splice( idx, 1 );
}
else {
tr.addClass( 'details' );
row.child( format( row.data() ) ).show();
if ( idx === -1 ) {
detailRows.push( tr.attr('id') );
}
}
} );
dt.on( 'draw', function () {
$.each( detailRows, function ( i, id ) {
$('#'+id+' td.details-control').trigger( 'click' );
} );
} );
} );
td.details-control {
background: url('https://datatables.net/examples/resources/details_open.png') no-repeat center left;
cursor: pointer;
}
tr.details td.details-control {
background: url('https://datatables.net/examples/resources/details_close.png') no-repeat center left;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css" rel="stylesheet"/>
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet"/>
<table id="example" class="nowrap table table-hover table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>TicketT id</th>
<th>Order Level Issue</th>
<th>Geo</th>
<th>Region</th>
<th>Territory</th>
<th>Market</th>
<th>Country</th>
<th>SoldTo Number</th>
<th>SoldTo Name</th>
<th>Order Numer</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Ticket id</th>
<th>Order Level Issue</th>
<th>Geo</th>
<th>Region</th>
<th>Territory</th>
<th>Market</th>
<th>Country</th>
<th>SoldTo Number</th>
<th>SoldTo Name</th>
<th>Order Numer</th>
</tr>
</tfoot>
</table>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
I assume the problem was not dataTables at all but your ajax call, since you are using serverSide your server side is the one who sends the data the table will display including the total of records so in your ajax response you have:
{draw: 1, recordsTotal: 16, recordsFiltered: 16, data: Array(4)}
So all you have to do is work in your server side script in order the reflect the expected output.
Hope it helps
I get API response in JSON format with nested arrays in it. I want to parse it in nested datatable. I've tried for this, but it won't work. Can anyone let me know where I made a mistake. In JSON I have passenger data & each passenger having multiple drivers, I want to show it in datatable in nested format, like Passenger is parent & respective drivers of it as child.
Expected Result
Here is my JSON response:
/* Formatting function for row details - modify as you need */
function format(driver_data) {
// `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>' + driver_data.employeename + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + driver_data.email + '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
var table = $('.trip_unmacthed').DataTable({
type: "GET",
url: "https://api.myjson.com/bins/13woes",
dataType: "json",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "employeename"
},
{
"data": "email"
}
],
"order": [[1, 'asc']]
});
// Add event listener for opening and closing details
$('.trip_unmacthed 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');
}
});
});
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table class="table table-striped table-bordered table-hover trip_unmacthed">
<thead>
<tr>
<th>User Type</th>
<th> Name</th>
<th>Start Location</th>
<th>Drop Location</th>
<th> Date </th>
<th>Actions</th>
</tr>
</thead>
<tbody id="myData">
</tbody>
</table>
Change the passenger_data to data according to API Docs and your format function.
$(document).ready(function () {
function format(driver_data) {
console.log(driver_data); var b = ''; var i;
for (i = 0; i < driver_data.length; i++) {
b = b + '<tr>' +
'<td></td>' +
'<td>' + driver_data[i].employeename + '</td>' +
'<td>' + driver_data[i].email + '</td>' +
'<td>' + driver_data[i].distance + '</td>' +
'</tr>';
}
return b;
}
var table = $('#example').DataTable({
"ajax": "https://api.myjson.com/bins/y53hs",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "employeename"
},
{
"data": "email"
},
{
"data": "mobilenumber"
}
],
"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
console.log(row.data());
row.child(format(row.data().driver_data)).show();
tr.addClass('shown');
}
});
});
Not sure about what your JSON is . If you have a passenger in your JSON e.g.
{
"passenger_data": [
{
"employeename": "Passenger A",
"email": null,
"driver_data": [
{
"employeename": "Driver A1",
"email": null,
"distance": 0,
},
{
"employeename": "Driver A2",
"email": null,
"distance": 0,
},
],
"mobilenumber": "+12344576",
},
]
}
then you should do it like
"columns": [
{"passenger_data": "employeename"},
{"passenger_data": "driver_data.employeename"},
{"passenger_data": "driver_data.email"}
],
may be your are not using the . operator
I have a html+php page with javascript.
In script I have a table with child row. In child row i vold like to open a modal window, that contain a text from mysql database. BUT the modal do not open, if I put into the child row table. From html link works perfectly.
What can I modify to work.
function format ( d ) {
// `d` is the original data object for the row
return '<div class="slider">'+
'<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<th>Operatőr 2:</th>'+
'<td>'+d.doctor2+'</td>'+
'<td style="width:100px"></td>'+
'<th>Leírás: </th>'+
'<td>'+d.description+'</td>'+
'<td style="width:100px"></td>'+
'<th>TAJ:</th>'+
'<td> '+d.patientid+'</td>'+
'</tr>'+
'</table>'+
'</div>';
$(document).ready(function() {
var table = $('#videos').DataTable( {
"ajax": 'data.php',
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "patient" },
{ "data": "patientid" },
{ "data": "diagnose" },
{ "data": "surgerydate" },
{ "data": "description" },
{ "data": "doctor1" },
{ "data": "uploader", "visible": false }
]
}
});
// Add event listener for opening and closing details
$('#videos 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
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}
else {
// Open this row
row.child( format(row.data()), 'no-padding' ).show();
tr.addClass('shown');
$('div.slider', row.child()).slideDown();
}
});
//Modal description
$('.openPopup').on('click',function(){
var dataURL = $(this).attr('data-href');
$('.modal-body').load(dataURL,function(){
$('#myModal').modal({show:true});
});
});
});
I'm working to add child rows to a data table and am getting a "TypeError: undefined is not a function" for a line of code that works perfectly on a different table and page. Any ideas?
HTML:
<div class="table-responsive">
<h2 class="sub-header">Account Users <span class="glyphicon glyphicon-question-sign"></span></h2>
<table id="users_table" class="table table-striped embedded_table">
<thead>
<tr class="text-center">
<th></th>
<th>User Name</th>
<th>Full Name</th>
<th>User Type</th>
<th>Assigned Device</th>
<th>Date Added</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
Javascript/jQuery:
<script>
function format ( d ) {
var html = '<table id="child_table" class="text-right" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>Email Address:</td>'+
'<td>'+ d.email_address +'</td>'+
'<td>Time Zone:</td>'+
'<td>'+ d.timezone +'</td>'+
'</tr>'+
'<tr>'+
'<td>Create Date:</td>'+
'<td>'+ d.create_date +'</td>'+
'<td>Last Login:</td>'+
'<td>'+ d.last_login +'</td>'+
'</tr>'+
'</table>';
return html;
}
$(document).ready(function() {
username = "<?php echo($_SESSION["username"]); ?>";
userType = "<?php echo($_SESSION["user_type"]); ?>";
var table = $('#users_table').dataTable({
order: [1, 'asc'],
"ajax": {
"url": "/s/user_data.php",
"dataSrc" : ""
},
"language": {
"search": "Search: "
},
"columns": [
{"data": null, "class": "details-control", "orderable": false, "defaultContent": "", "width": "2%"},
{"data": "username", "name": "username", "width": "20%"},
{"data": "fullName", "name": "fullName", "width": "20%"},
{"data": "type", "name": "type", "width": "15%"},
{"data": "cal_color", "name": "cal_color", "width": "15%"},
{"data": "create_date", "type": "date", "name": "create_date", "visible": false},
{"data": "time_zone", "name": "time_zone", "visible": false},
{"data": "last_login", "type": "date", "name": "last_login", "visible": false},
{"data": "email_address", "name": "email_address", "visible": false},
{"data": "uid", "name": "uid", "visible": false}
]
});
// Add event listener for opening and closing details
$('#users_table').find('tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var td = $(this).closest('td');
var row = table.row(tr);
console.log(tr);
console.log(td);
console.log(row);
if(row.child.isShown())
{
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
td.removeClass('shown');
}
else
{
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
td.addClass('shown');
}
});
});
The line of code that generates the error is as follows. It's under the comment "Add event listener for opening and closing details" in the bottom third of the script.
var row = table.row(tr);
Like I said, I'm using the same listener on another table and this line isn't an issue there. I've checked my punctuation multiple times and don't see any missing commas, semicolons, or quotes. You can see that I have 3 lines writing to the console log. Here's what I get if I comment out the offending line:
[tr.even, prevObject: n.fn.init[1], context: td.details-control, jquery: "1.11.0", constructor: function, selector: ""…]
[td.details-control, prevObject: n.fn.init[1], context: td.details-control, jquery: "1.11.0", constructor: function, selector: ""…]
I'm not a strong javascript or jQuery developer. All comments and suggestions are welcome.
Thanks.
I think you should replace
var table = $('#users_table').dataTable({...
by
var table = $('#users_table').DataTable({
The difference? Datable with a capital "D". Otherwise, you can't use the function table.row()
From the manual (https://datatables.net/manual/api), you can see:
It is important to note the difference between $( selector ).DataTable() and $( selector ).dataTable(). The former returns a DataTables API instance, while the latter returns a jQueryJS object. An api() method is added to the jQuery object so you can easily access the API, but the jQuery object can be useful for manipulating the table node, as you would with any other jQuery instance (such as using addClass(), etc.).