I have a datatable created by the following code
var data = results.rows;
var column_names = results.headers;
if (column_names) {
var columns = [];
var total = 0;
for (var i = 0; i < column_names.length; i++) {
columns[i] = {
'title': column_names[i],
'data': i
}
};
dataTable=$('#report').DataTable( {
columns: columns,
data: data,
paging: false,
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel', 'pdf', 'print'
]
}
);
showTable();
dataTable.columns.adjust().draw();
} else {
alert('No Results Found');
}
I would like to add a footer to the table that contains a sum of the 2nd column and has text that says "Total: "
The table in the html looks like:
<table id="report" class="compact">
</table>
I tried adding a footer in html but it was overwritten when the report is rerun so this needs to be done in the top section of code in order to display every time a table is created.
Thanks in advance:)
I found an example here http://jsbin.com/putiyep/edit?js.
It wont look as pretty as you hoped for but it'll do the job.
It leverages the footerCallback of the API and use the column index of the table and basic math to return your total.
The data table section of the code would look like:
dataTable=$('#report').DataTable( {
columns: columns,
data: data,
paging: false,
dom: 'Bfrtip',
"footerCallback": function (tfoot, data, start, end, display) {
var api = this.api();
var p = api.column(2).data().reduce(function (a, b) {
return a + b;
}, 0)
$(api.column(2).footer()).html("Total: "+p);
},
buttons: [
'copy', 'csv', 'excel', 'pdf', 'print'
]
}
);
Related
i'm using DataTables in a coldfusion project so i want to create a refresh button for my table without using ajax but by using the sent data from my CFC.
$.fn.dataTable.ext.buttons.refresh = {
text: 'Refresh'
, action: function ( e, dt, node, config ) {
dt.clear().draw();
dt.ajax.reload();
}}
var table = $(divname).dataTable({
data: data,
columns: columns,
dom: 'Bfrtip',
buttons: ['refresh'],
"oLanguage": language_datatable,
});
return table;
}
I was unable to utilize the jQuery datatable plugin here:
https://editor.datatables.net/examples/inline-editing/simple
I kept getting an error, so I just dropped it and decided to do it myself.
Starting with the datatable:
$.ajax({
url: 'api/searchVoyageInfo.php',
type: 'POST',
data: '',
dataType: 'html',
success: function(data, textStatus, jqXHR){
var jsonObject = JSON.parse(data);
var table = $('#example1').DataTable({
"data": jsonObject,
"columns": [{
{ "data": "COLUMN1" },
{
"data": "COLUMN2",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$(nTd).html("<a href='#' class='checkBound'>"+oData.COLUMN2+"</a>
<input type='text' class='editbound'
id='editbound' data-uid='"+oData.VOYID+"'
data-editbound='"+oData.COLUMN2+"' value='"+oData.BOUND+"
display: none;' />");
}
},
{ "data": "COLUMN3" },
// few more columns
}],
"iDisplayLength": 50,
"paging": true,
"bDestroy": true,
"autoWidth": true,
"dom": 'Bfrtip',
"buttons": [
// some extend buttons
]
});
},
error: function(// some stuff){
// do some other stuff
// this part is not important
}
});
Within COLUMN2, you should see a class 'checkBound' which is visible when the page loads. There is also an input class 'editbound' which is not visible.
Here is the function that is supposed to hide class 'checkBound' and then display class 'editbound':
$('#example1').on('click', 'tr > td > a.checkBound', function(e)
{
e.preventDefault();
var $dataTable = $('#example1').DataTable();
var tr = $(this).closest('tr');
var data = $dataTable.rows().data();
var rowData = data[tr.index()];
$('.checkBound').hide();
$('.editbound').show();
});
Using the above, when the page is finished loading, the datatable is displayed with no problem.
Upon clicking one of the cells with class 'checkBound' to display the input class 'editbound', the input does display itself, but it also displays every other cell in the column.
Before click:
After click:
As you can see, the first cell in the BOUND column is the cell that was clicked. But when clicked, the rest of the cells were activated. I want to prevent this from happening.
How can I make this work?
This is the way i created a column with a button in it . You should be able to do similar instead of button !
fields: [
{ name: "column_id", title:"View" ,itemTemplate: function(value) {
return $("<button>").text("buttontitle")
.on("click", function() {
//do something
return false;
});
}]
This is how I (somewhat) solved my problem. In the datatable section, I added an ID field called VOYID and included that ID with the class in the href and the input:
"data": "COLUMN2",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$(nTd).html("<a href='#' class='checkBound"+oData.VOYID+"' id='checkBound'>"+oData.COLUMN2+"</a>
<input type='text' class='editbound"+oData.VOYID+"'
id='editbound' data-uid='"+oData.VOYID+"'
data-editbound='"+oData.COLUMN2+"' value='"+oData.BOUND+"
display: none;' />");
}
Then down in the button click section, I utilized the rowData to check for the exact class. This way, when you click the link, only the unique class will open and not all of the cells in the column:
$('#example1').on('click', 'tr > td > a.checkBound', function(e)
{
e.preventDefault();
var $dataTable = $('#example1').DataTable();
var tr = $(this).closest('tr');
var data = $dataTable.rows().data();
var rowData = data[tr.index()];
var voyid = rowData.VOYID;
$('.checkBound'+voyid).hide();
$('.editbound'+voyid).show();
});
Now, when I click on the link, it is only that cell that gets the input activated:
I use the jQuery plugin DataTables to display tables. Then I managed to add the CSV and PDF export features by the Datatables API.
Then I have a form composed of three select options.
When a user selects an item, it shows a table.
If the user selects the second item of the select list, it switches to the second table with the export buttons associated to that second table. That is fine but it remains the export buttons of the first table.
How can I do to show the features of the first table only and hide features of the previous table ?
Here is my code :
$('select[name=tab]').change(function () {
if ($(this).val() == 'tab1') {
$('#table1').show();
$('#table2').hide();
$('#table1').DataTable({
dom: 'Bfrtip',
info : false,
buttons: [
'csv', 'excel', 'pdf'
]
});
}
else if ($(this).val() == 'tab2') {
$('#table1').hide();
$('#table2').show();
$(document).ready(function () {
$('#list-saint-iv').DataTable({
dom: 'Bfrtip',
info : false,
buttons: [
'csv', 'excel', 'pdf'
]
});
});
}
[.....]
Thank you very much !
Have something like this; you'll need to keep 2 table templates. and then destroy
the table not in use during your selection.
$( document ).ready(function() {
var tblTemplateWithoutExport = {
"paging" : false,
"info" : false,
};
var tblTemplateWithExport = {
"paging" : false,
dom: 'Bfrtip',
"info" : false,
buttons: [
'csv', 'excel', 'pdf'
]
};
var tbl1,tbl2;
tbl1 = $('#table1').DataTable(tblTemplateWithoutExport);
tbl2 = $('#table2').DataTable(tblTemplateWithExport);
$( 'select[name=tab]' ).change(function() {
if ($(this).val() == 'tab1') {
tbl2.destroy();
tbl1.destroy();
tbl1 = $('#table1').DataTable(tblTemplateWithoutExport);
}
else if($(this).val() == 'tab2'){
tbl1.destroy();
tbl2.destroy();
tbl2 = $('#table2').DataTable(tblTemplateWithExport);
}
else{
console.log('something other selection');
}
});
});
I don't understand what is wrong with this implementation. Do note that my data is "empty-ish" as I plan on created cells based on their row/col coordinates. So I pass in a dummy array and return the content in the render() callback.
You will notice in the console log it calls createdCell() 100*100 times... The html generated also agrees.
var size = 100
var zeroes = new Uint8Array(size)
var data = _.range(size).map(function() {
return zeroes
})
var cells = 0
var rows = 0
var config = {
autoWidth: false,
paging: false, // Disable Paging
ordering: true, // Sortable columns
info: false, // Disable 'showing x of x entries'
data: data,
deferRender: true,
processing: true,
createdRow: function(cell, data, dataIndex) {
rows += 1
},
columnDefs: [{
targets: _.range(size),
title: 'Title',
render: function(data, type, row, meta) {
return meta.col * meta.row
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex) {
cells += 1
},
}],
}
var dataTable = $('#dashboard-table').DataTable(config)
console.log("Rows: " + rows)
console.log("Cells: " + cells)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/css/jquery.dataTables.min.css" rel="stylesheet"/>
<table className="table table-compressed" id="dashboard-table">
</table>
Here's the fiddle as well:
https://jsfiddle.net/rrauenza/x5nj7qgt/
Why isn't this deferring the cell creation?
Ah, I think I see what is going on. deferRender only works when paging=true in the config and defers the additional page renders.
The Datatables Scroller plugin may be closer to what I expect.
I am using Datatable on one of my project. Issue is that Copy is not working due to some special characters. When I am click to copy button and pasting it to excel it is not showing in correct format. Pls check the example link - https://jsfiddle.net/bhaskarjuly26/ssLbeuqL/3/
In the example, first row has two fields name and position which value has javascript code.
I have also tried below code but not working:
var buttonCommon = {
exportOptions: {
format: {
body: function ( data, column, row ) {
var filterData = data.replace( /</, '<' )
return filterData.replace( />/, '>' );
}
}
}
};
To Clear the Issue I am giving the screenshot
enter image description here
Output should be same in Excel as visible in the screenshot of Step 1
It think this is what you need.
$(document).ready(function() {
var buttonCommon = {
exportOptions: {
format: {
body: function ( data, column, row ) {
var filterData = data.replace( /</g, '<' )
return filterData.replace( />/g, '>' );
}
}
}
};
$('#example').DataTable( {
dom: 'Bfrtip',
buttons: [
$.extend( true, {}, buttonCommon, {
extend: 'copyHtml5'
} ),
$.extend( true, {}, buttonCommon, {
extend: 'excelHtml5'
} ),
$.extend( true, {}, buttonCommon, {
extend: 'pdfHtml5'
} )
]
} );
} );
Check jsfiddle here: https://jsfiddle.net/ssLbeuqL/8/