Datatable Print Customization - javascript

My datatable when printed has the date of printing on top. I want to change the format of that date to dd/mm/yy hh:mm. I have used javascript to initialize the title for datatable, but it appears in the header of the printed page as well as above the table. Also, in the footer of the printed page, I want to display my website name. I couldn't find options to manipulate these. Any help would be appreciated. Thank you.
$(document).ready(function() {
var handleDataTableButtons = function() {
if ($("#report").length) {
$("#report").DataTable({
initComplete: function() {
this.api().columns().every(function() {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function() {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
},
dom: "Bfrtip",
buttons: [
{
extend: "excel",
className: "btn-sm"
},
/* {
extend: "pdfHtml5",
className: "btn-sm"
},*/
{
extend: "print",
className: "btn-sm",
message: 'Message',
title: 'Some title',
customize: function(win) {
$(win.document.body).find('table')
.addClass('compact')
.css('font-size', '10pt');
}
},
],
responsive: true
});
}
};
TableManageButtons = function() {
"use strict";
return {
init: function() {
handleDataTableButtons();
}
};
}();
TableManageButtons.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<table id="report">
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>

Related

How can have multirows Footer in Datatables?

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.

AngularJS- TypeError: $element.find(...).each is not a function

I am trying to use datatable in angularJS.
Here is my HTML Code:
<div ng-app="datatable">
<div ng-controller="voucherlistcontroller">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0"
my-table="overrideOptions"
aa-data="voucherList"
ao-column-defs="columnDefs"
fn-row-callback="myCallback" >
<thead>
<tr>
<th>VIN Date</th>
<th>VIN No</th>
<th>Receive Type</th>
<th>Amount</th>
<th>Particulars</th>
<th>Posted</th>
<th>Status</th>
<th>Preview</th>
</tr>
</thead>
<tbody ng-repeat = " vlist in voucherList">
<tr>
<td>{{vlist.vindate}}</td>
<td>{{vlist.vinno}}</td>
<td>{{vlist.receivetype}}</td>
<td>{{vlist.amount}}</td>
<td>{{vlist.particulars}}</td>
<td>{{vlist.posted}}</td>
<td>{{vlist.status}}</td>
<td>{{vlist.preview}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Here is my angularJS code:
var dialogApp = angular.module('datatable', []);
dialogApp.directive('myTable', function() {
return function(scope, element, attrs) {
// apply DataTable options, use defaults if none specified by user
var options = {};
if (attrs.myTable.length > 0) {
options = scope.$eval(attrs.myTable);
} else {
options = {
"bStateSave": true,
"sDom":"lftipr",
"searching": true,
"iCookieDuration": 2419200, /* 1 month */
"bJQueryUI": true,
"bPaginate": true,
"bLengthChange": false,
"bFilter": false,
"bInfo": false,
"bDestroy": true
};
}
// Tell the dataTables plugin what columns to use
// We can either derive them from the dom, or use setup from the controller
var explicitColumns = [];
element.find('th').each(function(index, elem) {
explicitColumns.push($(elem).text());
});
if (explicitColumns.length > 0) {
options["aoColumns"] = explicitColumns;
} else if (attrs.aoColumns) {
options["aoColumns"] = scope.$eval(attrs.aoColumns);
}
// aoColumnDefs is dataTables way of providing fine control over column config
if (attrs.aoColumnDefs) {
options["aoColumnDefs"] = scope.$eval(attrs.aoColumnDefs);
}
if (attrs.fnRowCallback) {
options["fnRowCallback"] = scope.$eval(attrs.fnRowCallback);
}
// apply the plugin
var dataTable = element.dataTable(options);
// watch for any changes to our data, rebuild the DataTable
scope.$watch(attrs.aaData, function(value) {
var val = value || null;
if (val) {
dataTable.fnClearTable();
dataTable.fnAddData(scope.$eval(attrs.aaData));
}
});
};
});
dialogApp.controller("voucherlistcontroller" ,function Ctrl($scope) {
$scope.message = '';
$scope.myCallback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td:eq(2)', nRow).bind('click', function() {
$scope.$apply(function() {
$scope.someClickHandler(aData);
});
});
return nRow;
};
$scope.someClickHandler = function(info) {
$scope.message = 'clicked: '+ info.price;
};
$scope.columnDefs = [
{ "mDataProp": "vindate", "aTargets":[0]},
{ "mDataProp": "vinno", "aTargets":[1] },
{ "mDataProp": "receivetype", "aTargets":[2]},
{ "mDataProp": "amount", "aTargets":[3]},
{ "mDataProp": "particulars", "aTargets":[4]},
{ "mDataProp": "posted", "aTargets":[5]},
{ "mDataProp": "status", "aTargets":[6]},
{ "mDataProp": "preview", "aTargets":[7]}
];
$scope.overrideOptions = {
"bStateSave": true,
"sDom":"lftipr",
"searching": true,
"iCookieDuration": 2419200, /* 1 month */
"bJQueryUI": true,
"bPaginate": true,
"bLengthChange": false,
"bFilter": false,
"bInfo": false,
"bDestroy": true
};
$scope.voucherList = [--some data-];
But It is not considered the element as a function. It shows -TypeError: element.find(...).each is not a function at Object.
But I think I have given all the references on html page. The list of references is given:
JQuery-1.9.0
JQUery-migrate 1.2.1.js
bootstrap.bundle.min.js
jquery-ui.min.js
http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.8.2/jquery.dataTables.min.js
https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js
https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js
How Can I solve this problem? Please Help!!!
Error occurs because element is a dom element not a jQuery object. It will be:
$(element).find('th').each(function(index, elem) {
explicitColumns.push($(elem).text());
});
Instead of:
element.find('th').each(function(index, elem) {
explicitColumns.push($(elem).text());
});

Jquery datatables - How count numbers of rows?

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

How to add index column to datatables

I'm trying to add an index column like this example ( https://datatables.net/examples/api/counter_columns.html ), in my table. I try to implement the code from the example to my program, but the results don't appear. How do I add an index column like the example, to my table ?
thank you
Table :
<table id="order_data">
<thead >
<tr >
<th style="text-align:center;" width="21%">Number</th>
<th style="text-align:center;" width="21%">Datetime </th>
<th style="text-align:center;" width="19%">Temp</th>
<th style="text-align:center;" width="21%">Humidity</th>
</tr>
</thead>
</table>
Javascript :
$(document).ready(function(){
$('.input-daterange').datepicker({
todayBtn:'linked',
format: "yyyy-mm-dd",
autoclose: true
});
fetch_data('no');
function fetch_data(is_date_search, start_date='', end_date='')
{
var dataTable = $('#order_data').DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'print',
title: '<h3 align ="center">Monitoring</h3>',
text: '<i class="fa fa-pencil"></i>',
messageTop: '<p align ="center"><strong>PDF</strong> created by PDFMake with Buttons for DataTables.</p>'
},
{
extend: 'pdfHtml5',
customize: function (doc) {
doc.content[1].table.widths =
Array(doc.content[1].table.body[0].length + 1).join('*').split('');
},
title: 'Monitoring',
titleAttr: 'PDF',
text: 'PDF',
}
],
"columnDefs": [ {
"searchable": false,
"orderable": false,
"targets": 0
} ],
"order": [[ 1, 'asc' ]],
"processing" : true,
"serverSide" : true,
bFilter:false,
"ajax" : {
url:"fetch.php",
type:"POST",
data:{
is_date_search:is_date_search, start_date:start_date, end_date:end_date
},
},
});
}
$('#search').click(function(){
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
if(start_date != '' && end_date !='')
{
$('#order_data').DataTable().destroy();
fetch_data('yes', start_date, end_date);
//$("#tabel").show();
document.getElementById('tabel').style.display = "block";
}
else
{
alert("Both Date is Required");
}
});
dataTable.on( 'order.dt search.dt', function () {
dataTable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
});
The example you're referencing isn't using server side processing. Rather it's assuming a static data source. You have serverSide: true and using an AJAX request to retrieve the data from a source so there are a couple of ways to handle this:
1) Use column render to generate the index value after the data is retrieved:
{
"sName": "Index",
"render": function (data, type, row, meta) {
return meta.row; // This contains the row index
}
}
2.) Add the index value to your data source and retrieve it along with your url:"fetch.php" request. Though this would actually act more like a unique ID and less like row numbering.
There is also an api call for row().index() that you could leverage in a number of ways.

Why my dataTables in bootstrap don't see the data included?

I want to create a dynamic table in bootstrap/jquery, similar to this one
In this example the data is hardcoded, so I thought about changing it with the data that comes from json. Additionally, each row in table has to have a hyperlink added, so my jquery code is as follows:
$('#dataTables-example').DataTable({
responsive: true
});
var data = '[{"number":"1","id":"2","price":"100.70","date":"2015-10-18 03:00:00","hidden":"21"},
{"number":"2","id":"2","price":"88.20","date":"2015-10-18 04:00:00","hidden":"22"}]';
json = JSON.parse(data);
$.each(json, function(i, v) {
$('<tr/>', {
html: [$('<td/>', {
text: v.number
}), $('<td/>', {
text: v.id
}), $('<td/>', {
text: v.price
}), $('<td/>', {
text: v.date
}), $('<td/>', {
html: [
$('<a/>', {
href: '#',
class: 'show-details',
text: 'show details',
data: { id: v.hidden },
click: function() {
var id = $(this).data('id');
console.log(id);
alert(id);
}
})
]
})]
}).appendTo('#dataTables-example tbody')
})
In my html I hardcoded the header of the table:
<div class="panel-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th>number</th>
<th>id</th>
<th>price</th>
<th>date</th>
<th>show details</th>
<th style="display:none;">hidden identifier</th>
</tr>
</thead>
<tbody></tbody>
</table>
and later on thanks to my script I'm appending rows to the table. Simple as that.
However, as you can see in my fiddle:
http://jsfiddle.net/uo8rc5qL/6/
there is a problem, because since the data is not hardcoded, the table thinks there are no rows and displays the specific message there No data available in table. Also, when I click any column name to sort that data - content disappears, since the table thinks there's nothing to display after sorting...
How can I fix this situation?
This is because you're just adding the data to the table, not the underlying datatable source. The solution is to let datatables handle the loading of the data:
$('#dataTables-example').DataTable({
responsive: true,
"data": JSON.parse(datasrc),
"columns": [
{ data: 'number' },
{data: 'id'},
{data: 'price' },
{ data: "date" },
{
"data": "null",
"defaultContent": "<a>click</a>"
},
{ data: "hidden" }
]
});
Working example: JSFIDDLE
Always go through the API! Insert new rows using table.row.add([..]) instead of the jQuery $('<tr>', {... approach :
$.each(json, function(i, v) {
var row = table.row.add([v.number, v.id, v.price, v.date, '<a>show details</a>']);
table.cells({ row: row.index(), column: 4 }).nodes().to$().find('a')
.attr('href', '#')
.addClass('show-details')
.css('cursor', 'pointer')
.data('id', v.hidden)
.on('click', function() {
var id = $(this).data('id');
console.log(id);
alert(id);
})
table.draw();
})
forked fiddle -> http://jsfiddle.net/2wujw71x/1

Categories