Get Dynamic Filename and Title for Export button in Datatable - javascript

I am trying to init different tables with single DataTable initialization code block in which I have created Datatable Excel Button to export data. and I got success pretty much. But now challenge is that I am not able to export data with correct file name.
Actually when datatable initialized, Export button is automatically bind with the table do data is being exported correctly but while assigning file name I am trying to get visible Datatable instance by searching by its class. I am able to get correct table when there is only one table in the page. but when there are multiple table on single page then fining visible table does not give correct table. How can I get correct table instance in my JS code so that it works exactly on correct table.
This is how I am trying to get my visible datatable $('.dt-table:visible').data('excel-filename')
Please let me know how can I get more specific table using below code.
JS CODE
var tableObj = $('.dt-table').DataTable({
retrieve: true,
"lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, 'All'] ],
"language": {
"emptyTable": "No data available to show...",
"info": "Showing _START_ to _END_ from _TOTAL_ records",
"infoEmpty": "0 records to show...",
"lengthMenu": "Show _MENU_ records",
"loadingRecords": "Loading...",
"processing": "Processing...",
"zeroRecords": "No matching records found...",
"infoFiltered": "(filtered from _MAX_ total records)"
},
dom: "<'row'<'col-sm-12'B>>" +
"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
buttons: {
buttons: [
{
text: '<i class="far fa-file-excel pr-2"></i> Export to Excel(.xlsx)',
title: function(thead, data, start, end, display) {
return $('.dt-table:visible').data('excel-title');
},
extend: 'excel',
autoFilter: true,
filename: function() {
var d = new Date($.now());
var n = d.getDate()+"_"+(d.getMonth()+1)+"_"+d.getFullYear()+"_"+d.getHours()+"_"+d.getMinutes()+"_"+d.getSeconds();
return $('.dt-table:visible').data('excel-filename') + '_' + n;
},
customize: function(xlsx) {
var sheet = xlsx.xl.worksheets['sheet1.xml'];
$( 'sheets sheet', xlsx.xl['workbook.xml'] ).attr( 'name', $('.dt-table:visible').data('excel-title') );
},
exportOptions: {
//columns: [ 1, 2, 3 ]
format: {
body: function (data, row, column, node) {
if($(node).find(".notExportable").length) {
return $(data).remove(".notExportable").html();
} else {
return data;
}
}
},
columns: ':not(.notExportable)'
}
}
],
dom: {
container: {
tag: "div",
className: "mb-2 mlmt-act dt-buttons"
},
button: {
tag: "a",
className: "btn btn-info mlmt-button"
},
buttonLiner: {
tag: null
}
}
},
drawCallback: function() {
var hasRows = this.api().rows({ filter: 'applied' }).data().length > 0;
var tableId = this.api().tables().nodes().to$().attr('id');
var excelButton = $('a.mlmt-button[aria-controls="'+tableId+'"]');
//alert(tableId);
//alert('.mlmt-button-'+($('.dt-table:visible').attr('id')));
if(hasRows > 0) {
excelButton.removeAttr('style');
} else {
excelButton.css('pointer-events', 'none').css('background-color', 'gray');
}
}
});
HTML CODE
<table class="table table-bordered table-hover table-striped dt-table" id="tblAllLic" data-page-length='10' data-order='[[0, "asc"]]' data-excel-title="All License List" data-excel-filename="All_Licenses">
</table>

Related

Uncaught TypeError: Cannot read property 'style' of undefined using datatable pipeline

