I have a datatable that is being populated with data from ajax->mysql database. After it is populated I use various datatables tools like "rowsGroup", "searchColumns" etc to make the table look better.
Is there any way I can then get the table body as a tbody element with td's and tr's and append it to a variable?
My problem is that I have the datatable looking as I want it when it is initialized in javsscript (with the filters and plugins etc applied) but I have no way of exporting it like that.
My question is, how can I export it to a variable looking exactly how it is so that I can save it somewhere and re-use it elsewhere on the page or project.
===TABLE INIT===
let table;
const getTableBody = async (crop) => {
table = $('#pests_js_table').DataTable({
"pageLength": 50,
"processing": true,
"ajax": {
"url": '/assets/ajax/table_ajax_handler.php',
"type": "POST",
"data": {
action: "getPestsForTable"
}
},
"rowsGroup": [
],
"columns": [{
"data": "crop"
},
{
"data": "weeds"
},
{
"data": "chemical"
},
{
"data": "product"
},
{
"data": "rate"
},
{
"data": "max_no"
},
{
"data": "hi"
},
{
"data": "mrl"
},
{
"data": "pcs_no"
},
{
"data": "supplier"
},
{
"data": "use_by_date"
}
],
"searchCols": [{
"search": String(crop) || null
}],
"columnDefs": [{
"targets": [0],
"visible": false,
"searchable": true
},
{
"targets": [1],
"visible": true,
"searchable": true
}
],
"order": [
[2, "asc"]
],
"rowsGroup": [
1, 2, 4, 5, 6, 7, 9
]
});
return table.outerHTML;
}
const exportPdf = async () => {
let crops = <?=json_encode($crops)?>;
//console.log(crops);
// crops.map(async crop => {
// let tableBody = await getTableBody(crop);
// console.log(tableBody);
// });
let tableBody = await getTableBody('v7xn82Ff3XQFYwCl');
console.log(tableBody);
}
For a more complex requirement like the one you have, you are going to need to combine DataTables capabilities with some extra logic (JavaScript, in this case) to iterate over the set of tables you need.
So, the following example is not a complete solution - it just shows how to create one copy of your original table, with an applied filter. But this could be extended to loop over each of your continents, one-by-one.
The code creates a variable called tableCopy which contains a clone of the original table. You can then use tableCopy.outerHTML to get the full HTML of the copied table.
$(document).ready(function() {
let table = $('#example').DataTable( {
// my test data is sourced from a JavaScript variable, not from ajax:
data: dataSet,
// my custom code will not work if deferRender is true:
"deferRender": false,
// for testing, provide pre-filtered data:
"search": {
"search": "ni"
},
columns: [
{ title: "ID", data: "id" },
{ title: "Name", data: "name" },
{ title: "Office", data: "office" },
{ title: "Position", data: "position" },
{ title: "Start date", data: "start_date" },
{ title: "Extn.", data: "extn" },
{ title: "Salary", data: "salary" }
]
} );
let tableCopy = document.getElementById("example").cloneNode(true);
tableCopy.id = 'my_copy'; // the cloned table needs a unique ID
//remove the (incomplete) set of <tr> nodes in the <tbody> node, since they
// only account for the initially displayed set of rows (one page of data):
$('tbody', tableCopy).empty();
// we will not select any rows which have been filtered out (and are therefore hidden):
let rowsSelector = { order: 'current', page: 'all', search: 'applied' };
// build a complete set of <tr> nodes using the DataTables API:
table.rows( rowsSelector ).every( function ( rowIdx, tableLoop, rowLoop ) {
$('tbody', tableCopy).append( this.node() );
} );
//console.log( tableCopy.outerHTML );
$('#displayTarget').html( tableCopy.outerHTML );
// redraw the main table to re-display the removed <tr> nodes:
table.draw( false );
} );
In your case, you would need to extend this approach to handle multiple copies of the table.
I have not tested the following - but this shows the approach:
You would need an array of values to hold the copies:
let tableCopies = [];
contients.forEach(function (item, index) {
tableCopies.push(document.getElementById("example").cloneNode(true));
tableCopies[index].id = 'table_' + item; // e.g.: 'table_Europe'
});
You would need to extend this section:
table.rows( rowsSelector ).every( function ( rowIdx, tableLoop, rowLoop ) {
$('tbody', tableCopy).append( this.node() );
} );
Instead of using the filtered data from the original table, you would loop through every row - and you would not use the rowsSelector:
table.rows().every( ... )
In the body of that function, you would check which continent is in the current row:
table.rows( rowsSelector ).every( function ( rowIdx, tableLoop, rowLoop ) {
let continent = this.data().continent;
// and add the relevant continent row to the related object in the `tableCopies` array.
} );
Related
I have datatable with defined column values from let's say hardcoded JSON object( jsonData ).
var jsonData = [{
"name": ["first", "second", "third", "fourth",...},
"name": ["foo", "bar", ...
}]
$(document).ready(function() {
var my_table = $('#dataTable').DataTable({
"data": jsonData,
"columns": [{
"data": "name"
},
I want to update columns to slice first 3 elements of array:
"columns": [{
"data": "name",
"render": function(data, type, row, meta) {
return data.slice(0, NUM_OF_SLICES) + ...
}
I want these "..." to have onclick event that will show full data,
by default it is only first 3 elements.
I have a function that involves fetching data via ajax and making a table and returning said table. I also have a function that gets triggered when a button is clicked. I have names this function with async and hoped that when i called the function to get the table, it would wait for it to finish (I have used await) then the rest of the code would follow. But instead the console logs the table with no data in it (because it needs time for the data to be fetched), instead console logs the empty table right away.
The trigger function
const exportPdf = async () => { //Called from a button
let tableBody = await getTableBody('v7xn82Ff3XQFYwCl');
console.log(tableBody);
}
The function that returns the table
const getTableBody = async (crop) => {
table = $('#pests_js_table').DataTable({
"pageLength": 50,
"processing": true,
"ajax": {
"url": '/assets/ajax/table_ajax_handler.php',
"type": "POST",
"data": {
action: "getPestsForTable"
}
},
"rowsGroup": [
],
"columns": [{
"data": "crop"
},
{
"data": "pests"
},
{
"data": "chemical"
},
{
"data": "product"
},
{
"data": "rate"
},
{
"data": "max_no"
},
{
"data": "hi"
},
{
"data": "mrl"
},
{
"data": "pcs_no"
},
{
"data": "supplier"
},
{
"data": "use_by_date"
}
],
"columnDefs": [{
"targets": [0],
"visible": false,
"searchable": true
},
{
"targets": [1],
"visible": true,
"searchable": true
}
],
"order": [
[2, "asc"]
],
"rowsGroup": [
1, 2, 4, 5, 6, 7, 9
]
});
let tableBody = $('#pests_js_table').html();
table.destroy();
return tableBody;
}
Your getTableBody function returns a string immediately since it's not awaiting anything. So if the result of calling DataTable isn't awaitable you need to return a Promise and call resolve when you actually have a value to return, like:
const getTableBody = async crop => {
return new Promise((resolve, reject) => {
const table = $('#pests_js_table').DataTable({
ajax: {
success: resp => {
resolve($('#pests_js_table').html()) // <-- call resolve when ready
table.destroy()
},
... // etc.
},
... // etc.
})
})
}
I have a simple code to pull data using ajax in my datatable:
$(document).ready(function() {
$('#datatable').dataTable( {
"pageLength": 50,
"ajax": "/test/pull/",
"columnDefs": [ {
"targets": 6,
"data": null,
"defaultContent": "<button type=\"button\" class=\"btn btn-success btn-sm\" onclick>Click</button>"
} ],
"columns": [
{ "data": "a" },
{ "data": "b" },
{ "data": "c" },
{ "data": "d" },
{ "data": "r" },
{ "data": "f" }
]
} );
I am pulling from server one more column - g and I would like to add this value as a new attribute ( for example ID ) to a button named "Click".
Was trying to find anything in google but unsuccessfully - will be thankful for your support
Thanks in advance,
How do I multiply Data in Datatables ?
I have Datatables and javascript that look like this:
$('#xxdata').DataTable( {
"destroy": true,
"processing": true,
"ajax": {
url : "xxreport.php",
type : 'GET',
data : {
datedari : SplitRange[0].trim(),
datesampai : SplitRange[1].trim()
}
},
"columns": [
{ "data": "offerName" },
{ "data": "offerCountry" },
{ "data": "visits" },
{ "data": "conversions" },
{ "data": "profit"}
]
} );
I want to multiply data in { "data": "profit"} maybe like
this { "data": "profit" * 0.7}
Can I change data in datatables as I want? Or can anyone give other solutions?
Thank You.
You can use the columns.render option (documented here) to do this.
"columns": [
{ "data": "offerName" },
{ "data": "offerCountry" },
{ "data": "visits" },
{ "data": "conversions" },
{ "data": "profit",
"render": function (data) {
return data * 0.7;
}
}
]
In this case, data in the function signature represents the data for the cell. There are other options that can be passed into the function, but in your case these do not need to be included since this is such a simple operation. See the documentation link if you ever want to expand to a more complicated rendering function
You must add a render to your column, something like this:
{ "data": "profit", "render": renderMyProfit}
and you should have the rendering function declared before you call the .DataTable() function.
var renderMyProfit = function (data, type, row, meta) {
var renderContent = "<div>*</div>";
return renderContent.replace("*", row.profit * 0.7);
};
I want to implement function in which data will be loaded into datatable after onChange event. So for that I am trying to implement code as below.
var viewdatatab = $('#dataTablesFeedback').dataTable({
"columns": [
{ "data": "resourceId" },
{ "data": "feedbackRecommendation" },
{ "data": "technicalSkillGaps" },
{ "data": "technicalAvgSkills" },
{ "data": "feedbackType" },
{ "data": "feedbackId" },
{ "data": "isNew" },
]
});
Which is creating my datatable layout and I am calling below function on dropdown change event is :
function loadFeedback(){
viewdatatabJS = $('#dataTablesFeedback').dataTable({
"processing" : true,
"retrieve" : true,
"ajax" : "/nhp/rest/feedback/viewFeedback",
"fnServerParams": function ( aoData ) {
aoData.push( { "name": "userName", "value":employeeId } ,
{ "name": "resourceId", "value":mentorDataJson[$('#dropDownId').val()].resourceId });
},
});
}
Where I am passing some parameter in aoData.push but my URL is not getting called.
I Solved the issue by simply implementing datatable properties. i wrote my code of datatable
var viewdatatab = $('#dataTablesFeedback').dataTable({
"columns": [
{ "data": "resourceId" },
{ "data": "feedbackRecommendation" },
{ "data": "technicalSkillGaps" },
{ "data": "technicalAvgSkills" },
{ "data": "feedbackType" },
{ "data": "feedbackId" },
{ "data": "isNew" },
]
});
in jsp document.ready(function()) and then on my request call of drop down change event i wrote below code on my javascript function.
$.ajax({
url : "",
type: 'GET',
contentType: "application/json",
data: {
'userName': value,
'resourceId' : value,
},
success: function(data) {
var table = $('#dataTablesFeedback').DataTable();
table.clear();
table.rows.add(data.data);
table.draw();
});
this way i first clear my datatable and then redraw it using my json which i got from my ajax call.
Thanks