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
Related
I want make two rows at my footer datatables. First row of footer for sum columns and second row of footer for search columns.
This is my code in javascript
$(function () {
$('#ntable1 tfoot th').each( function () { //for search columns in footer
var title = $(this).text();
$(this).html( '<input type="text" placeholder="'+title+'"/>' );
} );
var table = $("#ntable1").DataTable({
"responsive": false, "scrollX": true, "lengthChange": true, "autoWidth": false,
"buttons": [
{
extend: 'copy',
exportOptions: {
columns: [':visible' ]
}
},
{
extend: 'excel',
exportOptions: {
columns: [':visible' ]
},
messageBottom: textTop,
},
{
extend: 'print',
footer: true,
exportOptions: {
columns: [':visible' ]
},
messageTop: textTop
},
{
extend: 'colvis',
exportOptions: {
columns: [':visible' ]
}
}
],
footerCallback: function (row, data, start, end, display) { //for sum of columns in footer
var api = this.api();
// Remove the formatting to get integer data for summation
var intVal = function (i) {
return typeof i === 'string' ? i.replace(/[\$,]/g, '') * 1 : typeof i === 'number' ? i : 0;
};
// Total over all pages
total = api
.column(3)
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Total over this page
pageTotal = api
.column(3, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Update footer
$('tr:eq(0) td:eq(3)', api.table().footer()).html(format('$' + pageTotal + ' ( $' + total + ' total)')); //not work
// $(api.column(3).footer()).html('$' + pageTotal + ' ( $' + total + ' total)'); //not work
},
initComplete: function () {
// Apply the search
this.api().columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
}
}).buttons().container().appendTo('#ntable1_wrapper .col-md-6:eq(0)');
});
Datatables code in html
<table id="ntable1" class="table table-bordered table-striped">
<thead> ... </thead>
<tbody> ... </tbody>
<tfoot>
<tr> <!-- for sum columns -->
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr> <!-- for search columns -->
<th>No</th>
<th>Nama Program</th>
<th>Tahun</th>
<th>Jumlah Kota</th>
<th>Nama Kota</th>
<th>Jumlah Sekolah</th>
<th>Jumlah Siswa</th>
<th>Pre Test</th>
<th>Post Test</th>
<th>%</th>
<th>Tingkat Kepuasan</th>
<th>Tabungan Pelajar (Account)</th>
</tr>
</tfoot>
</table>
If I add row in footer, my search column doesn't work. My problem only how to have multiple rows in footer datatables, which first row for calculate sum and second row for search column. Hope anyone can help.
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 created a datatable using jQuery. The table has seven columns , among one column is for Grand Total (column 6). I have to display the sum of Grand Total (column 6) in the Grand Total (column 6) at the bottom of Grand Total (column 6).
How can I do that? I have tried some code but nothing worked.
Outout is blank column.
here is the code that I found.
below is the html code
HTML
<table class="display table table-bordered table-striped" id="dynamic-table">
<thead>
<tr>
<th>Invoice Type</th>
<th>Invoice No</th>
<th>Invoice Date</th>
<th>Customer Name</th>
<th>City </th>
<th>Grand Total</th>
<th class="hidden-phone">Action</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th>Total:</th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
JavaScript
function load_datatable() {
var data = $('input[name=report]:Checked').val();
var date = $('#rep_date').val();
var type = $('#type_id').val();
datatable = $("#dynamic-table").dataTable({
"bAutoWidth": false,
"bFilter": true,
"bSort": true,
"bProcessing": true,
"bDestroy": true,
"bServerSide": true,
"oLanguage": {
"sLengthMenu": "_MENU_",
"sProcessing": "<img src='" + root_domain + "img/loading.gif'/> Loading ...",
"sEmptyTable": "NO DATA ADDED YET !",
},
"aLengthMenu": [
[10, 20, 30, 50],
[10, 20, 30, 50]
],
"iDisplayLength": 10,
"sAjaxSource": root_domain + 'app/invoice/',
"fnServerParams": function(aoData) {
aoData.push({
"name": "mode",
"value": "fetch"
}, {
"name": "report",
"value": data
}, {
"name": "type_id",
"value": type
}, {
"name": "date",
"value": date
});
},
"footerCallback": function(row, data, start, end, display) {
var api = this.api(),
data;
// Remove the formatting to get integer data for summation
var intVal = function(i) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '') * 1 :
typeof i === 'number' ?
i : 0;
};
// Total over this page
pageTotal = api
.column(5, {
page: 'current'
})
.data()
.reduce(function(a, b) {
return intVal(a) + intVal(b);
}, 0);
console.log(pageTotal);
// Update footer
$(api.column(5).footer()).html('$' + pageTotal);
},
"fnDrawCallback": function(oSettings) {
$('.ttip, [data-toggle="tooltip"]').tooltip();
}
}).fnSetFilteringDelay();
//Search input style
$('.dataTables_filter input').addClass('form-control').attr('placeholder', 'Search');
$('.dataTables_length select').addClass('form-control');
}
do this example :
const Table = $('#foo').DataTable({
. . . . . .,
. . . . . .,
drawCallback: function(){
Table.columns(5, {
page: 'current'
}).every(function() {
var sum = this
.data()
.reduce(function(a, b) {
var x = parseFloat(a) || 0;
var y = parseFloat(b) || 0;
return x + y;
}, 0);
console.log(sum);
$(this.footer()).html(sum);
});
}
});
in this case the column was column number 5
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.
I am newbie to DataTable. here I am trying to get the of first cell value of a row when I click the viewlink associated with the row, instead of the value I am getting [object object].
heres my code
$(document).ready(function() {
// Delete a record
$('#example').on('click', 'a.editor_view', function (e) {
e.preventDefault();
var rowIndex = oTable.fnGetPosition( $(this).closest('tr')[0] );
aData = oTable.fnGetData($(this).parents('tr')[0]);
alert(aData);
} );
// DataTables init
var oTable=$('#example').dataTable( {
"sDom": "Tfrtip",
"sAjaxSource": "php/browsers.php",
"aoColumns": [
{ "mData": "browser" },
{ "mData": "engine" },
{ "mData": "platform" },
{ "mData": "grade", "sClass": "center" },
{
"mData": null,
"sClass": "center",
"sDefaultContent": 'view / Delete'
}
]
} );
} );
HTML Table:
<table cellpadding="0" cellspacing="0" border="0" class="display" id="example" width="100%">
<thead>
<tr>
<th width="30%">Browser</th>
<th width="20%">Rendering engine</th>
<th width="20%">Platform(s)</th>
<th width="14%">CSS grade</th>
<th width="16%">Admin</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Browser</th>
<th>Rendering engine</th>
<th>Platform(s)</th>
<th>CSS grade</th>
<th>Admin</th>
</tr>
</tfoot>
Now when I Click on the view I need to Navigate to another page with the id like
view.php?id=125
Thank you
$('#example').on('click', 'a.editor_view', function (e) {
e.preventDefault();
var rowIndex = oTable.fnGetPosition( $(this).closest('tr')[0] );
aData = oTable.fnGetData(rowIndex,0);
alert(aData);
} );
From the api docs:
fnGetData
Input parameters:
{int|node}: A TR row node, TD/TH cell node or an integer. If given as a TR node then the data source for the whole row will be returned. If given as a TD/TH cell node then iCol will be automatically calculated and the data for the cell returned. If given as an integer, then this is treated as the aoData internal data index for the row (see fnGetPosition) and the data for that row used.
{int}: Optional column index that you want the data of.
Assuming your first row is your id, would you want to include the links in your dataTable initializer like this?
$(document).ready(function () {
var oTable = $('#example').dataTable({
"aoColumnDefs": [{
"fnRender": function (oObj) {
var id = oObj.aData[0];
var links = [
'View',
'Delete'];
return links.join(' / ');
},
"sClass": "center",
"aTargets": [4]
}, {
"sClass": "center",
"aTargets": [3]
}]
});
});
see: http://jsfiddle.net/9De6w/