I am using Datatable pipeline for generating table. My table has dynamic column means it has no fixed column. The column column number changes with the change of a month. Suppose, during current month the table has 4 column but for november it has 32 columns. When I changes month to november,it gives me Cannot read property 'style' of undefined this error.
My datatable initilization function:
function monthlyAttendanceStatusDatatableInit(tableIdOrCss, url, columns, sortArr, pageLength, year, month) {
console.log(columns);
var param = {
"responsive": false,
// "columnDefs": [
// {responsivePriority: 1, targets: -1},
// {responsivePriority: 2, targets: 0}
// ],
"aLengthMenu": [[10, 20, 50, -1], [10, 20, 50, 'All']],
"pageLength": pageLength || 10,
"iDisplayLength": pageLength || 10,
//"language": { search: "" },
"sPaginationType": "simple_numbers", // you can also give here 'simple','simple_numbers','full','full_numbers'
"oLanguage": {
"sSearch": "Search:",
"sProcessing": "Loading..."
},
"ajax": $.fn.dataTable.pipeline( {
url: url,
data: {
'month': month,
'year': year
},
pages: 2 // number of pages to cache
}),
"processing": true,
"serverSide": true,
"searching": true,
// "bPaginate": true,
// "fnDrawCallback":function(){
// if(typeof callBack == 'function'){
// callBack();
// }
// },
"destroy": true,
"paging": true,
"retrieve": false,
"aoColumns": columns,
"aaSorting": sortArr, //[[ 0, "asc" ],[ 1, "desc" ]] // Sort by first column descending
// "scrollX": true,
// "createdRow": function( row, data, dataIndex ) {
// $(row).attr('id', 'employee-'+data.id);
// }
};
// $(tableIdOrCss).remove();
var table = $(tableIdOrCss).DataTable(param);
return table;
}
I genrating column using server side data.
Columndefinition function:
function getColumnDefinition(year, month) {
var columns = [
{"sTitle": "ID", "mData": "e_id", "bSortable": true},
{"sTitle": "Employee Name", "mData": "employee_name", "bSortable": true},
];
var totalDay = getDayCount(year, month);
var monthS = month.slice(0, 3);
for (var i = 1; i <= totalDay; i++) {
if (i < 10) {
var date = '0' + i.toString();
}else {
var date = i.toString();
}
var dateColumn = {"sTitle": date + "-" + monthS, "mData": date, "bSortable": true};
columns.push(dateColumn);
}
return columns;
}
I am unable to find any solution
As you can see on DataTable documentation for destroy() method, in the case of column change, you should destroy datatable instance and remove all child nodes of the table element with jQuery#empty() call before adding new columns.
var table = $('#myTable').DataTable();
$('#submit').on( 'click', function () {
$.getJSON( 'newTable', null, function ( json ) {
table.destroy();
$('#myTable').empty(); // empty in case the columns change
table = $('#myTable').DataTable( {
columns: json.columns,
data: json.rows
} );
} );
} );
Here it is the working example.

datatable, update footer info totalSize value without redrawing table

