Datatables column.render - datatables

I am using datatables and would like to over-ride the contents of a cell depending on the value it contains. I am using '1' to flag true in the underlying database and '0' for false. I am attempting to use the Columndefs render function to do this.
Here is my code..
xample_table = $('#treatment_list').DataTable(
{
select: true,
destroy: true,
"order": [ 0, 'desc' ],
data:json,
columns : [
{'data':'treatment_name'},
{'data':'description'},
{'data':'measured_in'},
{'data':'exclusive'}
],
"columnDefs": [
{
"targets":3,
"data" : "exclusive",
"render": function ( data, type, row ) {
if (type === 'display'){
if (row.exclusive == '0')
{
return 'No';
}
else
return 'Yes';
}
}
}
]
}
);
The problem is I get an erro message from datatables that reads..
DataTables warning: table id=treatment_list - Requested unknown parameter 'exclusive' for row 0, column 3....
Apart from the error message, it is in fact working.

thanks for the advice,but the json was fine and the other variables did not reveal much as I had console logged them before posting here. I did find a solution and am posting it here in case it helps anyone else. This expression works :
"columnDefs": [
{
"render": function ( data, type, row ) {
if (data =='1') {
return "True" ;
}
else{
return "False" ;
}
},
"targets": [3]
}
]
In all of the examples I have found, they often included the name of the column being affected and I think this is what caused the error message , whereas - you really just need to include the "targets" : [n] where 'n' is the column number. Perhaps it depends on how the table is constructed ?
Thanks.

Related

Fixed values on sorted column with formatted dates

I have a table initialised by
document.addEventListener("DOMContentLoaded", function(){
$.fn.dataTable.moment( 'DD MMM Y' );
})
The problem is that my column has both dates and text (only one type of text), i.e. 'ongoing'. The dates have this format: 30 Oct 2020, and I am able to order it correctly thanks to the addition of the $.fn.dataTable.moment( 'DD MMM Y' ); line. If there's only one instance of 'ongoing' among the data, though, the ordering gets messed up and doesn't work. How can I add an exception to the ordering?
I'm looking for something like
"order": [[ 2, "asc" ]], "exception": ["ongoing"]
(very pseudo-code).
Update
I've learned about the absoluteOrder plugin and have implemented like so:
var deadlineType = $.fn.dataTable.absoluteOrder( [
{ value: 'ongoing', position: 'top' }
] );
"columnDefs": [ {
[...]
{ "targets": 2, type: deadlineType } ]
})
It almost works. It puts the 'ongoing' on top. Nevertheless, the data sorting is messed up again, even when using absoluteOrderNumber. Is there an absoluteOrder line specific for dates?
Thanks to kthorngren on the datatables forum I have solved this problem.
This is the working code:
{
"targets": 2,
"render": function (data, type, row) {
if ( type === 'sort' ) {
if (data === 'ongoing') {
return '01 Jan 0001';
}
return data;
}
return data;
}
}

Button onClick inside DataTables doesn't show the correct url

I'm displaying all the customer data using DataTables like this:
<script type="text/javascript" src="DataTables/datatables.min.js"></script>
<script>
var theTable = null;
$(document).ready(function() {
theTable = $('#table-customer').DataTable({
"processing": true,
"serverSide": false,
"ordering": true,
"order": [[ 0, 'asc' ]],
"ajax":
{
"url": "http://localhost/myshop/showdata.php",
"type": "GET"
},
"sAjaxDataProp": "data",
"deferRender": true,
"aLengthMenu": [[5, 10, 20, 50],[ 5, 10, 20, 50]],
"columns": [
{ data: "cust_id" },
{ data: "cust_name" },
{ data: "cust_addr" },
{ data: "cust_email" },
{ data: "cust_phone" },
{ data: "cust_photo", sortable: true, render: function (o) { return '<button id="btn1" onclick="displayImage(data)">Show</button>';}
]
});
});
function displayImage(link){
window.alert(link);
}
</script>
All information is displayed properly, except 1 thing: if you click any button on "customer photo" column, instead of showing an alert which shows its URL, nothing happens. Inspecting the page showed me this:
Uncaught ReferenceError: data is not defined
at HTMLButtonElement.onclick (view.html:1)
How to fix this?
The columns.data render function builds a string which is returned:
function (o) { return 'your string here, including data value'; }
You have to (a) concatenate your data variable with the string literals you need; and (b) use the variable name you provided - I will use data instead of o:
function (data) { return 'your string here, including ' + data + ' value'; }
So, if we provide all the possible parameters allowed in the renderer, that becomes:
{
"data": "cust_photo",
"sortable": true,
"render": function(data, type, row, meta) {
return '<button id="btn1" onclick="displayImage(\'' + data + '\')">Show</button>';
}
}
I use \' to ensure the value of the data variable is surrounded in single quotes.
(Note that in your question, the code is also missing a closing }.)
But to avoid potential issues with sorting and filtering, these column data render functions need to account for DataTable's use of orthogonal data.
The type parameter can be used for this:
{
"data": "cust_photo",
"sortable": true,
"render": function(data, type, row, meta) {
if (type === 'display') {
return '<button id="btn1" onclick="displayImage(\'' + data + '\')">Show</button>';
} else {
return data; // type is for sorting or filtering - just use the raw value
}
}
}

