I'm using datatable to show list from database mysql
I need to update some input on end of table loading, then I'm using success function but this seems to prevent data rendering
var table = $('#example').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
type: 'POST',
'url': url,
'data': function (d) {
console.log(d.order);
return JSON.stringify( d );
},
// EDIT this "my" success function
success: function( data ) {
$('#my_input').val(data.return);
}
}
Json returned is:
{
"data":[[ (datatable value) ]],
"returned":"myvalue"
}
here the jsfiddle
EDIT
http://jsfiddle.net/ntcwust8/95/
Datatable has its own complete event thats called initComplete.
If you redefine success you are overriding Datatable's own function.
var table = $('#example').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
....
....
},
'initComplete':function(settings, json){
alert($('#example tbody tr').length+ ' records on screen');
});
Reference: https://datatables.net/reference/option/initComplete
Update fidle: http://jsfiddle.net/ntcwust8/94/
Just remove the success callback.
success - Must not be overridden as it is used internally in
DataTables. To manipulate / transform the data returned by the server
use ajax.dataSrc (above), or use ajax as a function
Datatable by default handles the success callback, Don't override it.
Instead use complete option of AJAX to do something after data loading.
Updated fiddle
You just need to remove success callback.
var table = $('#example').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
type: 'POST',
'url': url,
'data': function (d) {
console.log(d.order);
return JSON.stringify( d );
}
}
Edit
you need to use ajax.dataSrc property it will call after ajax finish.
It will work on refresh as well
https://datatables.net/reference/option/ajax.dataSrc
var table = $('#example').DataTable({
'ajax': {
type: 'POST',
'url': url,
'data': function (d) {
console.log(d.order);
return JSON.stringify( d );
},
"dataSrc": function (json) {
$("#mydata").val(json.recordsTotal);
return json.data;
}
},
});
here is updated fiddle.
http://jsfiddle.net/2jkg3kqo/2/
Related
I'm trying to add <tr/> tags dynamically to a DataTable, but I didn't find actual good documentation on how the "adding TR process" is supposed to work. I have this as my DataTables setup:
$("#Grid").DataTable({
stateSave: true,
fixedHeader: true,
rowReorder: true,
.
.
columnDefs: [
{ orderable: false, className: "seq-cell", targets: 0 },
{ orderable: false, targets: "_all" }
]
})
.on("row-reordered", function (e, diff, edit) {
for (var i = 0; i < diff.length; i++)
{
..
}
});
I'm getting the definition of the item in the grid from an MVC action method as an HTML string, via a jQuery AJAX statement:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
var $body = $("#Grid tbody");
$body.append(d);
}
});
The "d" parameter is the HTML for a row; I'm appending it to the body. That adds correctly and but doesn't have the row reorder functionality enabled then. What is the proper way to append to a DataTable, then re-enable whatever functionality?
Use row.add() API method to add a new row instead of appending to the table body.
If d contains string in the following format <tr>...</tr>, you could just use $("#Grid").DataTable().row.add($(d).get(0)) to add a new row.
For example:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
$("#Grid").DataTable().row.add($(d).get(0)).draw();
}
});
See this example for code and demonstration.
The best option is to use Datatables API's to add rows to the table. As indicated in the previous response you can use either row.add() or rows.add(). The data needs to be in a data structure that matches your Datatables data structure config, ie, arrays or objects.
However it looks like you are receiving HTML structured data and appending directly to the table. In this case Datatables is not aware of the added data. You will need destroy (destroy()) the Datatables table, append your data then re-init Datatables. For example:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
$("#Grid").DataTable().destroy();
var $body = $("#Grid tbody");
$body.append(d);
$("#Grid").DataTable({
stateSave: true,
fixedHeader: true,
rowReorder: true,
.
.
columnDefs: [
{ orderable: false, className: "seq-cell", targets: 0 },
{ orderable: false, targets: "_all" }
]
})
}
});
I initialized the DataTable in a variable:
var dataTable = $("#selector").DataTable({
processing: true,
serverSide: true,
ajax: $.fn.dataTable.pipeline({
dataType: "json",
url: "/path/ajaxurl",
data: {
"fruits": "apple",
"veggies": "banana",
},
dataSrc: "data"
}),
sPaginationType: "extStyle"
});
Now, somewhere in my script I have this checkbox that when changed will add a new data on the ajax above then initialize the draw():
$(document).on("change", "#add-some-liquors", function(e) {
// some validations here
// My attempt to add this data
dataTable.data({"drinks" : "coca-cola"});
// Draw the dataTables
dataTable.clearPipeline().draw();
});
Seems that dataTable.data({"drinks" : "coca-cola"}); does not add the drinks on the POST when I checked on the backend, I only get the apple & banana which is the two default initialized data. What am I missing?
According to the API .data method is only for retrieving. Try holding data in a variable, updating that object and then using it in .ajax method.
var items = {}
ajax: $.fn.dataTable.pipeline({
dataType: "json",
url: "/path/ajaxurl",
data: items,
Declare your data as a variable and add the drinks value later.
var data = {
"fruits": "apple",
"veggies": "banana",
};
console.log(data);
//On the click event
$('#chk').on('click', function() {
if ($(this).is(':checked')) {
data['drinks'] = 'coca-cola';
} else {
//When unchecking the option, set it's value to null
data['drinks'] = null;
//Or delete the property.
//delete data['drinks'];
}
console.log(data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="chk" />
The ajax.data object can be initialized as a function. The function will be evaluated each time the data is fetched. In this example, the value of the global variable selectedDrink will be sent with the ajax request as the drinks field.
var selectedDrink = "";
var dataTable = $("#selector").DataTable({
processing: true,
serverSide: true,
ajax: $.fn.dataTable.pipeline({
dataType: "json",
url: "/path/ajaxurl",
data: function(d) {
d.fruits = "apple";
d.veggies = "banana";
d.drinks = selectedDrink;
},
dataSrc: "data"
}),
sPaginationType: "extStyle"
});
$(document).on("change", "#add-some-liquors", function(e) {
selectedDrink = "coca-cola";
// Draw the dataTables
dataTable.clearPipeline().draw();
});
How to use dataTables to instantiate the table does not load data (server mode),then loading data when i click on a button.If serverSide is set to true at initialization, the table will automatically send an ajax request, then render the data, which is not what I want !:(
You should use "iDeferLoading" : 0 in DataTables parameters, when you initialize it:
var table = $("#table").dataTable({
"bProcessing": true,
"bServerSide": true,
"iDeferLoading": 0,
"sAjaxSource": service_url,
"sServerMethod": "POST",
...
...
(or "deferLoading":0 for newer DataTables versions, 1.10 and above),
and then add the event to your button:
$("#button").on("click", function (event) {
$('#table').dataTable().fnDraw();
});
https://datatables.net/examples/server_side/defer_loading.html
in a similar situation, this is how I did it.
<script>
$(function ($) {
$("#tbl").DataTable({columns:[{data:"id"}, {data:"text"}], dom: "tB", buttons: [{ text: "Load Me", action: function (e, dt, node, config) { loadme(e, dt, node, config); } }] });
}
);
// // parameters are passed from the datatable button event handler
function loadme(e, dt, node, config) {
parms = JSON.stringify({ parm1: "one", parm2: "two" });
$.ajax({
// my test web server that returns an array of {id:"code field", text:"country namee"}
url: "WebService1.asmx/GetAList",
data: JSON.stringify({ s: parms }),
type: 'post',
contentType: "application/json; charset=utf-8",
dataType: "json",
// this is just away of passing arguments to the success handler
context:{dt:dt, node:node},
success: function (data, status) {
var contries = JSON.parse(data.d);
for (var i = 0; i < contries.length; i++){
this.dt.row.add(contries[i], "id", "text");
this.dt.draw();
}
},
error: function (one, two) {
debugger;
}
});
}
</script>
</head>
<body>
<div style="width:500px">
<table id="tbl">
<thead>
<tr>
<th>Code</th>
<th>Contru</th>
</tr>
</thead>
<tbody></tbody>
<tfoot></tfoot>
</table>
</div>
</body>
After looking at the source code for half a day, I finally found a solution. First I needed a custom parameter called firstAjax and set it to false. like this:
$("#example").DataTable({
serverSide: true,
ajax: {
url: 'your url'
},
firstAjax: false
});
Then I changed the
_fnReDraw (settings); //in datatables.js line 4717
to
if (settings.oInit.firstAjax) {
_ fnReDraw (settings);
}
If the compressed js file(datatables.min.js), you should find _fnReDraw function corresponding alias.
I found the solution, in the initialization make like this, with the "oLanguage":
$('.table').dataTable({
oLanguage: {
sUrl: ""
}
});
After initialize datatables with ajax, use this simple line to call ajax for get data:
$('#table').DataTable().ajax.reload();
this code may not working with old versions of datatables.
Download latest version: https://datatables.net/download
Not only should this be a straightforward operation but I'm following the documentation as well. I have an ajax call that returns a json data set. I've cleared the table successfully but when the success method is called nothing happens. The console statement shows that data is being returned... however the table remains empty. Any idea why?
JS
$('#SortByCoverage').click(function () {
var table = $('#theTable').DataTable();
table.fnClearTable();
$.ajax({
url: '/Home/Question2',
type: 'GET',
dataType: 'json',
success: function (data) {
console.log(data);
$("#thetable").dataTable({
"aaData": data,
"aoColumns": [
{title:"AdId"},
{title:"BrandId"},
{title:"BrandName"},
{title:"NumPages"},
{title:"Position"}
]
});
}
});
Server Side Code
public JsonResult Question2()
{
var ads = _client.GetAdDataByDateRange(new DateTime(2011, 1, 1), new DateTime(2011, 4, 1));
var json = ads.Where(x => x.Position.Equals("Cover") && x.NumPages >= (decimal)0.5).Select(x => new{
AdId = x.AdId,
BrandId = x.Brand.BrandId,
BrandName = x.Brand.BrandName,
NumPages = x.NumPages,
Position = x.Position
});
return Json(json, JsonRequestBehavior.AllowGet);
}
Sample Data (client side)
EDIT
As pointed out in the comments I misspelled the element name dataTable in the success callback. However, now I'm getting the following error:
Cannot reinitialise DataTable. To retrieve the DataTables object for this table, pass no arguments or see the docs for bRetrieve and bDestroy
Do I really have to destroy the table, once it's clear, to reload the data?
I added the bRetrieve and bDestroy. This got rid of the error but still no new data loaded into the table.
$.ajax({
url: '#Url.Action("Question2", "Home")',
type: 'GET',
dataType: 'json',
success: function (data) {
console.log(data);
$("#theTable").dataTable({
//"bRetrieve": true,
"bDestroy": true,
"aaData": data,
"aoColumns": [
{title:"AdId"},
{title:"BrandId"},
{title:"BrandName"},
{title:"NumPages"},
{title:"Position"}
]
});
}
});
I would make a little different, see how:
var theTable = $("#thetable").dataTable({
"aaData": [],
"aoColumns": [
{data:"AdId"},
{data:"BrandId"},
{data:"BrandName"},
{data:"NumPages"},
{data:"Position"}
]
}).DataTable();
$('#SortByCoverage').click(function () {
$.ajax({
url: '/Home/Question2',
type: 'GET',
dataType: 'json',
success: function (data) {
theTable.clear().draw();
table.rows.add(data)
.draw();
}
});
I'm trying to use DataTables with a success callback. Because I want to give a user a warning if the values they entered that creates a DataTable has an error.
Unfortunately, DataTables requires success callback for themselves, hence I cannot overload it.
Currently the code is:
configurationBlockChart = $('#blockSearchTable').DataTable(
{
processing: true,
serverSide: true,
stateSave: true,
bDestroy: true,
ajax:
{
type: 'GET',
url:"ajax_retreiveServerSideBlockNames/",
data:
{
'csrfmiddlewaretoken':csrftoken,
'username':username
}
},
rowCallback: function(row, data)
{
if ($.inArray(data.DT_RowId, blockSelected)!== -1)
{
$(row).addClass('selected');
}
},
});
The data that is returned by this Ajax Get are rows of data.
However, there is a possibility that the data returned has a response of invalid, with no rows returned
I tried to add success before rowCallBack:
success: function(response)
{
if(response.status == "invalid")
//then inform user
}
Also tried to use fnDrawCallBack
fnDrawCallback: function(settings, response)
{
console.log("Hello World!");
if(response.status == "invalid")
{
$('#invalid').modal("show");
$('#usernameSearch').modal("show");
}
}
However, the fnDrawCallBack will only call if there are rows returned.
The problem is that sometimes that no rows are returned, and an exception is given by the javascript code.
I could, however, do a try catch, but I would still like my server to give json statuses to the javascript code.
EDIT: With using xhr, it could catch that invalid response while in the meantime does not interfere with the success function for ajax.
$('#chartSearchUsername').click(function(event)
{
$('#chartConfigModal').modal("hide");
$('#usernameSearch').modal("show");
configurationUserChart = $('#userSearchTable').DataTable(
{
processing: true,
serverSide: true,
stateSave: true,
bDestroy: true,
ajax:
{
type: 'GET',
url:"ajax_retreiveServerSideUsernames/",
data:
{
'csrfmiddlewaretoken':csrftoken
},
},
rowCallback: function(row, data)
{
if ($.inArray(data.DT_RowId, userSelected)!== -1)
{
$(row).addClass('selected');
}
},
})
.on('xhr.dt', function(e, settings, response)
{
if(response.status == "invalid")
{
$('#invalid').modal("show");
$('#usernameSearch').modal("hide");
}
});
});
$('#example').dataTable();
$('#example').on( 'xhr.dt', function () {
console.log( 'Ajax call finished' );
} );
jQuery datatables is coded to use the success callback in ajax and it breaks if you intercept it. Source
You can also make use of jQuery ajax dataFilter callback.
$('table[id=entries]').DataTable({
processing: true,
serverSide: true,
ajax: {
type: 'POST',
url: 'http://example.com/entries',
dataFilter: function(response) {
var json_response = JSON.parse(response);
if (json_response.recordsTotal) {
// There're entries;
}else{
// There're no entries;
}
return response;
},
error: function (xhr) {
console.error(xhr.responseJSON);
}
}
});
Note: Return a String, not JSON in dataFilter callback.