DataTables - Calling functions in 'columnDefs' in react - javascript

So when I'm creating a DataTable in react, defining a certain column using the columnDefs property.
"columnDefs": [
{
"targets": 7,
"data": "data",
"render": function ( data, type, full, meta ) {
return "<button onclick='test()'>view</button>"
}
}
]
But as expected, it can't find the test() function. Is there anyway to do this jsx style or something? Or will I just have to create the function inside the onclick?

You can try like this:
$('#your_table').DataTable({
. . .
"columnDefs": [{
"targets": 7,
"data": "data",
"render": function ( data, type, full, meta ) {
return "<button class='view_btn' data-id='"+data+"'>view</button>"
}
}]
Then create the test function outside:
$('#your_table').on('click', '.view_btn', function(){
var id = $(this).data('id');
test(id); // your function
});

You can't use render in this case as the function will be called directly. You can use arrow function and createdCell insetead in columnDefs.
For example you have a function in a component:
this.test= this.test.bind(this);
Call that function in columnDefs by:
"columnDefs": [{
"targets": 0,
"data": "data",
"createdCell": (td, cellData, rowData, row, col) => {
$(td).click(e => {
this.test();
})
}
}]
Take a look at the link above for more information.

You can use the arrow function and this object
"columnDefs": [
{
"targets": 7,
"data": "data",
"render": ( data, type, full, meta ) => {
return "<button onclick='this.test()'>view</button>"
}
}
]

Related

DataTables add tag to column based on another attribute's value

I am trying to get the <span> tag into the "salesStatusName" column cell that already has some data in it. The tag should be placed in there when the value of the last column "completelyDelivered" is true. However, I also don't want "completelyDelivered" to even be a column in the table, so I assume I somehow need to access the value of "completelyDelivered" attribute in the received JSON.
How it looks now:
https://i.imgur.com/S171i2o.png circle in a separate column
How I want it to look:
https://i.imgur.com/74nCnGu.png circle within Status Name column
I looked around and there are very similar questions, but I was unable to implement any solution.
DataTables instantiation code:
Note that I use AJAX and get JSON code returned
$(document).ready(function () {
$.fn.dataTable.moment('MM-DD-YYYY');
var datatableObj = $('#salesOrdersTable').DataTable({
"ajax": {
"url": "/Orders/GetAll",
"type": "GET",
error: function (error) {
RedirectUserToErrorPage();
}
},
"columns": [
{ "data": "salesOrderNumber" },
{ "data": "salesOrderNumber" },
{ "data": "poNumber" },
{ "data": "orderDateString" },
{ "data": "company" },
{ "data": "salesPerson" },
{ "data": "salesStatusName" },
{ "data": "completelyDelivered" }
],
"columnDefs": [
{
"targets": 0, //salesOrderNumber col
"orderable": false,
"render": function (data) {
return '<input type="button" value="+" onclick="location.href=\'/Shipments/Get?salesOrderNumber=' + data + '\'">';
}
},
{
"targets": 7, //completelyDelivered col
"render": function (data) {
if (String(data) == "true") {
return '<span class="SalesOrderDelivered">⬤</span>';
}
return "";
}
},
{ className: "salesOrderNumber", "targets": 1 },
],
});
I've done some research and figured it out.
Basically, if you write { "data": null }, as a definition for a column, you gain access to all properties of that row. So, in "render": function(data) function, write data["propertyName"] to get the value.
Code:
$(document).ready(function () {
$.fn.dataTable.moment('MM-DD-YYYY');
var datatableObj = $('#salesOrdersTable').DataTable({
"ajax": {
"url": "/Orders/GetAll",
"type": "GET",
error: function (error) {
RedirectUserToErrorPage();
}
},
{"data": "salesOrderNumber",},
{ "data": "salesOrderNumber" },
{ "data": "poNumber" },
{ "data": "orderDateString" },
{ "data": "company" },
{ "data": "salesPerson" },
{ "data": null, },//this is Sales Status column.
//"data: null" accesses all JSON data. We need this so that in "columnDefs" section
//we can use the values of both "completelyDelivered" and "salesStatusName" properties.
],
"columnDefs": [
{
"targets": 0, //button col
"orderable": false,
"render": function (data) {
return '<input type="button" value="+" onclick="location.href=\'/Shipments/GetShipments?salesOrderNumber=' + data + '\'">';
}
},
{
"targets": 6, //Sales Status col.
"render": function (data) { //This is where we can use values of "completelyDelivered" and "salesStatusName" JSON properties.
if (String(data["completelyDelivered"]) == "true") {
return (String(data["salesStatusName"]) + '<span class="AllDelivered"> ⬤</span>');
} else {
return String(data["salesStatusName"]);
}
}
},
{ className: "salesOrderNumber", "targets": 1 },
],
});

Adding an element within a td in jQuery datatable

I have a js data table that I have implemented for pagination of data. It uses the jQuery data table. The data is being displayed correctly. However, I want to add an element within the first row of the data table.
Before I added it like this : <td>#Html.ActionLink(item.CarId, "Detail", "Cars", new { id = item.CarId},null)
<span class="dt-expand-btn js-expand-btn">+</span></td>
What I want to add within the td of the js is : <span class="dt-expand-btn js-expand-btn">+</span>
var carsDataTable = $('.js-cars-lists').DataTable({
"ajax": {
"url": "/Cars/CarsPagination",
"processing": true,
"serverSide": true,
"language": {
"paginate": {
"previous": '<i class="material-icons">chevron_left</i>',
"next": '<i class="material-icons">chevron_right</i>'
}
},
"order": [0, "asc"],
"type": "POST",
"datatype": "json"
},
"columns": [
{
"data": "CarId", "name": "CarId", "autowidth": true,
"render": function (data, type, row, meta) {
$(row.CarId).css('color', 'red');
return '' + row.CarId + '';
}
},
{ "data": "CarName", "name": "CarName", "autowidth": true },
Could someone please help me to achieve this ? Also, paginate icons are not appearing. Please help.
jQuery DataTable has a function of render it accepts 4 parameters function(data, type, row) which you can control the rendering of your rows. You can now check the rows of a table and add your element in it.
You can use columnDefs method and then render:
...
columnDefs: [{
"render": function(data, type) {
return '<span class="dt-expand-btn js-expand-btn">+</span>';
},
"targets": 0
}]
...
targets refers to the index of the table column (since you are referring to the 1st column) set it to 0

Send jquery datatable column value to Javascript Function (Asp.Net MVC)

I am binding data to jquery datatable in asp.net mvc, i have an anchor tag in one of the columns of the grid where i am accessing / reading row data and sending that data to a javascript function. The problem which i am facing is, i am able read and send row values to the function which are numbers for example ProductID="1" or CategoryID="3" , but if i try to send ProductName="Chai" to the javscript function i get an error in the console, and if i remove the parameter "ProductName" everything works fine and the javascript function also gets triggered.
Following the console error:
"Index:1 Uncaught ReferenceError: Chai is not defined
at HTMLAnchorElement.onclick (Index:1)"
Following is my Code:
var BindDataTable = function (response) {
$("#tbProduct").DataTable({
"aaData": response,
"aoColumns": [
{ "mData": "ProductID" },
{ "mData": "ProductName" },
{ "mData": "SupplierID" },
{ "mData": "SupplierName" },
{ "mData": "SupplierCountry" },
{ "mData": "CategoryID" },
{ "mData": "CategoryName" },
{ "mData": "QuantityPerUnit" },
{ "mData": "UnitPrice" },
{
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
}
],
"columnDefs": [
{
"targets": [2],
"visible": false,
"searchable": false
},
{
"targets": [5],
"visible": false,
"searchable": false
}
],
"aaSorting": []
});
}
var EditProduct = function (ProductID, SuppID, CatID,PrdName) {
var url = "/Product/EditProduct?ProductID=" + ProductID + "&SuppID=" + SuppID + "&CatID=" + CatID;
$("#myModalBodyDiv1").load(url, function () {
$("#myModal1").modal("show");
})
}
Error:
My suggestion is that instead of playing around with that much string concatenations, what you can do is pass single object to your function and then use the required fields which needs to be passed as ajax call:
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
and in your js function use it :
var EditProduct = function (product) {
var url = "/Product/EditProduct?ProductID=" + product.ProductID+ "&SuppID=" + product.SupplierID + "&CatID=" + productCategoryID + "&ProdName=" + product.Prooductname ;
You can use the following approach in for passing string arguments to a JavaScript function:
<a onclick="javaScriptFunction(#p.ID, '#p.FileName');">#p.FileName</a>
function javaScriptFunction(id, fileName) {
...
}

Accessing data in another column in Datatables

I'm using Datatables and I'm trying to access data in another column. It's unclear to me if I should be using columns.data or if I should be taking another approach by using getting the column index instead?
Objective
In the second render function, I want the first makeSlug(data) to be referencing the "data": "district" and the second one to remain the same and reference "data": "school"
scripts.js
"columns": [
{ "data": "district",
"render": function (data, type, row, meta) {
return '' + data + '';
}
},
{ "data": "school",
"render": function (data, type, row, meta) {
return '' + data + '';
}
},
{ "data": "subject"},
{ "data": "rate"},
{ "data": "test_takers"}
],
Third argument row is an array containing full data set for the row. Use row['district'] to access district property.
For example:
{
"data": "school",
"render": function (data, type, row, meta) {
return '' + data + '';
}
}

Make edit link on datatable with multiple column values and global search on single/custom column(s)

How to create an edit link with function having multiple parameter from the data columns returned from ajax.
I read about the render callback but it only gets one column value & I need 2.
I need something like the following pseudo code.
"columnDefs": [ {
"targets": [0,1],
"data": "0,1",
"render": function ( data, type, full, meta ) {
return ``
}
} ]
As I'm disabling global search on all column except one. I cannot use the above code that use targets property. I don't know how to achieve this, please guide.
Edit: Complete code
var datatable = $('#datatable').DataTable({
"ajax": "/get_data/",
"processing": true,
"serverSide": true,
"deferRender": true,
"columnDefs": [
{ "searchable": false, "targets": [ 0,2,3,4,5,6,7,8,9,10,11 ] }
]
});
You can access row data using full variable, for example full[0] or full[1].
However instead of generating links in HTML, I would retrieve row data in a click handler as shown below:
$('#example').DataTable({
"columnDefs": [
{
"targets": [0, 1],
"render": function ( data, type, full, meta ) {
return 'Edit';
}
}
],
// ... other options ...
});
$('#example').on('click', '.btn-edit', function(){
// Get row data
var data = $('#example').DataTable().row($(this).closest('tr')).data();
edit(data[0], data[1]);
});
I needed Edit link on first column, so I followed #Gyrocode.com answer and it works great.
I also wanted to use the global search for searching but only on one column. Datatable ColumnDef Documentation gave me the clue so I ended up doing as follows.
Here The complete code:
var datatable = $('#datatable').DataTable({
"ajax": "/get_data/",
"processing": true,
"serverSide": true,
"deferRender": true,
"columnDefs": [
{
"targets": 0,
"render": function ( data, type, full, meta ) {
return 'Edit';
}
},
{ targets: 1, searchable: true },
{ targets: '_all', searchable: false }
]
});

Categories