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');
}
});
});
Related
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 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'
]
}
);
I am using a Kendo UI grid and for deleting a row I am using a custom button with bootstrap that when I click on it, with ajax I call a web api method to remove that row and if it is successfully deleted that row removes it from the DOM. (I'm not using the command destroy of kendo)
The problem I have is that if I try to filter that row that was removed, it appears again in the grid and it seems that it was not removed at all.
This is my Kendo UI grid:
var table = $("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "/api/customers",
dataType: "json"
}
},
pageSize: 10
},
height: 550,
filterable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [{
template: "<a href='' class='btn-link glyphicon glyphicon-remove js-delete' title='Delete' data-customer-id= #: Id #></a>",
field: "Id",
title: " ",
filterable: false,
sortable: false,
width: 50,
attributes: {
style: "text-align: center"
}
}, {
field: "Name",
title: "Name",
width: 100,
}, {
field: "LastName",
title: "LastName",
width: 100,
}, {
field: "Email",
title: "Email",
width: 150
}]
});
And this is my jQuery code for deleting a row:
$("#grid").on("click", ".js-delete", function () {
var button = $(this);
if (confirm("Are you sure you want to delete this customer?")) {
$.ajax({
url: "/api/customers/" + button.attr("data-customer-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove(); //This part is removing the row but when i filtered it still there.
}
});
}
});
I know that in jQuery DataTables when can do something like this:
table.row(button.parents("tr")).remove().draw();
How can i do something like this with Kendo UI using jQuery?
Don't ever play with a Kendo's widget DOM. Always use it's methods instead.
Using Grid's removeRow():
$("#grid").on("click", "button.remove", function() {
var $tr = $(this).closest("tr"),
grid = $("#grid").data("kendoGrid");
grid.removeRow($tr);
});
Demo
Using DataSource's remove():
$("#grid").on("click", "button.remove", function() {
var $tr = $(this).closest("tr"),
grid = $("#grid").data("kendoGrid"),
dataItem = grid.dataItem($tr);
grid.dataSource.remove(dataItem);
});
Demo
My usage was a little different. I have a custom delete button, so I needed to delete by ID, not UID.
You should be able to match on any field value instead of ID.
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataSource.get(ID);
var row = grid.tbody.find("tr[data-uid='" + dataItem.uid + "']");
grid.removeRow(row);
We were trying to prevent messing with the controller, and this calls the existing delete function.
The removed row will be present in the kendo ui till you push changes to server.
To remove the row entirely you need to use
grid.saveChanges()
So the code below will remove row from server as well from ui
const row = $(e.target).closest('tr')[0];
const grid = $(e.target).closest('#grid').data("kendoGrid");
grid.removeRow(row);
grid.saveChanges() //comment out if you need to remove only from ui
Need to call csv button from my custom button.
<button value="Export report to Excel" class="button-default datatable-csv" type="button" id="ExportReporttoExcel">
<span>Export report to Excel</span>
</button>
Instead of calling it from the Datatable button, i want the same functionality from the above button.
Looking for some configuration changes in Datatable so that i can call my custom button to export the table records as csv.
var table=$('#tableId').DataTable( {
"paging": true,
"info": true,
"searching": true,
,buttons: true
});
$("#SEARCH").on("keyup search input paste cut", function() {
table.search(this.value).draw();
});
var buttons = new $.fn.dataTable.Buttons(table, {
buttons: [
'csvHtml5'
]
}).container().appendTo($('#ExportReporttoExcel'));
Getting output like below but i need only one button.
At last i found the solution.
In Datatable configuration , i added click event for the button to be triggered.
buttons: [
{
extend: 'csv',
}
]
$("#ExportReporttoExcel").on("click", function() {
table.button( '.buttons-csv' ).trigger();
});
This works fine for me thanks for the comments and answers
dataTables export buttons is by default enriched with signature classes like .buttons-excel, .buttons-pdf, .buttons-csv and so on. Take advantage of that :
$('#ExportReporttoExcel').on('click', function() {
$('.buttons-excel').click()
});
Say you have your own button
Export Excel
And you have your table that you are using the below code for;
$(document).ready(function () {
var table = $('#example').DataTable({
"paging": false,
"info": false,
searching: false,
dom: 'Bfrtip',
buttons: [
{
extend: 'excelHtml5'
}
]
});
});
Then all you need to do is to use this code below:
$('#example').DataTable({
"paging": false,
"info": false,
buttons: [
{
extend: 'excel'
},
{
extend: 'csv'
},
]
});
$('.button_export_excel').click(() => {
$('#example').DataTable().buttons(0,0).trigger()
})
The 0,0 points to excel and if you want to point to csv you do 0,1.
If you are trying to trigger the click event of another button and you are using jQuery (according to your tags), you can use
<button onclick="$('#ExportReporttoExcel').click()">Click me</button>
This selects the element with the id "ExportReporttoExcel" and triggers a click with using jQuery.
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/