DataTables: "targets: - 1` Meaning?

In this datatables example, what's the meaning of targets : -1?
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": "data/arrays.txt",
"columnDefs": [ {
"targets": -1,
"data": null,
"defaultContent": "<button>Click!</button>"
} ]
} );
$('#example tbody').on( 'click', 'button', function () {
var data = table.row( $(this).parents('tr') ).data();
alert( data[0] +"'s salary is: "+ data[ 5 ] );
} );
} );
As said in the Documentation :
Targets tells DataTables which column(s) the definition (columnDefs) should be applied to. It may be :
0 or a positive integer - column index counting from the left
A negative integer - column index counting from the right
A string - class name will be matched on the TH for the column
The string "_all" - all columns (i.e. assign a default)
So -1 is the first column counting from the right.

DataTables ajax requires explicit json collection name for the returned datasource?

I recently ran into a problem when implementing the ajax functionality of jquery DataTables. Until I actually gave my json object collection an explicit name I couldn't get anything to display. Shouldn't there be a default data source if nothing named is returned?
Client Side control setup (includes hidden field that supplies data to dynamic anchor:
$('#accountRequestStatus').dataTable(
{
"destroy": true, // within a method that will be called multiple times with new/different data
"processing": true,
"ajax":
{
"type": "GET",
"url": "#Url.Action("SomeServerMethod", "SomeController")",
"data": { methodParam1: 12341, methodParam2: 123423, requestType: 4123421 }
}
, "paging": false
, "columns": [
{ "data": "DataElement1" },
{ "data": "DataElement2", "title": "Col1" },
{ "data": "DataElement3", "title": "Col2" },
{ "data": "DataElement4", "title": "Col3" },
{ "data": "DataElement5", "title": "Col4" },
]
, "columnDefs": [
{
"targets": 0, // hiding first column, userId
"visible": false,
"searchable": false,
"sortable": false
},
{
"targets": 5, // creates action link using the hidden data for that row in column [userId]
"render": function (data, type, row) {
return "<a href='#Url.Action("ServerMethod", "Controller")?someParam=" + row["DataElement1"] + "'>Details</a>"
},
"searchable": false,
"sortable": false
}
]
});
Here's a snippet of my server side code that returns the json collection.
tableRows is a collection of models containing the data to be displayed.
var json = this.Json(new { data = tableRows });
json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return json;
As I said before, the ajax call returned data but wouldn't display until I gave the collection a name. Maybe I missed this required step in the documentation, but wouldn't it make sense for the control to wire up to a single returned collection as the default data source and not require the name? Figuring out the name thing equated to about 2+ hours of messin' around trying different things. That's all I'm saying.
Maybe this'll help someone else too...
dataTables does actually have a dataSrc property! dataTables will look for either a data or an aaData section in the JSON. Thats why you finally got it to work with new { data=tableRows }. That is, if dataSrc is not specified! If your JSON differs from that concept you must specify dataSrc :
If you return a not named array / collection [{...},{...}] :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: ""
}
If you return a JSON array named different from data or aaData, like customers :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: "customers"
}
If the content is nested like { a : { b : [{...},{...}] }}
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: "a.b"
}
If you have really complex JSON or need to manipulate the JSON in any way, like cherry picking from the content - dataSrc can also be a function :
ajax: {
url: "#Url.Action("SomeServerMethod", "SomeController")",
dataSrc: function(json) {
//do what ever you want
//return an array containing JSON / object literals
}
}
Hope the above clears things up!

.getjson from external domain. Print from the Array

I'm currently getting 2 arrays from the following get statement.
$.getJSON("http://domain.com?callback=?", function(data){
$("#results").html(JSON.stringify(data));
I'm appending the results in a div with the id results.
All that is doing is just displaying the array. I need to pull certain objects from the array but I can't do that because I am just printing the whole array. How do I get specific information from that array?
Here is some of the data that is being appended to the DIV.
{"me":[{"player":{"high_score":110345,"rank":2}}],"all":[{"player":{"#score := s.score":110345,"avatar":"http://profile.ak.fbcdn.net/hprofile-ak-snc6/195312_789328764_1121893995_q.jpg","guid":"FE4EC535-B74F-4B68-8F4D-2CA0EBC28FAF","name":"Charles Chase","rank":1,"score":110345}},
Thanks!
Provided that the following is your returned JSON data
{
"me": [
{
"player": {
"high_score": 110345,
"rank": 2
}
}
],
"all": [
{
"player": {
"#score := s.score": 110345,
"avatar": "http://profile.ak.fbcdn.net/hprofile-ak-snc6/195312_789328764_1121893995_q.jpg",
"guid": "FE4EC535-B74F-4B68-8F4D-2CA0EBC28FAF",
"name": "Charles Chase",
"rank": 1,
"score": 110345
}
}
]
};
You can use the following to grab the values from the JSON object
CODE
$.getJSON("http://domain.com?callback=?", function(data){
alert(data.me[0].player.high_score);
alert(data.all[0].player.name);
));
Note me and all is returned as array. I hope it helps.