row().child().show() isnt picked up by jquery datatables - javascript

After following the examples in https://datatables.net/reference/api/row().child(), I got this working in one project. Now im working on a new one, and everything was fine until the .show() came up with the error 'Property 'show()' does not exist on type Api' I followed the example and my imports seem to be up to date (this function has been in datatables since 1.10) so I dont know what could be wrong. This is in a typescript file, but as far as im aware everything still works like javascript. The function doesnt get upset if I do row.child().show(), but when I put the format function in it doesnt like that. Im still new to programming, so any help is super welcome :)
My HTML Table:
<table id="duckTable" class="display" cellspacing="0" width="80%">
<thead>
<tr>
<th>Select</th>
<th>Id</th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
</table>
My JS table:
var duckTable = $('#duckTable').DataTable({
"ajax": {
"url": "/Ducks/getDucks",
"type": "GET",
"dataSrc":""
},
paging: false,
ordering: false,
info: false,
"columns": [
{
className: 'dropdown',
orderable: false,
data: null,
defaultContent: '',
},
{ "data": "id" },
{ "data": "name" },
{ "data": "type" }
],
order: [[1, 'asc']],
"columnDefs": [
{
"render": function (data, type, row) {
var status = row.status;
var editButton = "<i name=" + row.id + " class=\"open-table\" style=\"padding-left:27px; padding-top:10px;\">&#8595</i> ";
if (status == null || status === 'D') {
return editButton;
} else {
return "";
}
},
"targets": 0
},
{"width": "10%", "targets":0},
]
});
My function:
function format(d) {
return ('<div>Still doesnt work</div>');
}
$('#duckTable tbody').on('click', 'td.dropdown', function () {
var tr = $(this).closest('tr');
var row = duckTable.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row (the format() function would return the data to be shown)
row.child(format(row.data())).show();//this throws the error
tr.addClass('shown');
}
});

You mentioned that you're using TypeScript - the error that you're receiving sounds like a TypeScript compilation error.
This is because by the Typescript API definition that DataTables publishes, calling row.child(data) returns a union type of RowChildMethods<T> | Api<T>. Because the .show() method is not defined on the Api type, the Typescript compiler throws an error.
You should be able to get around this by splitting up your code into two statements:
row.child(format(row.data()));
row.show();

Related

Add json data to datatables

