Loaded State Is NOT Overwriting The Current DOM DataTables State
Loaded State Is NOT Overwriting The Current DOM DataTables State
I have a JQuery Datatables application that I’m trying to load the state from a database with a button click. During the button click event, I retrieve the desired state (oData) from one database table (tblSavedStates), and then I overwrite the state (oData) value in another database table (tblState) which holds the saved state of my web page. Next, I reload the web page and the “stateLoadCallback” function retrieves the new saved state (oData) value from the database. However, I cannot get the “stateSaveCallback” function to save the correct state (the one returned by the “stateLoadCallback” function) into the database. It just saves the current state of the DOM object and not the retrieved state. I’m currently using version 1.10.1 and here’s a snippet of my JQuery code:
// Initialization
var oTable = $('#mytable').dataTable({
"dom": 'RC<"clear">lfrtip',
"processing": true,
"serverSide": true,
"ajax": baseurl + "MyController/IndexAjaxHandler?someId=" + someId,
"sServerMethod": "POST",
"stateSave": true,
"stateSaveCallback": function (oSettings, oData) {
/* Save the oData in the database */
$.ajax({
type: 'POST',
data: { url: $(location).attr('href'), oData: JSON.stringify(oData)},
dataType: "json",
async: false,
url: baseurl + 'MyController/SaveOData',
success: function (data) {
},
error: function () {
}
});
},
"stateLoadCallback": function (oSettings) {
/* Get the oData from the database */
var oData;
$.ajax({
type: 'POST',
async: false,
data: { url: $(location).attr('href') },
url: baseurl + 'MyController /GetOData',
success: function (data) {
oData = data.oData;
},
error: function () {
}
});
/* If returned oData is not an empty string, then parse it */
if (oData != '') {
return JSON.parse(oData);
}
},
This question has an accepted answers - jump to answer
Answers
Update - After some searching, I found a post that mimics my issue and how the returned state is being ignored.
http://datatables.net/forums/discussion/21894/problems-with-statesavecallback-and-stateloadcallback#
Any help would be greatly appreciated.
Looks like it should work. Can you link to the page in question so I can debug it please?
Thanks,
Allan
Thank you Allan for taking the time to assist me. I cannot post a link to my code but I'll try my best to describe the situation.
I'm loading the saved state from the database with a button click and it's returning the correct state during the “stateLoadCallback” function. However, during the “stateSaveCallback” function it's not overwriting the DOM state. After further review, I discovered that the search, sort and paging is working as expected but the column visibility in the returned state is not being honored. Here's some additional code:
Also, here's the order of events after the button click event:
1) "stateLoadCallback" event
2) "fnServerParams" event
3) "stateSaveCallback" event
4) "initComplete" event
Is this after the DataTable has initialised? The state can only be loaded during initialisation. There isn't an API method at the moment to restore a state once the table has been constructed.
So the state is loading (in which case you can ignore my above comment), and only the column visibility is being ignored? Are you using Responsive perhaps? I'm afraid I'm really only guessing without being able to see the problem.
Allan
I'm not using Responsive. During the button click event, the database is replacing the saved state and then I reload the page. So, the table is initialised one time. During the "stateLoadCallback" event, the returned state has the correct column visibility value for each column but they're not being applied to the DOM object. How can I accomplish this task?
State saving should take the column visibility into account - I've just put together a little example together showing this.
To see it in action, use ColVis to hide the "Name" column and then click the "Run with JS" button which is basically a reload. The "Name" column will still be hidden.
I'm afraid I would need a test page showing the issue to be able to help much more than that as i don't know what is going wrong.
Allan
I'll try to recreate a scaled down version of my application in a JS Bin test page.
@allan
Update - After hours of debugging, I finally identified the issue. When I saved the state (oData) into the database, a timestamp, the "time" value, would be created at that time. Well, the "_fnLoadState" function in the API has a code check to reject old data (state) if the iStateDuration is greater than zero and the state.time (retrieved "time" value") is less than the current datetime minus the iStateDuration multiplied by one thousand. Here's the code check:
To test my theory, I edited the timestamp value of my saved state in the database table and voila!, it worked.
So, what's the best way to handle this issue? Should I overwrite the timestamp values of my saved states to a value of "9999999999999" when I save them into the database or do you have a better workaround?
So just to check - DataTables is throwing away the data because it is stale? You could use
stateDuration
to have a longer state duration if you want - set it to a year perhaps. Or 100 years if needed.The alternative is to override the state data which you could also do.
Allan
Yes. The "_fnLoadState" function is throwing away the data because it's stale but in my case it's not stale.
In which case, is the
stateDuration
option the correct one to use? If you want to change the duration for which the data is valid for, then I think that would be the best way of doing it as that is what it is designed for.Allan