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);
};
Related
I've a datatable which i fill with ajax response. In the response i'm getting a string date data. I can write that data on datatable but i can't filter the data with date range. I've try so much way but i can't solve this. some of my trying i get " fnDraw()" is not function or some error like this. how can I make the range filter ?
JavaScrıpt code :
$(document).ready(function () {
var table = $.ajax({
type: "GET",
url: '/History/GetCallbackHistory',
data: { UserId: document.getElementById("callbackuserid").value },
dataType: 'json',
success: function (obj, textstatus) {
$('#callback_table').DataTable({
"pagingType": "input",
"language":
{
"processing": "<div class='loader'>Loading...</div>",
"paginate": {
"previous": "",
"next": ""
},
},
dom: "<'row'<'container-c'pi<'permuheader'<'refresh-button'>><'tlength'l>>>"
+ "<'row'>"
+ "<'row'<'col-sm-12't>r>",
data: obj,
columns: [
{
"data": "Id"
},
{
"data": "DateCallback"
},
{
"data": "callbackId"
},
{
"data": "Task_name"
},
{
"data": "callbackStatus"
},
{
"data": "Point"
},
{
"data": "TransactionType"
},
{
"data": "DateEnd"
}
]
});
},
error: function (obj, textstatus) {
alert(obj.msg);
}
});
$("#datepicker_from").datepicker({
showOn: "button",
buttonImageOnly: false,
"onSelect": function (date) {
minDateFilter = new Date(date).getTime();
table.fnDraw();
}
}).keyup(function () {
minDateFilter = new Date(this.value).getTime();
table.fnDraw();
});
$("#datepicker_to").datepicker({
showOn: "button",
buttonImageOnly: false,
"onSelect": function (date) {
maxDateFilter = new Date(date).getTime();
table.fnDraw();
}
}).keyup(function () {
maxDateFilter = new Date(this.value).getTime();
table.fnDraw();
});
});
$.fn.dataTableExt.afnFiltering.push(
function (oSettings, aData, iDataIndex) {
if (typeof aData._date == 'undefined') {
aData._date = new Date(aData[1]).getTime();
}
if (minDateFilter && !isNaN(minDateFilter)) {
if (aData._date < minDateFilter) {
return false;
}
}
if (maxDateFilter && !isNaN(maxDateFilter)) {
if (aData._date > maxDateFilter) {
return false;
}
}
return true;
}
);
When you use jQuery's ajax like this:
var table = $.ajax({ ... });
You are assigning the jQuery object to your table variable. You are not assigning the DataTable from the success function to the table variable.
This is why, when you try to use table.fnDraw(), you get that specific error: Your table is not a DataTable. The ajax call is asynchronous - it does not return anything from the success call in the normal flow of your code.
Instead, the simplest alternative that I would recommend is to re-arrange your code to use DataTables' built-in support for ajax.
In this new approach we do not need to use the jQuery ajax function at all - so we completely remove that from the code. Instead, we do this:
var table = $('#callback_table').DataTable({
"ajax": {
"method": "GET",
"url": "/History/GetCallbackHistory",
"data": {
UserId: document.getElementById("callbackuserid").value
},
"dataType": "json",
"dataSrc": ""
},
"pagingType": "input",
"language": {
"processing": "<div class='loader'>Loading...</div>",
"paginate": {
"previous": "",
"next": ""
},
},
"dom": "<'row'<'container-c'pi<'permuheader'<'refresh-button'>><'tlength'l>>>" +
"<'row'>" +
"<'row'<'col-sm-12't>r>",
"columns": [{
"data": "Id"
},
{
"data": "DateCallback"
},
{
"data": "callbackId"
},
{
"data": "Task_name"
},
{
"data": "callbackStatus"
},
{
"data": "Point"
},
{
"data": "TransactionType"
},
{
"data": "DateEnd"
}
]
});
The main point to note is the ajax section:
"ajax": {
"method": "GET",
"url": "/History/GetCallbackHistory",
"data": {
UserId: document.getElementById("callbackuserid").value
},
"dataType": "json",
"dataSrc": ""
},
This is a wrapper around the jQuery ajax function. But it also uses a DataTables extension to jQuery's ajax: the dataSrc option. This option replaces your old data: obj option. It tells DataTables that your JSON response is a plain array.
Once you have done this, then your table variable will contain a valid DataTables object - and you can now use table.fnDraw();. But it would be better to use the modern name for this function: table.draw();.
If you have filtering problems, after that, you can refer to the official date range filtering example DataTables date range filter, to make sure your approach matches the example's approach (but using your preferred datepicker controls).
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 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,
I'm using ASP.net MVC on the server side. Basically I have a model class, I normally JsonConvert.SerializeObject(DataTableModel) and send it back to datatables.js. After the conversion the json data looks like the following;
"{
"draw":1,
"recordsTotal":2,
"recordsFiltered":2,
"data":[
{"PONumber":"PO 1234","SupplierNumber":"SUP 123","SupplierName":"Supplier 1","ProductDescription":"SUND Salt & Pep Grinder 6/210g","POQuantity":"6","POUOM":"12","BatchQuantity":"18","BatchUOM":"24","ShelfDate":"2016/02/24","ExpireDate":"2016/03/15","CreatedDate":"2016/02/23","CreatedBy":"HORIZON.COM\\mohammadi","POReceiveDate":"2016/02/20","Notes":"Note 1"},
{"PONumber":"PO 1236","SupplierNumber":"SUP 124","SupplierName":"Supplier 2","ProductDescription":"365 Cinnamon Strick Whol 6/36g*","POQuantity":"6","POUOM":"12","BatchQuantity":"18","BatchUOM":"24","ShelfDate":"2016/02/25","ExpireDate":"2016/03/31","CreatedDate":"2016/02/23","CreatedBy":"HORIZON.COM\\mohammadi","POReceiveDate":"2016/02/25","Notes":"Note 2"}
]
}"
It gets the data alright. But if I don't convert it to in jquery.dataTables.js >> _fnBuildAjax.baseAjax >> success into the following (between line 9 - 15) it doesn't show data; gets an error can't find lenght of undefined, which I get.
var baseAjax = {
"data": data,
"success": function (json) {
var error = json.error || json.sError;
if ( error ) {
_fnLog( oSettings, 0, error );
}
var x = JSON.parse(json);
oSettings.json = x;
callback(x);
//oSettings.json = json;
//callback( json );
},
"dataType": "json",
"cache": false,
"type": oSettings.sServerMethod,
"error": function (xhr, error, thrown) {
var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
if ( $.inArray( true, ret ) === -1 ) {
if ( error == "parsererror" ) {
_fnLog( oSettings, 0, 'Invalid JSON response', 1 );
}
else if ( xhr.readyState === 4 ) {
_fnLog( oSettings, 0, 'Ajax error', 7 );
}
}
_fnProcessingDisplay( oSettings, false );
}
};
Following are my js code binding with datatables.
var table = $('#example').DataTable({
"processing": true,
"serverSide": false,
"ajax": {
"url": "/Home/GetDateLogData",
"type": "POST"
},
"columns": [
{ "data": "PONumber" },
{ "data": "SupplierNumber" },
{ "data": "SupplierName" },
{ "data": "ProductDescription" },
{ "data": "POQuantity" },
{ "data": "POUOM" },
{ "data": "BatchQuantity" },
{ "data": "BatchUOM" },
{ "data": "ShelfDate" },
{ "data": "ExpireDate" },
{ "data": "CreatedDate" },
{ "data": "CreatedBy" },
{ "data": "POReceiveDate" },
{ "data": "Notes" }
]
});
In the ajax part I've tried with dataSrc as well, didn't work.
"dataSrc": function ( json ) {
var x = JSON.parse(json);
return x;
},
My question, is there any builtin extender to do that, or perhaps how can I make a prototype like thing for this? I thank you in advance.
This is exactly the purpose of dataSrc. It is not working because you are expected to return an array of items, i.e data :
dataSrc: function ( json ) {
json = JSON.parse(json);
return json.data;
},
PS: Why "type": "POST"?
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