I have a datatable that gets called in a function like this:
function createDatatable(){
//get table data
var resp = getTableData()
var dataset = resp.data //table data
var total = resp.total //number like 238
//if table already exists
if (myProductGapsTable) {
myProductGapsTable.clear();
myProductGapsTable.rows.add(dataset); //add new dataset
//myProductGapsTable.language.reload(); //trying to get something like this to work
myProductGapsTable.draw();
} else {
//create table
myProductGapsTable = $('#myProductGapsTable').DataTable({
scrollY: "60vh",
scrollX: true,
scrollCollapse: true,
paging: false,
fixedColumns: true,
"autoWidth": true,
data: dataset,
retrieve: false,
"language": {
"emptyTable": "No table data availiable.",
"info": `Showing _START_ to _END_ of ${total} entries`,
},
"sDom": 'ti',
"paging": false,
"preDrawCallback": function (settings) {
pageScrollPos = $("#myProductGapsTableContainer div.dataTables_scrollBody").scrollTop();
},
"drawCallback": function (settings) {
$("#myProductGapsTableContainer div.dataTables_scrollBody").scrollTop(pageScrollPos);
},
buttons: [
{
extend: 'excelHtml5',
text: 'excel',
exportOptions: { rows: { selected: true, search: 'applied' } }
},
{
extend: 'csvHtml5',
text: 'csv',
exportOptions: { rows: { selected: true, search: 'applied' } }
},
],
select: {
style: 'multi',
selector: 'td:first-child',
search: 'applied'
},
order: [1, 'asc'],
});
}
}
I am trying to have the info field use a custom total number for the info footer, this works fine when the table is first created; it will load the number (238 initially) in the footer correctly. But when I call the function again, if the total number is changed (like now lets say total is 77), the footer info text will not show the updated 'out of 77' text that I would like it to have.
I have an if statement that checks if the table has already been created when the function is called, is there any way I can refresh or reload the table's language field? So I can refresh the table's lower dom info text when the if statement is called?
I don't know of a way to do this using the DataTables API, unfortunately, but here is a jQuery/DOM way:
function changeCountTotal() {
total = resp.total;
var info = $('#myProductGapsTable_info').html();
// Format is assumed to be: "Showing 1 to 10 of 1,234 entries"
var regex = /(Showing.*of ).+?( entries)/;
var updatedinfo = info.replace(regex, "$1" + total + "$2");
$('#example_info').html(updatedinfo);
}
This would need to be called after the redraw peformed by myProductGapsTable.draw();, to ensure the other parameters (_START_, _END_) are correctly re-evaluted by DataTables.
If you want to format the total for thousands separators (or whatever is appropriate for your locale), that would be something like this:
total = resp.total.toLocaleString()
(If there is a way to do this using the DataTables API, that would be a better answer, of course.)

How to show just the N first number of rows on DataTables? How to download all data after this?

I am trying to show only the first N rows of data on DataTables, but can't find a way.
Additionally, when I click the Copy or Excel buttons I want to download all the data, and not just the rows who are being show.
In my last try, I used paging and pageLength without success. Below is the code. My data is on tbldata:
var dtable = $("#dvTableAC").DataTable({
data: tbldata,
columns: [
{ title: "A" },
{ title: "B" },
{ title: "C" },
{ title: "D" }
],
"paging": false,
"pageLength": 50,
dom: 'Blfrtip',
buttons: [
'excel', 'copy'
]
});
Please not that you need an extra plugin to be able to use the buttons (excel, copy).
https://datatables.net/extensions/buttons/built-in
var dtable = $("#dvTableAC").DataTable({
data: tbldata,
columns: [
{ title: "A" },
{ title: "B" },
{ title: "C" },
{ title: "D" }
],
"paging": true,
"pageLenght":10,
dom: 'Blfrtip',
buttons: [
'excel', 'copy'
]
});
Datatables will show all the data you send to it, if you set paging to false, then pageLenght is not used. If you want to limit the total records that datatables show, you must send just those records to it. You can restrict the number on the mysql query using limit 10. But I don't know any method of not having pagination and show only a x amount of rows from the total.

Change DataTable Search Label

