Reputation: 282885
I'm extending the DataTables defaults like so:
$.extend(true, $.fn.dataTable.defaults, {
lengthChange: false,
deferRender: true,
displayLength: 25,
stateSave: false,
serverSide: true,
processing: true,
ajax: {
type: 'POST',
error: function($xhr) {
if($xhr.status === 401) {
wxu.openLoginBox(function(data) {
// HELP: how can I get the DataTables object from this context?
});
} else {
wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
}
}
}
});
Sometimes a user will get logged out and then when they try changing pages or sorting, it just says "Processing" forever. I can catch this by looking for a 401
error response (this is what my app sends when you've been timed out), but then I don't know how to "refresh" dataTables to make the "Processing" message go away so that you can resume using the app.
Please note that I'm extending the defaults here in a .js
file -- I don't know what element DataTables is going to be bound to at this point.
How can I "fix" dataTables from inside the ajax/error callback?
Upvotes: 3
Views: 6342
Reputation: 58880
NOTES
You should not override ajax.error
since this property is used internally by DataTables, the same applies to ajax.success
.
SOLUTION
You can add event handler for xhr
event to handle Ajax errors (json === null
).
// Prevent alert message from being displayed
$.fn.dataTable.ext.errMode = 'none';
// Use delegated event handler
// to handle Ajax request completion event
$(document.body).on('xhr.dt', function (e, settings, json, xhr){
// If there is an Ajax error and status code is 401
if(json === null && xhr.status === 401){
var api = new $.fn.dataTable.Api(settings);
console.log('Session expired');
/*
wxu.openLoginBox(function(data){
api.ajax.reload();
});
*/
} else {
console.log('Could not load list');
/*
wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
*/
}
});
DEMO
See this jsFiddle for code and demonstration.
Upvotes: 3
Reputation: 4030
Per the documentation, ajax
can be a function. It is called with the table settings object, which can be used to construct a new API object for the table. Then, you can just use the API method to get the processing element (using .dataTables_processing
) or take whatever other action you like using the other available API methods. Concretely, something like this should work:
{
"ajax": function (data, callback, settings) {
$.ajax({
type: "POST",
success: function (json) {
callback(json);
},
error: function ($xhr) {
if ($xhr.status === 401) {
var api = new $.fn.dataTable.Api(settings);
var container = api.table().container();
$(container).find('.dataTables_processing').hide();
}
}
});
}
}
I don't see it documented specifically, but this
is also set to the DataTable object in the ajax
function when it is called. Using that could be a more direct route to your goal, but I think the above aligns more with the intended use.
Upvotes: 2