DataTables export to csv with format Syntax error - datatables

I have datatables and I try to export it to CSV. The column 7 is a date.
text: 'Csv',
extend: 'csvHtml5',
filename: "customers",
exportOptions: {
columns: [1, 2, 7,8],
format: {
body: function (data, row, column, node) {
//check if type is input using jquery
console.log(data)
return $(data).is("input") ? $(data).val() : data;
}
}
}
It works all OK if I don't use "format" but with format I have error:
Uncaught Error: Syntax error, unrecognized expression: 13/11/2021
When I log "data" without format, it is all OK. It looks like the slashes in date make problems in "format".
Any help:)
edit:
the date I take from firestore
let options = {
year: 'numeric',
month: '2-digit',
day: 'numeric',
//hour: 'numeric',
// minute: 'numeric'
// second: 'numeric'
};
dataSet.push([
...
oc.data().created ? doc.data().created.toDate().toLocaleDateString("en-GB", options) : "",
...

This is caused by your jQuery $(data) selector when the data variable contains one or more forward slashes. See:
Selector with string space and /; $(" /") throws uncaught error in jquery
Why is the slash character causing my selector to fail?
And probably others.
A simple (but potentially error-prone) approach would be to write some logic like this:
// possible, but not recommended:
data.startsWith('<input') ? $(data).val() : data
Instead of this type of approach, you can use DataTables' support for orthogonal data.
In this new approach we will target the column which contains <input> fields, and specify two different versions of these data values for that column:
The version we want to display in the table (i.e. the actual input HTML).
The version we want to export (i.e. the value contained in the input field).
To do this we have to specify this for the relevant column (or columns). In my test example, this is the second column - so col index 1:
columnDefs: [
{
targets: [1],
render: function (data, type, row) {
return type === 'export' ? $(data).val() : data;
}
}
]
Here, I have specified that there will be a custom data type called export for the 2nd column - and its value will be the result of $(data).val() - and all other built-in orthogonal data types (display, sort, filter) will just use the raw data value.
Now I can use this new orthogonal data type in my export section of the DataTable:
exportOptions: {
columns: [0, 1, 4, 5],
orthogonal: 'export'
}
The overall solution using my test data is as follows:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.23/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css"/>
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.5/css/buttons.dataTables.min.css"/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.colVis.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.html5.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.print.min.js"></script>
</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>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td><input type="text" value="System Architect"></td>
<td>Edinburgh</td>
<td>61</td>
<td>13/11/2021</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td><input type="text" value="Accountant"></td>
<td>Tokyo</td>
<td>63</td>
<td>14/12/2021</td>
<td>$170,750</td>
</tr>
<tr>
<td>Donna Snider</td>
<td><input type="text" value="Dev/Ops"></td>
<td>New York</td>
<td>27</td>
<td>15/01/2022</td>
<td>$112,000</td>
</tr>
</tbody>
</table>
</div>
<script>
$(document).ready(function() {
var table = $('#example').DataTable( {
columnDefs: [
{
targets: [1],
render: function (data, type, row) {
return type === 'export' ? $(data).val() : data;
}
}
],
dom: 'Brftip',
buttons: [ {
text: 'Csv',
extend: 'csvHtml5',
name: 'testExport',
exportOptions: {
columns: [0, 1, 4, 5],
orthogonal: 'export'
}
} ]
} );
} );
</script>
</body>
</html>
The table looks like this:
And the exported CSV data is:
"Name","Position","Start date","Salary"
"Donna Snider","Dev/Ops","15/01/2022","$112,000"
"Garrett Winters","Accountant","14/12/2021","$170,750"
"Tiger Nixon","System Architect","13/11/2021","$320,800"
The benefit: I do not need any potentially error-prone logic to detect whether my strings contain / characters, or begin with <input... and so on.

Related

how to sort in a bootstrap3 DataTable using derived value from column?

I am using a DataTable in a bootstrap app and it is working great.
You can see the app running at (for example):
https://opencalaccess.org/calaccess/filingdate/2022-11-09
But. I have:
<script>
$(document).ready(function () {
$('#filings').DataTable(
{
"columns": [
{"name": "Filing ID", "orderable": true},
{"name": "Filer ID", "orderable": true},
{"name": "Filer Name", "orderable": true},
{"name": "Filer Type", "orderable": true},
{"name": "Period", "orderable": true},
{"name": "Form", "orderable": true},
{"name": "Amounts", "orderable": false},
{"name": "Rpt Covers", "orderable": false}
]
}
);
});
</script>
And, like I said, it works great. But I want to sort of the Amounts column also.
But the Amounts column is actually put together from several possible values. I would like to sort on the sum of those values, but I do not need to display the sum of those values.
So, say I have two rows:
<tr>
<td>col1</td>
<td>
thing1: 100,
thing2: 100,
thing3: 200
<div style="visibility: hidden;">sum: 400</div>
</td>
</tr>
<tr>
<td>col1</td>
<td>
thing1: 100,
thing2: 1000
<div style="visibility: hidden;">sum: 1100</div>
</td>
</tr>
I would like to have the standard sort buttons on the column, but I want them to sort on the sum value in each row.
Possible?
I see things to try that might work but they all seem very awkward and ugly.
FYI, the versions of the libraries that I am using are:
https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
Is this relevant?
In DataTable, how to sort a column by partial value?
Is jquery DataTable the same as the bootstrap DataTable?
What ended up working. The cell contents are:
This is a bit tricky to test. The cell now looks like:
<td style = "white-space: nowrap;">
<div style="visibility: hidden;">5898748</div>
debt-amt_incur: $38,001.00<br/>
debt-amt_paid: $4,824.00<br/>
expn-amount: $271,681.00<br/>
rcpt-amount: $234,479.00<br/>
smry-amount_a: $3,662,227.00<br/>
smry-amount_b: $1,362,306.00<br/>
splt-elec_amount: $325,230.00<br/>
</td>
and the final js is:
{"name": "Amounts",
"render": function(data, type, row, meta) {
if (type === 'display' || type === 'filter') {
return data;
}
else { // type is 'sort' in this case:
return Number($.parseHTML(data)[0].innerHTML);
}
}
},
Here is an example approach using a column render function and orthogonal data.
It uses similar table data to the data provided in the question.
$(document).ready(function() {
$('#filings').DataTable({
columns: [{
name: "Col One",
},
{
name: "Col Two",
render: function(data, type, row, meta) {        
if (type === 'display' || type === 'filter') {
return data;        
} 
else { // type is 'sort' in this case:       
let sum = Number($.parseHTML(data)[1].innerHTML.split(':')[1]);            
return sum;
}    
}
}
]
});
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/dataTables.bootstrap.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.13.1/js/dataTables.bootstrap.js"></script>
</head>
<body>
<div style="margin: 20px;">
<table id="filings" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Col One</th>
<th>Col Two</th>
</tr>
</thead>
<tbody>
<tr>
<td>col1b</td>
<td>
thing1: 100, thing2: 200, thing3: 200
<div style="visibility: hidden;">sum: 500</div>
</td>
</tr>
<tr>
<td>col1a</td>
<td>
thing1: 100, thing2: 1000
<div style="visibility: hidden;">sum: 1100</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
The demo uses this:
let sum = Number($.parseHTML(data)[1].innerHTML.split(':')[1]);
to extract the sum value from each hidden <div>. It's just for demo purposes, to show you the approach. I am sure there are more robust approaches. And this only works for the very specific sample data provided in the question.
Reference: parseHTML

Jquery Datatables plugin. How to read the HTML Column Heading value

I am using the JQuery Datatables plugin (https://datatables.net/).
I would like to be able to reference the original HTML <th></th> column header values.
<table border="0">
<thead>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
</thead>
<tbody>
<tr>
<td>data for column 1</td>
<td>data for column 2</td>
<td>data for column 3</td>
</tr>
</tbody>
</table>
I know that columns can be named within the plugin using the columns property:
$('#mytable').DataTable(
{
columns: [
{name: 'column1'},
{name: 'column2'},
{name: 'column3'}
]
}
)
However it would be very useful when dealing with dynamically created HTML to be able to reference the HTML <th> tag in order to find the Datatables index for the column with a specific name.
I have had a look at dataTable.context[0].aoHeader and can see both and idx and innerHTML objets within that, however it looks like table().header() might provide a solution.
You can use the column.name values shown in the question to select the DataTables column index values.
Example:
table.column( 'column2:name' ).index()
Demo:
$(document).ready(function() {
var table = $('#mytable').DataTable(
{
columns: [
{ name: 'column1' },
{ name: 'column2' },
{ name: 'column3' }
]
}
)
let idx = table.column( 'column2:name' ).index();
console.log( idx ); // prints 1 (2nd column's index)
} );
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/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="mytable" class="display dataTable cell-border" style="width:100%">
<thead>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
</thead>
<tbody>
<tr>
<td>data for column 1</td>
<td>data for column 2</td>
<td>data for column 3</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
This uses the column() API function, together with a column selector.
There are various different ways you can provide a column selector - one of which is the way I show in the above code:
'YOUR_COL_NAME_HERE:name'
Then the index() function returns the zero-based column index.
If you have draggable columns (i.e. columns can be reordered) then you may also need to add a selector modifier to account for that, depending on what specific index you want - the original one, or the currently displayed one.

Get value of hidden column in DataTable

Once a button is selected on my page I need to iterate through a DataTable, find the row with the radio button that's selected and then get the value from a hidden column on that row. I've tried just about everything but my hidden columns aren't accessible, only my 3 visible columns. My code example has several of the options I've tried to I apologize if it's a little messy. This is my first time posting so please don't get mad if I've messed something up here. I've seen the .fnGetData option but it's listed as "legacy" so I'd rather not use it (???).
Table Setup:
var thisurl = '#Url.Action("Addresses", new { AddUID = "000" })';
thisurl = thisurl.replace("000", #ViewBag.AddUID);
$('##ViewBag.TblID').dataTable({
"columnDefs": [
{
"targets": [0, 1],
"visible" : false
}
],
"searching": false,
"info": false,
"paging": false,
"order": [1, "desc"],
"ajax": {
"type": "POST",
"url": thisurl,
"contentType": 'application/json; charset=utf-8',
"data": function (data) { return data = JSON.stringify(data); }
},
"columns": [
{ "data": "Adrs_UID" },
{ "data": "revision_id" },
{
"render": function (data, type, row) {
var url = '#Html.RadioButton("000", "select", false, htmlAttributes: new { #id = "111", onclick = "ResetRadioBtns()" })';
url = url.replace("000", '#ViewBag.ChkID').replace("111", '#ViewBag.ChkID');
return url;
}
},
{
"render": function (data, type, row) {
return row.Adrs_One + ' ' + row.Adrs_City + ' ' + row.Adrs_St + ' ' + row.Adrs_Zip;
}
},
{
"render": function (data, type, row) {
var text = 'Print';
var target = '_blank';
var link = '../DocGen/DocGen_AB.aspx?AUID=' + row.Adrs_UID + '&REV=' + row.revision_id;
return '' + text + '';
}
}
]
});
Script
$('.btnAPL_DTV').click(function (e) {
var table = $('#tblAPLAddress_DTV').DataTable();
table.rows().every(function (value, index) {
node = table.row(value).node();
var check = $(node).find("input[id$='chbxAPLAdSelect_DTV']");
var data1 = $('#tblAPLAddress_DTV').DataTable().row(this).data();
data = data1[0];
if (check.prop("checked") == true) {
// Get Rev_Id & Adrs_UID from Hiddent Field
var allData = table.row(index).data();
var revData = allData[0].data();
adrsUID = node.data()[0];
revId = node.data()[1];
}
});
});
UPDATE 08-13-2021
Andrew - Here the script code and my results from yesterday using your example (including using the index value so you can see what I did yesterday):
$("#tblAPLAddress_DTV").on("click", ":radio", function () {
var table = $('#tblAPLAddress_DTV').DataTable();
var rowNode = $(this).parent().parent()[0];
console.log("Result using .Adrs_UID: " + table.row(rowNode).data().Adrs_UID);
console.log("Result using Index Value: " + table.row(rowNode).data()[0]);
});
And here are my results displayed in the console:
Result using .Adrs_UID: undefined
Result using Index Value: <input id="chbxAPLAdSelect_DTV" name="chbxAPLAdSelect_DTV" onclick="ResetRadioBtns()" type="radio" value="select">
I'm not sure which HTML you're referring to. Here's my HTML table set-up. #ViewBag.TblID = "tblAPLAddress_DTV":
<div class="row">
<div class="col-md-offset-1">
<table id=#ViewBag.TblID class="table text-nowrap" style="padding-top:1em">
<thead>
<tr>
<th>Address UID</th>
<th>RevisionID</th>
<th></th>
<th>Address</th>
<th>Address Block</th>
</tr>
</thead>
</table>
</div>
</div>
And I don't think this matters but I apologize if it does. My table HTML set-up and table definition script above are in a Partial View.
Here's the Html call in the Index View to call the PartialView:
#{ Html.RenderAction("_Addresses", "DocGeneration", new { id = "tblAPLAddress_DTV", chkId = "chbxAPLAdSelect_DTV", AddUID = ViewBag.AddUID });}
Hope this gives you the info you need.
UPDATE 2
Updated script:
$("#tblAPLAddress_DTV").on("click", ":radio", function () {
var table = $('#tblAPLAddress_DTV').DataTable();
var rowNode = $(this).parent().parent()[0];
console.log(rowNode);
});
Console results - I didn't drill down too far.
<tr role="row" class="odd">
<td class="sorting_1">
<input id="chbxAPLAdSelect_DTV" name="chbxAPLAdSelect_DTV" onclick="ResetRadioBtns()" type="radio" value="select">
</td>
<td>17647 157TH STREET BONNER SPRINGS XX 66000</td>
<td>Print</td>
</tr>
These console results are the same as the HTML getting generated.
Thank you!
I have taken a simplified version of your table and code to show one possible approach:
$(document).ready(function() {
var table = $('#example').DataTable( {
"columnDefs": [
{
"targets": [0, 1],
"visible" : false
}
]
} );
$( "#example" ).on( "click", ":radio", function() {
var rowNode = $( this ).parent().parent()[0];
console.log( table.row(rowNode).data()[0] );
});
} );
<!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 in Country</th>
<th>Age</th>
<th>Start date</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td><input type="radio"></td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td><input type="radio"></td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior "Technical" Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td><input type="radio"></td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>London</td>
<td>22</td>
<td>2012/03/29</td>
<td><input type="radio"></td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Milan</td>
<td>33</td>
<td>2008/11/28</td>
<td><input type="radio"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
(In my case, the radio buttons are not cleared after each click, because I did not add that logic.)
How this works:
I use a delegated event handler:
$( "#example" ).on( "click", ":radio", function() { ... }
This allows events to be attached to radio buttons which may not initially be drawn - for example, if they are not on page 1 of the DataTable's paginated data.
I extract the row node (the <tr> element) using jQuery:
var rowNode = $( this ).parent().parent()[0];
In my case, the row node is the grandparent (.parent().parent()) of the radio button. Your case may be slightly different. I don't know what your final rendered HTML structure is.
In my case, each row of data is stored as an array of values (not as an object), so I can use the following to access the first hidden value:
table.row(rowNode).data()[0]
Note that the table variable was already defined as part of the DataTable declaration.
If your row data is provided as objects { ... } instead of arrays [ ... ], you will need to adjust your code accordingly.
You can log table.row(rowNode).data() to the console to see for yourself. You haven't shown us your JSON data, but it looks as if you would need to access the named values, such as adrsUID - so probably this:
table.row(rowNode).data().adrsUID

Is there a way to hide a DataTables column based on its type?

I have this code currently:
drawCallback: function () {
let api = this.api();
// hide columns that add up to 0
api.columns().every(function (i) {
let sum = this.data().sum();
if (sum === 0 && typeof sum === 'number' && i !== 0) {
api.column(i).visible(0);
}
});
}
There is an issue with it, however... for one particular column where the values are just a single word, such as "Completed" or "Pending", it seems as though this.data().sum(); will result in 0 rather than NaN.
The first two columns will result in NaN, seemingly because they are multi-word sentences, which is the only difference between these two columns.
This is a sample of the data
<td>Foo Bar Jones Jonesy McFoo Department</td>
<td>ABC CityName Location Code XXFOO</td>
<td data-sort="20201002">10/02/2020</td>
<td>Pending</td>
<td>(a variable number of columns with data that is some number that is possibly zero or greater)</td>
Isn't there some way to check the column type with api.columns().every()?
I am not able to recreate your specific error with single-word cell values vs. multi-word cell values. When I use parseFloat('x') vs. parseFloat('x y z'), they both evaluate to NaN.
(Also, I don't know how you implemented your sum() function, so that may explain what you are seeing.)
I am going to use the following example from here, as a starting point for my sum() - but with a modification:
$.fn.dataTable.Api.register( 'column().data().sum()', function () {
return this.reduce( function (a, b) {
var x = parseFloat( a ); // removed the 'or' operator: || 0;
var y = parseFloat( b ); // removed the 'or' operator: || 0;
return x + y;
} );
} );
My change (removing the "or" operators) ensures NaN values are not set to zero, but remain as NaN - which is what you need for your specialized sum() function.
Now, if I use this with your DataTable code, and some test data based on what you provided, I get the expected outcome:
As a side note, dates may be parsed into numbers OK, depending on the data format - which can explain why date columns can show up OK (they sum to a positive number).
Here is the full standalone demo, in case it helps.
In this example, all the data in the final column ("Val 3") are zeros - so that column is hidden. The column remains hidden if there are non-zero values which sum up to zero, also:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.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>Dept</th>
<th>Loc</th>
<th>Date</th>
<th>Status</th>
<th>Val 1</th>
<th>Val 2</th>
<th>Val 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Foo Bar Jones Jonesy McFoo Department 1</td>
<td>ABC CityName Location Code XXFOO</td>
<td data-sort="20200119">19/01/2020</td>
<td>Active</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>Foo Bar Jones Jonesy McFoo Department 2</td>
<td>DEF CityName Location Code XXFOO</td>
<td data-sort="20201002">10/02/2020</td>
<td>Pending</td>
<td>0</td>
<td>2</td>
<td>0</td>
</tr>
<tr>
<td>Foo Bar Jones Jonesy McFoo Department 3</td>
<td>XYZ CityName Location Code XXFOO</td>
<td data-sort="20201016">16/02/2020</td>
<td>Pending</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
$.fn.dataTable.Api.register( 'column().data().sum()', function () {
return this.reduce( function (a, b) {
var x = parseFloat( a );
var y = parseFloat( b );
return x + y;
} );
} );
$(document).ready(function() {
var table = $('#example').DataTable( {
drawCallback: function () {
let api = this.api();
// hide columns that add up to 0
api.columns().every(function (i) {
let sum = this.data().sum();
if (sum === 0 && typeof sum === 'number' && i !== 0) {
api.column(i).visible(0);
}
});
}
} );
} );
</script>
</body>
</html>

Unable to see dataTables tableTools menu "CSV, Excel, PDF, PRINT"?

I'm working on a project of Fees Management System for my elder brother's school project by using bootstrap 3, php, mysql.
I'm using bootstrap's plugin dataTables and unable to see the dataTables tableTools menu with dataTables. I downloaded tableTools from github and include all necessary files in dashboard page but tableTools is not working for me. Anyone can help me?
I include these files in my student-dashboard.php's head section :-
<!-- DataTables CSS -->
<link href="../bower_components/datatables-plugins/integration/bootstrap/3/dataTables.bootstrap.css" rel="stylesheet">
 
<!-- DataTables tableTools CSS -->
<link rel="stylesheet" type="text/css" href="../bower_components/datatables-plugins/TableTools/css/dataTables.tableTools.css">
 
<!-- DataTables Responsive CSS -->
<link href="../bower_components/datatables-responsive/css/dataTables.responsive.css" rel="stylesheet">
 
<!-- DataTables tableTools JS -->
<script type="text/javascript" language="javascript" src="../bower_components/datatables-plugins/TableTools/js/dataTables.tableTools.js"></script>
And here are the codes for dataTables :
<div class="dataTable_wrapper row">
<div class="col-lg-12 table-responsive">
<table class="table table-striped table-bordered table-hover" id="dataTables-view">
<thead>
<tr>
<th>ID</th>
<th>Roll Number</th>
<th>Student Name</th>
<th>Class</th>
<th>Fee Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$sql = mysql_query("SELECT * FROM student_info ORDER BY student_roll_number");
while($row = mysql_fetch_array($sql)){
$id = $row["student_id"];
$rollnumber = $row["student_roll_number"];
$fname = $row["student_fname"];
$lname = $row["student_lname"];
$class = $row["student_class"];
echo '
<tr>
<td> '.$id.'</td>
<td> '.$rollnumber.'</td>
<td> '.$fname.' '.$lname.'</td>
<td><i class="icon-group"></i> '.$class.'</td>
<td><center>Pending</center></td>
<td><center>
<div class="btn-group text-center">
<i class="fa fa-eye fa-1x"></i>
<i class="fa fa-edit fa-1x"></i>
<i class="fa fa-trash-o fa-1x"></i>
</div></center>
</td>
</tr>
';
}
?>
</tbody>
</table>
</div>
</div>
And in end of the page i used following codes for initializing dataTables:
<script>
$(document).ready(function() {
$('#dataTables-view').DataTable({
responsive: true,
"order": [ 0, "desc" ],
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
"searchable": false
}
],
"lengthMenu": [ [7, 20, 50, -1], [7, 20, 50, "All"] ],
"dom": 'T<"clear">lfrtip',
"tableTools": {
"sSwfPath": "/swf/copy_csv_xls_pdf.swf"
}
});
});
</script>
The final output is this : In this picture, You can see there is no dataTables tableTools menu showing...
but i need this kind of output for my student dashboard page.
Anyone can help me to sort out this issue...?
If only print and Copy button works, then there should be problem in .swf file. Make sure the path of the file is correct
After clicking the buttons (except print and copy), See whether you are getting any error in the console. If the path of the file is wrong, you will get error in the console.