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.
Related
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.
} );
I have a JSON object like below (dataSource) in that JSON object the property 'viewClasses' sometimes comes as blank, here what I want to do is if 'viewClasses' have any record I want to add a dynamic column to the table and the name of the column header will be the value of 'viewClasses.class', I have tried the below code but it's not working as expected.
Here is the result of the below code -
Here how I want this to be-
var dataSource = [{
"Name": "PI61890",
"portfolioName": "PGIM Emerging Markets Debt Local Currency Fund",
"StartDate": "2020-10-31T00:00:00",
"EndDate": "2020-10-31T00:00:00",
"processDate": "2020-10-31T00:00:00",
"viewDetails": {
"Name": "Management",
"Code": "MGMT",
"category": "Asset",
"description": "Asset Description",
"viewClasses": [{
"class": "A",
"amount": 2000.0
},
{
"class": "B",
"amount": 3000.0
}
]
},
}];
var column = [];
function AddColumn() {
$.each(dataSource[0].viewDetails.viewClasses[0], function(key, value) {
var my_item = {};
my_item.data = key;
my_item.title = key;
column.push(my_item);
});
}
$('#example').dataTable({
data: dataSource[0].viewDetails.viewClasses,
"columns": column,
"paging": false,
"bInfo": false
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<style src="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css"></style>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12">
<table id="example" class="table table-striped" width="100%"></table>
</div>
</div>
</div>
Your source data needs to be iterated in two different ways, to build the two different dynamic arrays which DataTables needs: - column data and row data.
Firstly you have two columns, A and B. To build the array for these, you can use the following:
var dynamicColumns = [];
columnData.forEach(function (columnItem) {
// extract the column definitions:
var dynamicColumn = {};
dynamicColumn['data'] = columnItem['class'];
dynamicColumn['title'] = 'Heading ' + columnItem['class'];
dynamicColumns.push(dynamicColumn);
});
I chose not to use the jQuery iterator because I want access to each object in the array.
This gives me the following structure:
[
{
"data": "A",
"title": "Heading A"
},
{
"data": "B",
"title": "Heading B"
}
]
But for the table's data, I want to end up with only one row of data:
var dynamicRow = {};
columnData.forEach(function (columnItem) {
// extract the data set:
var field = columnItem['class'];
var value = columnItem['amount'];
dynamicRow[field] = value;
});
dynamicRows.push(dynamicRow);
Here, I end up with the following:
[
{
"A": 2000,
"B": 3000
}
]
Now I have the structures I need for my DataTable initialization. The overall script therefore is as follows:
<script type="text/javascript">
var dataSource = [{
"Name": "PI61890",
"portfolioName": "PGIM Emerging Markets Debt Local Currency Fund",
"StartDate": "2020-10-31T00:00:00",
"EndDate": "2020-10-31T00:00:00",
"processDate": "2020-10-31T00:00:00",
"viewDetails": {
"Name": "Management",
"Code": "MGMT",
"category": "Asset",
"description": "Asset Description",
"viewClasses": [{
"class": "A",
"amount": 2000.0
},
{
"class": "B",
"amount": 3000.0
}
]
},
}];
var dynamicColumns = [];
var dynamicRows = [];
function buildDynamicData() {
var columnData = dataSource[0].viewDetails.viewClasses;
var dynamicRow = {};
columnData.forEach(function (columnItem) {
// extract the column definitions:
var dynamicColumn = {};
dynamicColumn['data'] = columnItem['class'];
dynamicColumn['title'] = 'Heading ' + columnItem['class'];
dynamicColumns.push(dynamicColumn);
// extract the data set:
var field = columnItem['class'];
var value = columnItem['amount'];
dynamicRow[field] = value;
});
dynamicRows.push(dynamicRow);
}
buildDynamicData();
console.log(dynamicColumns);
console.log(dynamicRows);
$(document).ready(function() {
$('#example').DataTable({
columns: dynamicColumns,
data: dynamicRows,
paging: false,
info: false
});
} );
</script>
And the end result looks like this (in my test environment):
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 have a html drop down that initially populates and shows the data table. The data is coming from a json array. Once the drop down is changed i'm getting the reinitialise error and having trouble fixing it.
I've tried the table.ajax.reload and also the table.fnReloadAjax(); I work with datatables off an on so not the greatest with them.
Here is the code:
function Population() {
var table = $('#Population').dataTable();
$("#quickStats").change(function () {
var optionValue = $("#quickStats").val();
console.log(optionValue);
if (optionValue == 1) {
$("#display").append('<table cellpadding="0" cellspacing="0" border="0" class="display" id="Population">' +
'<thead><tr><th>Demographic</th><th>Total</th></thead>'
+ '</table>');
$('#Population').dataTable({
"data": usPopulation,
"bJQueryUI":true,
"columns": [
{ "data": "Demographic" },
{ "data": "Total" }
],
});
}
table.ajax.reload();
});
}
Try destroying the previous one before creating new:
$('#Population').dataTable().fnDestroy();
$('#Population').dataTable({
"data": usPopulation,
"bJQueryUI":true,
"columns": [
{ "data": "Demographic" },
{ "data": "Total" }
],
});
or do like this:
var table = $('#Population').dataTable({
"data": usPopulation,
"bJQueryUI":true,
"columns": [
{ "data": "Demographic" },
{ "data": "Total" }
],
});
table.draw();