Been trying to change the Search: to Filter: in my datatable that I created.
I tried this that i found:
$(document).ready(function() {
oTable = $('#datatable-example_filter').dataTable({
"aaSorting": [[ 10, "desc" ]],
"bJQueryUI": true,
"aLengthMenu": [[25, 50, 100, 250, 500, -1], [25, 50, 100, 250, 500, "All"]],
"sPaginationType": "full_numbers",
"oLanguage": {
"sSearch": "Filter: "
}
});
} );
but it is not working, #datatable-example_filter is the name of the id, inside the div that is generated by dataTable
The other answer that uses "oLanguage" is using legacy DataTables api. According to DataTables v 1.10+ documentation, the syntax is:
$('#example').dataTable( {
"language": {
"search": "Filter records:"
}
} );
very easy, just put this parameter when you call data table function:
"oLanguage": {
"sSearch": "<span>YOUR SEARCH TITLE HERE:</span> _INPUT_" //search
}
Inside the Datatable Javascript (table = $dataTable.DataTable) add the following code:
language: {
'search' : '' /*Empty to remove the label*/
}
I left the search empty because I wanted the info to be in the Placeholder
Ps: If you want to add a placeholder put the following code outside the Datatable initialization
$('.dataTables_filter input').attr("placeholder", "Zoeken...");
I have found this code will change the Search Label ( in my case to "Filter results:" before the DataTable get populated with data.
var dataTable_leSrch = $('#dataTable_leSrch').dataTable({
"oLanguage": {
"sSearch": "Filter results:"
}
});
but when I later populate the DataTable with data the label reverted back to "Search:", so I had to add this code to my DataTable configuration to keep the label changed:
function fillDataTable(res) {
if ($('#dataTable_leSrch').length !== 0) {
$('#dataTable_leSrch').DataTable({
fixedHeader: {
header: true,
headerOffset: $('#header').height()
},
oLanguage: {
"sSearch": "Filter results:"
},
responsive: false,
scrollX: true,
scrollY: 400,
scrollCollapse: true,
select: true,
destroy: true,
aaData: res.data.Results,
...
// Input text box will be appended at the end automatically
$(document).ready( function() {
$('#example').dataTable( {
"oLanguage": {
"sSearch": "Filter records:"
}
} );
} );
// Specify where the filter should appear
$(document).ready( function() {
$('#example').dataTable( {
"oLanguage": {
"sSearch": "Apply filter _INPUT_ to table"
}
} );
} );
for more detail check this link http://legacy.datatables.net/usage/i18n
try this for change label search panel
$('#table_id').DataTable({
"oLanguage": {
"sSearch": "type somthing.. ",
},
});

need help with editable tables in jQuery ( DataTables plugin )

I'm trying to use jQuery and its plugin DataTables ( http://www.datatables.net/release-datatables/examples/api/editable.html ), to make an editable table.
Here's my code so far. The top part of it works great by generating a table inside a DIV with the data from a js array.
Yet I also need this table to be editable. I have found an example code for it ( see bottom part ) but kinda can't figure out how to apply it to my table?
Any ideas? Thanks!
$(document).ready(function() {
$('#dynamic').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"></table>' );
/// create a table within the '#dynamic' DIV
$('#example').dataTable( {
"aaData": numbarr, /////// takes data from the 'numbarr' js array.
"aoColumns": [
{ "sTitle": "Country " }, //// column names
{ "sTitle": "Number " },
{ "sTitle": "Tariff ID " },
{ "sTitle": "Customer Acc " },
{ "sTitle": "Customer Name " },
{ "sTitle": "Payment Terms " },
{ "sTitle": "Payout/Call " },
{ "sTitle": "Payout/Min " },
]
} );
///////////////////////////// the code above workd fine!
////////////////// this code was taken from an example, not sure how to connect it with my table...
$('td', oTable.fnGetNodes()).editable( '../examples_support/editable_ajax.php', {
"callback": function( sValue, y ) {
var aPos = oTable.fnGetPosition( this );
oTable.fnUpdate( sValue, aPos[0], aPos[1] );
},
"submitdata": function ( value, settings ) {
return {
"row_id": this.parentNode.getAttribute('id'),
"column": oTable.fnGetPosition( this )[2]
};
},
"height": "12px"
} );
////////////////// this code was taken from an example, not sure how to connect it with my table...
I've used this plugin http://square-bracket.com/openjs
The example I see states to initialize your table like:
$('#example').dataTable(options).makeEditable(options);
That being said, I haven't gotten it to work yet either.
This is an example that works for me:
$('#tblDataTable2').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"aaSorting": [[ 0, "asc" ]],
"aoColumnDefs": [
{ "sClass": "center", "aTargets": [ 0, 1 ] }
]
}).makeEditable({
sAddURL: "Setting?operation=create",
sUpdateURL: "Setting?operation=update",
"aoColumns": [
{ placeholder: '' },
{ placeholder: '' }
],
});

Categories

Resources