Datatables TypeError: c is undefined - javascript

I try to use jQuery DataTables but I get the error
TypeError: c is undefined
I don't know what is wrong with my code as I can see the JSON correctly retrieve and is in the correct format too but I don't know what is wrong with it that I get the above error.
My JSON :
{"Data":[{"LOGIN":10184},{"LOGIN":10214},{"LOGIN":10180},{"LOGIN":10187},{"LOGIN":10179},{"LOGIN":10280},{"LOGIN":201},{"LOGIN":10238},{"LOGIN":10296},{"LOGIN":10312}]}
and my DataTables code:
$(document).ready(function() {
$('#tablename').dataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"type": "POST",
"url": "https://test.com/api/db/select",
"data": function ( json ) { return JSON.stringify( { "Sql": 12 } );},
"contentType": "application/json; charset=utf-8",
"dataType": "json",
"processData": true,
beforeSend : function(xhr){
var access_token = sessionStorage.getItem('access_token');
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
}
},
"dataSrc": "Data",
"columns": [
{ "data": "LOGIN" }
]
} );
} );

Check whether you have added
<thead></thead>
<tbody></tbody>
I've resolved this problem by adding those.
So basically the structure must be like:
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>

Sometime, This type issue arrives by fixing mismatched / unequal columns with HTML and datatables columns.
"columns": [
null,
null,
null,
{"orderable": false, "width":"2%"},
],
Above javascript defined 4 columns and HTML having 5 columns
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
<td>E</td>
</tr>
Hence you will have to fix / equal both side HTMl and Datatable configuration.
"columns": [
null,
null,
null,
null, //Added New
{"orderable": false, "width":"2%"},
],

dataSrc is a special dataTables ajax option, that should be included inside the ajax object :
"ajax": {
"dataSrc": "Data", //<--- place dataSrc here instead
"type": "POST",
...
}
You have placed it outside ajax, and by that dataTables have no idea what source to use (besides blindly trying the ajax response) or where LOGIN belongs.