I am trying to populate datatables with a complex json scheme, however I don't know exactly how to do it.
First, some parts of json are nested and it needs iteration.
Second I need to create some markup, basically a href link.
Here is what I have:
$(document).ready(function(){
$('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'/dashboard/ajaxgetrequests',
dataSrc: "json_list"
},
'columns': [
{ data: 'firstname' },
{ data: 'funding_project_name' } // this must be a link like <a href='/<relation_id>'><funding_project_name></a>
]
});
});
{
"json_list":{
"125":{
"firstname":"John",
"funding_project_name":"A",
"relation_id": "7"
},
"133":{
"firstname":"Cesar",
"funding_project_name":[
"A",
"B"
],
"relation_id":[
"7",
"9"
]
}
}
}
1) For nested JSON you can use something like this:
// JSON structure for each row:
// {
// "engine": {value},
// "browser": {value},
// "platform": {
// "inner": {value}
// },
// "details": [
// {value}, {value}
// ]
// }
$('#example').dataTable( {
"ajaxSource": "sources/deep.txt",
"columns": [
{ "data": "engine" },
{ "data": "browser" },
{ "data": "platform.inner" },
{ "data": "details.0" },
{ "data": "details.1" }
]
} );
2) To edit and insert a link you can use columns.render (documentation)
$('#example').dataTable( {
"columnDefs": [ {
"targets": 0,
"data": "download_link",
"render": function ( data, type, row, meta ) {
return 'Download';
}
} ]
} );
Honestly, there may be a better built in way of handling this but when I experience things that do not fit the exact mold of using the base datatable functionality, I prefer to take manual control of the generation. This will give you an overview on how to do it with your structure:
Just basic html for your table (nothing really to see here):
<table id="empTable">
<thead>
<tr><th>First Name</th><th>ProjectName</th></tr>
</thead>
<tbody></tbody>
</table>
In JS we declare a variable we can use throughout our script then on ready event we instatiate our datatable:
var dt;
$(document).ready(function () {
dt = $('#empTable').DataTable();
loadDT();
});
We will also use a function call 'loadDT()' and what this will do is trigger a ajax call to the backend to get your json, in this example, I'm just gonna mock it but in your world so this on the ajax success:
Iterate your list and determine the types then use the api call row.add to dynamically add new rows to your table. (notice we are reusing the stored variable dt that we initially declared.) This is where you can do whatever custom logic fun you need to do.
function loadDT(){
var mockJSON = { "json_list":{ "125":{ "firstname":"John","funding_project_name":"A","relation_id": "7"},"133":{ "firstname":"Cesar","funding_project_name":["A","B"],"relation_id":["7","9"]}}};
$.each(mockJSON.json_list, function (i, n){
if(Array.isArray(n.funding_project_name)) {
$.each(n.funding_project_name, function (i2, p){
dt.row.add([n.firstname,'' + p + '']);
dt.draw(false);
});
} else {
dt.row.add([n.firstname, '' + n.funding_project_name + '']);
dt.draw(false);
}
});
}
Like previously stated, there may be some built in functions to handle this that I am unaware but when things get complicated, just know you can take manual control of it.
Full Example:
var dt;
$(document).ready(function () {
dt = $('#empTable').DataTable();
loadDT();
});
function loadDT(){
var mockJSON = { "json_list":{ "125":{ "firstname":"John","funding_project_name":"A","relation_id": "7"},"133":{ "firstname":"Cesar","funding_project_name":["A","B"],"relation_id":["7","9"]}}};
$.each(mockJSON.json_list, function (i, n){
var projLinks = "";
if(Array.isArray(n.funding_project_name)) {
$.each(n.funding_project_name, function (i2, p){
projLinks += '' + p + ' ';
});
} else {
projLinks = '' + n.funding_project_name + '';
}
dt.row.add([n.firstname, projLinks]);
dt.draw(false);
});
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="empTable">
<thead>
<tr><th>First Name</th><th>ProjectName</th></tr>
</thead>
<tbody></tbody>
</table>

Getting Datatables and Sparklines to play nice together?

Im currently trying to get Datatables and the Sparklines packages to work together kind of like below:
(This stuff is all written in R however)
I realize my issue is similar to this one... However, even after looking at some of the code and adapting it to my own, I was only able to render one or the other.. either the data from my server on the chart or the sparklines rendered with all data missing - never both together...
Here's the code
<table id="table_id" class="display">
<thead>
<tr>
<th>Table Name</th>
<th>Column Name</th>
<th>Rule</th>
<th>Current</th>
<th>Minimum</th>
<th>Maximun</th>
<th>Median</th>
<th>Mean</th>
<th>Sparkline</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
The HTML above and the JS below..
<script>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
CURRENT_JOB = "{{ job_requested }}";
data = {{ data|safe}}
$(function() {
$('.js-typeahead').typeahead({
order: "asc",
source: {
groupName: {
// Array of Objects / Strings
data: {{jobs|safe}}
}
},
callback: {
onInit: function() {
$('#table_id').DataTable({
data:{{ data|safe}},
columns: [
{data: 'table_name'},
{data: 'col_name'},
{data: 'rule'},
{data: 'current'},
{data: 'min'},
{data: 'max'},
{data: 'median'},
{data: 'mean'},
],
"aoColumnDefs": [
{
"aTargets": [8],
"mRender": function (data, type, full) {
// since data is an array of values [1,2,3,4]
data = data.toString()
return '<span class="spark">' + data + '</span>'
}
}
],
"drawCallback": (oSettings) => {
console.log('callback')
$('.spark:not(:has(canvas))').sparkline('html', {
type: 'line',
minSpotColor: 'red',
maxSpotColor: 'green',
spotColor: false
});
}
});
}
}
});
});
Does anyone know what I am doing wrong? I need the columns: [] to point my JSON data to the right columns in the table but I also need to point one of the keys in my data object to the sparkline itself and then call the .sparkline()
Also my data object structure that im getting from the server kinda looks like this:
data = {
'table_name': cow,
'col_name' : cow_col,
'rule' : cow_col,
..etc, etc..
'data4spark: [1,2,3,4]
}
I really appreciate anyones feedback/help! Thanks! ❤️
Got it. This always happen every time I post a stackoverflow question, but I think i'd be stuck for a few days if I didn't post so..
Anyways, after reading the docs for a few hours -- The aoColumnDefs is a selector that can select an entire row in the table (if it's already created in the HTML) and that was wrong in my code above.. The aTargets is the parameter that you pass in the index of the column and the mRender is the call back function that you call right before it spits out whatever to the screen (it can modify the data beforehand for that specific col)
The diff is that I sent the code to the HTML using the columns and then I targeted the whole col to attatch the tags on and sent them over
Posting my code in hopes this saves someone time
$('#table_id').DataTable({
data:{{ data|safe}},
columns: [
{data: 'table_name'},
{data: 'col_name'},
{data: 'rule'},
{data: 'current'},
{data: 'min'},
{data: 'max'},
{data: 'median'},
{data: 'mean'},
{data: 'data'},
],
"aoColumnDefs": [
{
"aTargets": [8],
"mRender": function (data, type, full) {
// since data is an array of values [1,2,3,4]
return '<span class="spark">' + data + '</span>'
}
}
],
"drawCallback": (oSettings) => {
console.log('callback');
console.log($('.spark:not(:has(canvas))'))
$('.spark:not(:has(canvas))').sparkline('html', {
type: 'line',
minSpotColor: 'red',
maxSpotColor: 'green',
spotColor: false
});
}
});

JSON to HTML5 table

How to populate a HTML5 table if you receive data in JSON format in jQuery Ajax and based on a specific column on a row color that row on a table (Using bootstrap 4 CSS styles?)
For example if i receive a dataset in JSON format like this:
{ "name":"John", "age":31, "city":"New York" };
The column city is New York so the table row should be colored green so the finished product should be like this:
<tr class="success">
<td>John</td>
<td>31</td>
<td>New York</td>
</tr>
I'm fairly new at jQuery can anyone guide me through how this can be achieved?
I'm using datatables library at the moment and what i have done is this:
function btnSearch_Click() {
$.ajax({
type: "POST",
url: "index.aspx/GetJobs",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$('.table-sortable').dataTable({
destroy: true,
data: data,
columns: [
{
'd': 'Name'
},
{
'd': 'Age'
},
{
'd': 'City'
}]
});
}
});
};
Current HTML5 code is displayed bellow
<table class="table table-hover thead-inverse table-bordered table-sortable">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
</table>
But when I click the button no data rows are returned by the browser (SQL Server does return data). Also as i mentioned i do not know how to accomplish that if specific data is returned in a row i need to color it...
Thank you for your help in advance...
Try this :
$('.table-sortable').dataTable({
destroy: true,
data: data,
columns: [
{ "data": "name" },
{ "data": "age" },
{ "data": "city" },
]
});
For using DataTables with ajax you usually have something like this:
$(document).ready(function () {
$('.table-sortable').dataTable({
"ajax": {
"url": "index.aspx/GetJobs",
"type": "POST"
},
"columns": [
{ "data": "name" },
{ "data": "age" },
{ "data": "city" },
]
});
});
As you can see the plugin itself has the functionality to use ajax.
So by default your returned data from server should contain a property data which contains the elements that are about to be rendered. You can actually specifiy this by using the dataSrc (reference) prop of ajax, you can set it to other name or remove it if you use plain collection:
"ajax": {
"url": "index.aspx/GetJobs",
"type": "POST"
"dataSrc": ""
},
This however does not change the data name in columns declaration so don't change it there.
You can read more about accepted formats and see examples in the official documentation.
Now regarding your question about row styling, there are a lot of callbacks and declarations which you can use to achieve that. I personally prefer using the createdRow callback (reference):
"createdRow": function( row, data, dataIndex ) {
if ( parseInt(data[1]) >= 18 ) {
$(row).addClass( 'success' );
}
}
So in this case if the age (second column based on 0-start-indexing) of the current row is above 18 it will add the desired class.
I hope this helps resolving your issues, if there still are problems you can try making a working jsfiddle so we can try debugging it in a "real-like" situation.
This is just to get an idea, i will add button click code
$("button").click(function(){
var obj = JSON.parse('[{ "name":"John", "age":30, "city":"New York"},{ "name":"John1", "age":30, "city":"New York"}]');
var t = $('#example');
for (i = 0; i < obj.length; i++) // iterate data from json
{
var name = obj[i].name;
var age = obj[i].age;
var classStyle = 'yellow'
if(name=='John')
{
classStyle = 'green';
}
$('#example').append('<tr style=background:'+classStyle+'><td>'+name+'</td><td>'+age+'</td></tr>');
}
});

Jquery DataTable unable to add rows using table.rows.add method

For some very funny reason, I am unable to add multiple rows to a simple table using dataTables. Here is the thing,
I am adding 4 rows to an html table using datatable, specifically using the table.rows.add method (link).
Below is the simple html code for it with a sample row already present in it.
<table id="items-table" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>ID</th>
<th>Item Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>Sample Object</td>
</tr>
</tbody>
</table>
And here is the javascript code for it.
// create a dataTable
var itemsTable = $("#items-table").DataTable({
paging: false,
searching: false
});
// add data as rows. Make sure to call the ```.draw``` method.
itemsTable.rows.add([{
"id": "1",
"item": "Aardvark"
}, {
"id": "2",
"item": "Red Bull"
}, {
"id": "3",
"item": "Jack in the Box"
}, {
"id": "4",
"item": "Chair"
}]).draw();
Error says:
DataTable warning: table id=items-table -Requested unknown parameter
'0' for row 1, column 0. For more information see this error.
Using
DataTables 1.10.12
jQuery v3.1.1
What is going wrong here?
You need to specify the columns.
// create a dataTable
var itemsTable = $("#items-table").DataTable({
paging: false,
searching: false,
columns: [{data: 'id'}, {data: 'item'}]
});
One workaround is to put all the data in a regular table and then initialize it as a dataTable, instead of adding individual rows.
You may want to add "fnDrawCallback": function in your Datatable initialization if you are using underscore.js templates or similar, and use function to bind events to rows after the table is redrawn. Another possible way to do this would be to use, order.dt or search.dt or page.dt events provided by Datatables to do this. Possibly like:
function bind_feedback_behavior(){
$('table.program-status')
.on( 'order.dt', function () { enable_feedback_behavior(); } )
.on( 'search.dt', function () { enable_feedback_behavior(); } )
.on( 'page.dt', function () { enable_feedback_behavior(); } );
}

DataTables add column dynamically to table

I'm using DataTables (datatables.net) to display data from an Ajax source and having trouble customizing it. One thing I would like to do is add a column so I can have for example an 'edit' button for each row.
The closest thing to that in the examples is here but I can't get that to work with an ajax source.
Currently, I'm using the following code to display my table:
fnServerObjectToArray = function ( aElements ){
return function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": function (json) {
var a = [];
for ( var i=0, iLen=json.aaData.length ; i<iLen ; i++ ) {
var inner = [];
for ( var j=0, jLen=aElements.length ; j<jLen ; j++ ) {
inner.push( json.aaData[i][aElements[j]] );
}
a.push( inner );
}
json.aaData = a;
fnCallback(json);
}
} );
}
}
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": 'get_data.php',
"fnServerData": fnServerObjectToArray( [ 'username', 'email' ] )
} );
});
Why don't you use fnRenderFunction in the aoColumns? As an example:
aoColumns: [ { "bVisible": false} , null, null, null, null,
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"fnRender": function (oObj) {
return "<a href='EditData.php?id=" + oObj.aData[0] + "'>Edit</a>";
}
}
]
You can use it to format the value from the server side.
See similar example on the http://jquery-datatables-editable.googlecode.com/svn/trunk/ajax-inlinebuttons.html (ignore specific settings for the editable plugin)
I've created columns with edit button and links and so on, but usually i do everything server side by custominzg the data i return and then show/hide them with the aoColumns option. I don't really understand what you are tring to achieve: display server side data as a link?
Had the same problem a few months back. This is what I did.
By no means an elegant slution, but this worked.
As you might already know, DataTables do have an overload to accept Javascript Arrays.
So I made by $.ajax call. got my json, parsed it to a javascript array and then while parsing I created an extra element (an anchor tag) with href="edit.php?email=passed_email" Then on the column headers and added a column called Edit. Those values were fed to "aaData" and "aoColumns". And then the table was populated.
And BTW, if you looking for inline editing, check the following link.
DataTables editing example - with jEditableplugin
i have some RND on this problem and get this hope this will help you out.

Categories