in my case, i had to remove colspan attribute from a th inside thead and get rid of the error ;(

In my case, missing aaData in sever side return result.
//Javascript
$('#table').DataTable({
sAjaxSource: '/load',
aoColumns: [
...
],
});
//server side(in Rails)
render json: {'aaData'=>data}

In my case, I got the same error because I used the ajax.dataSrc( data ) function to manipulate the data. But after that i forgot to return the data.
"dataSrc": function ( json ) {
for ( var i=0, ien=json.data.length ; i<ien ; i++ ) {
//somethings...
}
return json.data;// I forgot this line, then i got the error "TypeError: c is undefined"
}
After a few minutes, I checked the documentation of the ajax.dataSrc function and I noticed that I did not have the return:
Returns: array. Array of data that DataTables is to use to draw the table
I hope you do not have the same distraction...

In my case th and td , count is not equal due do colspan, removed colspan and it worked.

In my case, my front-end: ajax: { dataSrc: "data" } was OK, but on server-side I returned object where first letter was Upper return Json(new { Data = model });

Another day, another solution - this time caused by a style sheet!
After spending hours reducing a gigantic web page to the raw charts code, I found that this error shows (for pie charts) when CSS rules for fonts in the stylesheet contain the calc function.
In our style sheet, this line of code:
html {
font-size: calc(12px + 5%);
}
...broke the chart. We needed this because our webfont wasn't resizing smoothly and needed a size slightly larger than 12px but smaller than 13px, and this trick forced a better resize.
Overwriting the style rule on the chart widget directly solved the issue:
CSS
html {
font-size: calc(12px + 5%);
}
.widget {
font-size: 12px /* Replace the above rule */;
}
JS
var GoogleChart1 = new google.visualization.PieChart(document.getElementById('Chart1'));
HTML
<div id="Chart1" class="widget"></div>

check followings
<td></td> -- check count
<th></th> -- check count
check <tbody> and <thead> - opening and closing

In my case the number of column in <thead> tag is different than the number of column in <tbody> tag.

Related

How to redraw a Datatable that uses server side processing using only the existing data in the datatable?

I'm trying to delete a row from a Datatable that uses server side processing (removing the row data and the row/tr visually) based on the value of certain attribute of the row.
I'm using the remove() function to do it and it removes the row data, but visually the table stills the same.
So I added the draw() function but it reinitializes the table, including the data.
So, how can I "redraw" the table after removing a row from the Datatable that uses server side processing? Is there any other function like draw() to redraw the table but using only the existing data in the datatable?
$("#tableSelector").DataTable()
.rows( function ( idx, data, node ) {
return data.attribute_value == value_to_delete;
} )
.remove()
.draw();
Finally, I found the solution.
I followed this thread then read about the DataTable's property "dataSrc".Then with this information searched for something similar in Stack Overflow and found this.
So the trick to do what I asked for was to use a variable to filter the row which I want to ignore in the ajax call.
I've reused the code provided in the referred question. And this is the result:
HTML:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Subject</th>
<th>Status</th>
<th>Message</th>
<th>Details</th>
</tr>
</thead>
</table>
JS:
$(document).ready(function() {
function loadDataTable(excluded_name = undefined){
$("#example").DataTable().destroy();
$('#example').DataTable({
// "processing" : true,
"ajax" : {
"url" : "https://api.myjson.com/bins/12uwp2",
"dataSrc": (json) => {
if(excluded_name !== undefined){
return json.filter((item) => item.name !== excluded_name)
}else{
return json
}
}
},
"columns" : [ {
"data" : "name"
}, {
"data" : "email"
}, {
"data" : "subject"
}, {
"data" : "status"
},{
"data" : "message"
},
{
"mData": "Details",
"mRender": function (data, type, row) {
return "<a class='delete' data-name='"+ row.name + "' data-id=" + row.id + " href='/Details/" + row.id + "'>Delete</a>";
}
}]
});
}
$(document).on("click", ".delete", function(e) {
e.preventDefault()
let excluded_name = $(this).data("name")
alert("Excluding this name in the next load: " + excluded_name);
loadDataTable(excluded_name);
})
loadDataTable();
});
Fiddle: https://jsfiddle.net/ek94mh1x/4/
Note: This is a client side "delete", I know this could be done with server side processing, but in my case I was only allowed to do it in the client side.
Additionally, in case you need to delete multiple rows you could use an array as a parameter and follow the same logic.
I hope this could help someone.

reload datatable after ajax success

I use JQuery DataTable. I send data to datatable onclick in json file at ajax succes .the first click everything is good,But the next click I get only the right data ANd wrong value of dataTables_info it display always the first value of dataTables_info And paginatio AND row too from the first result.
This is the first display of data in datatable:
ALL the next Click I get only right data:
For this exemple they are one result showing in picture below but everything else(info ,show,pagination) belong to first search showing in the first picture :
In the second Exemple When I click at any page of pagination I get the content of the first page result!!
This is my function ONclick:
$ ( '#ButtonPostJson' ).on('click',function() {
$("tbody").empty();
var forsearch = $("#searchItem").val();
$.ajax({
processing: true,
serverSide: true,
type: 'post',
url: 'searchData.json',
dataType: "json",
data: mysearch,
/* bRetrieve : true,*/
success: function(data) {
$.each(data, function(i, data) {
var body = "<tr>";
body += "<td>" + data.name + "</td>";
..........................
..........................
body += "</tr>";
$('.datatable-ajax-source table').append(body);
})
;
/*DataTables instantiation.*/
$('.datatable-ajax-source table').dataTable();
},
error: function() {
alert('Processus Echoué!');
},
afterSend: function(){
$('.datatable-ajax-source table').dataTable().reload();
/* $('.datatable-ajax-source table').dataTable({bRetrieve : true}).fnDestroy();
$(this).parents().remove();
$('.datatable-ajax-source table').dataTable().clear();*/
}
});
});
I try everything and i dont know what I miss.
I use this jquery for datatable:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
Thanks.
Use like it
$('#product_table').DataTable().ajax.reload();
Get table id first, like:
var table=('#tableid').Datatable();
table.draw();
just put these lines after ajax success function to reload datatable
On a button clik you dont need to empty your table body and make initiate the datatable again with the ajax.
you just have to call your ajax again as you have already initiate on document ready function
just use
$("#Table_id").ajax.reload();
check the below link, you will have better idea.
https://datatables.net/reference/api/ajax.reload()
Let me know if this doesn't help you
I had this same problem. I found a function I wrote on a project that deals with this. Here is a simple 2 column table I made.
<table id="memberships" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</tfoot>
</table>
This is my script to populate it:
function drawTable(){
var table = $('#memberships').DataTable();
table.destroy();
value = $("#memberName").val();
console.log("member name-->>" + value);
$('#memberships').DataTable({
responsive:true,
pageLength: 50,
ajax:{
"url": `//BACKEND API CALL`,
"type":"get",
"dataSrc": 'members'//my data is in an array called members
},
columns: [
{"data": "name_display" },
{"targets": 0,
"data": "membershipID",
"render": function ( data, type, full, meta ) {
return '<button type="button" class="btn btn-info btn-block"
onclick="editMember(' + data + ')">Edit Member</button><button
type="button" class="btn btn-danger btn-block"
onclick="deleteMember(' + data + ')">Delete</button>';
}
}
]
});
$.fn.dataTable.ext.errMode = 'none';
}
You can ignore my column render function. I needed 2 buttons based on the data returned. The key was the table.destroy in the function. I created the table in a variable called table. I destroy it right in this initialization because it allowed me to use this same function over and over. The first time it destroys an empty table. Each call after that destroys the data and repopulates it from the ajax call.
Hope this helps.
Update: After playing with datatables alot more I found that setting table to a variable in a global scope to your function allows you to use reload.
var table = $('#memberships').DataTable({});
Then
table.ajax.reload();
should work.
I created this simple function:
function refreshTable() {
$('.dataTable').each(function() {
dt = $(this).dataTable();
dt.fnDraw();
})
}
use below code..it perfectly work, it keep your pagination without lose current page
$("#table-example").DataTable().ajax.reload(null, false );
$('.table').DataTable().ajax.reload();
This works for me..
$("#Table_id").ajax.reload(); did not work.
I implemented -
var mytbl = $("#Table_id").datatable();
mytbl.ajax.reload;
.reload() is not working properly untill we pass some parameter
var = $("#example").DataTable() ;
datatbale_name.ajax.reload(null, false );
Try This i hope it will work
$("#datatable_id").DataTable().ajax.reload();

Put a button in front of all rows in jQuery DataTables

I am using jQuery DataTables. It is being populated with JSON data from a database. I can't figure out how to display a button or link in front of each record. I want to make it so that when the user clicks on that button then that particular record gets added in the database, so the button or link should contain an ID. Please help sort out my problem.
Below is the code I'm using:
var oTable = $('#jsontable').dataTable();
$.ajax({
url: 'process.php?method=fetchdata',
dataType: 'json',
success: function(s) {
console.log(s);
oTable.fnClearTable();
for (var i = 0; i < s.length; i++) {
oTable.fnAddData([
s[i][3],
s[i][4],
s[i][0], // this contains id
]);
}
},
error: function(e) {
console.log(e.responseText);
}
});
<table id="jsontable" class="display table table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Class Number</th>
<th>Subject</th>
<th>ADD</th>
</tr>
</thead>
</table>
I hope this is help
oTable = $('#jsontable').dataTable({
"fnRowCallback": function (nRow, aaData, iDisplayIndex) {
//nRow Row Object
//aaData Param
//iDisplayIndex Row Index
$('td:eq(0)', nRow).html("<input type='button'>Button</input>");
return nRow;
}
});
Do you mean to do something like this? (Also, this may be for an older version of datatables, now that I think about it. This is syntax for version 1.9, and I would guess you're using a more recent version (1.10+) The syntax may be a little different, but it should be documented in the api docs.
$('#jsontable').dataTable({
"sAjaxSource" : "process.php?method=fetchdata",
"aoColumns" : [
{ "mData": function(source) {
return '<input type="button" value=' + source[0] + '/>';
}},
{ "mData": function(source) {
return source[1];
}},
{ "mData": function(source) {
return source[2];
}}
}
});
Obviously, your button can look however you want, you probably don't want the id stored on the value. You can do what you need with it.

Applying fnFilter to a modified table

Using DataTables 1.9.4 and JQuery 1.4.4.
I'm trying to create a table which filters certain rows based on the visible column. The table is driven by an AngularJS like in-house controller.
When the table is displayed, the filter works fine, but thereafter, if the value changes, the filter is not updated.
The controller consists of an array (one for each row). When the table is updated through it, the filter is not reapplied. How can I make the filter reevaluate each row when the data changes?
HTML as generated by controller:
<table id="table-status">
<thead>
<tr>
<th>visible</th>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>name1</td>
<td>1</td>
</tr>
<tr>
<td>0</td>
<td>name2</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>name3</td>
<td>3</td>
</tr>
</tbody>
</table>
The DataTables initialization:
var oTable = $("#table-status").dataTable( {
"aoColumnDefs": [ { "bVisible": false, "aTargets": [ 0 ] },
{ "bVisible": true, "aTargets": [ 1 ] },
{ "bVisible": true, "aTargets": [ 2 ] } ],
"bSort": false,
"bFilter": true
} );
oTable.fnFilter("1", 0, false, false, false, false);
I'm not entirely sure if this is what you need, but I rolled my own function to display or not some rows, based on a column called Status.
I have a checkbox that can contain the values 0, 1, 2 and 3.
First, I get the regex function associating the values I want to filter:
var filter = "^" + $("#filterStatusCheck option:selected").map(function() {
return this.value;
}).get().join("|") + "$";
Which returns, for instance, ^1|2$, meaning I want to filter the values 1 and 2.
Then, I search() the DataTable, looking for those elements (not me, actually, but rather their search() method.
var t = s.getTable().DataTable();
t.column(8).search(filter, true, false).draw();
Here, on column with the index of 8, I'm doing so that it searches, using the above filter, and then draw() the DataTable again.
In your case, you might want to figure out what event you can attach the above code (maybe right after the row has been updated?). Your filter would be 1 (visible, right?), whereas your column search would be 0 (the first column called visible).
Hope it helps.

Specify column data type with a <th> attribute for DataTables

We're using the DataTables jQuery plugin (http://www.datatables.net) to create sortable tables. This plugin auto-detects the data type of the data in each column.
When you want to specify the data type of a column yourself, you add the "aoColumns" attribute when you initialize the datatable:
$('#accountTable').dataTable({
"bPaginate": false,
"sScrollX": "100%",
"bScrollCollapse": true,
"aoColumns": [
null,
null,
{ "sType": "currency" },
{ "sType": "currency" }
]
});
Note, I downloaded the currency data type plugin for datatables. This works great.
However, I'm concerned that if we ever make changes to the table column, we'll forget to go back into the JS and change how the datatables plugin is initialized on that table.
So... It would be ideal to specify the data types directly in the table as necessary:
<table class="dataTables display">
<thead>
<tr>
<th>Category</th>
<th>Product</th>
<th sType="currency">Cost</th>
<th sType="currency">Retail</th>
...
Is there any way to do this, either with default functionality of DataTables (which I can't find) or using a JS loop or something to loop through the tags of the table and update the sType where "sType" attribute exists?
Here is an absolutely cool way to do it:
Your header HTML:
<table id="sorted-table">
<thead>
<tr>
<th data-s-type="string">Number</th>
<th data-s-type="html">Complex Name</th>
<th>Price</th>
<th data-b-sortable="false">Action</th>
</tr>
</thead>
...
Your JS:
$('#sorted-table').dataTable({
...
"aoColumns": $('#sorted-table').find('thead tr th').map(function(){return $(this).data()})
});
Note: those dashes in data attributes are needed. They get converted to camelCase form by jQuery which makes it compatible with the data tables API.
Picking up on CBroe's comment, this is exactly what I do. Just ensure that your custom attributes are prefixed with data-, such as data-stype='currency' per the HTML specs.
Having your JS loop through and check for attributes on the headers would work, but you can't just invent an sType attribute and have it show up in the DOM. You'd have to subvert a valid but unused attribute like headers (and that might cause trouble for screen readers; there may be a better option).
Edit:
OK, having read CBroe's comment, I guess it is possible to give an element an arbitrary attribute.
So, if you wanted to be HTML5 compliant, you could name the property data-sType and then do something like this:
var aoColumns = [];
$('#accountTable > th').each(function() {
var sType = $(this).getAttribute("data-sType");
aoColumns.push(sType ? sType : null);
});
$('#accountTable').dataTable({
...
"aoColumns": aoColumns
});
Thanks to all for your help! I had to make a couple tweaks to Russell Zahniser's comment for it to work for me:
Changed $('#accountTable > th') to $('#accountTable thead th')
Changed aoColumns.push(sType ? sType : null) to aoColumns.push(sType ? { "sType" : "currency" } : null)
End result:
var aoColumns = [];
$('#accountTable thead th').each(function() {
var sType = $(this).getAttribute("data-sType");
aoColumns.push(sType ? { "sType" : "currency" } : null);
});
$('#accountTable').dataTable({
...
"aoColumns": aoColumns
});

Categories

Resources