DataTables logo DataTables

via Ad Packs
localStorage for state saving and updates in 1.9
  • Hello all,

    I've just posted a new blog entry describing the state changing API changes that are in DataTables 1.9 and showing how the new state saving API can be used very easily for saving your table's state with localStorage: http://datatables.net/blog/localStorage_for_state_saving .

    Enjoy,
    Allan
  • 24 Comments sorted by
  • Yeah, thanks a lot! :-)
  • This is fantastic... ofcourse the curse of IE7 continues,

    http://datatables.net/beta/1.9/examples/advanced_init/localstorage.html throws an error localstorage is undefined... looks gr8 on FF and chrome... waiting to get my hands on the new state saving functions
  • It would do yes, since localStorage isn't available in IE7-. Probably the easiest thing to do would be to check for the localStorage object in the state saving code and just discard the state in IE7-. If the user has a rubbish old browser, then they aren't going to get the cool new features :-). The alternative is to use the built in cookie saving as a callback by calling those functions.

    waiting to get my hands on the new state saving functions

    Already available in 1.9.0 :-)

    Allan
  • Great new changes. In the post you link to you said, "note that as such this will not work in browser which do not support localStorage". Searching for a cross-platform solution for persistent storage, I noticed a lot of people on StackOverflow recommending PersistJS: http://pablotron.org/?cid=1557
    This small plugin uses flash, gears, localstorage, whatwg_db, globalstorage, cookie, etc. transparently.

    Example:
    var store = new Persist.Store('My Data Store');
    var data = "pretend this is really long data that won't fit in a cookie";
    store.set('saved_data', data);
    

    Unfortunately, the get() method is... peculiar in that it is asynchronous (the reason being, I quote, "It turns out that some backends -- specifically the WHATWG Database (used for Safari 3.1) -- only function asynchronously, so using a callback function is the only reliable means of ensuring the correct order of operations").

    Example:
    store.get('saved_data', function(ok, val) {
      if (ok)
        alert('saved data = ' + val);
    });
    

    I was wondering if you could advise me how I could make that work with fnStateLoad()? fnStateLoad is a callback, from which you return a value. The issue is that from that callback I will need to call get() itself with an anonymous/async function, from which I can't quite return anything in the same scope.

    Recommendations?
    Thanks!
  • Unfortunately, the get() method is... peculiar in that it is asynchronous

    That's very unfortunate because at the moment DataTables requires that the state loading function give be synchronous - there is currently no callback method available for this function at the moment. Changing it could of course be done, but its not trivial in the DataTables core since the constructor is expecting the function to be synchronous.

    The only option I've really got to suggest, without changing the DataTables core (which of course I am willing to do, but it will take a bit of time), is to load your settings object first, then initialise your DataTable on the callback. Then you can use fnStateLoad to return the object that was loaded. The only downside is that the table will be uninitialised for that extra period of time while the state is being loaded.

    Allan
  • Thanks Alan. I switched from PersistJS to jStorage. That covered enough bases.
    http://www.jstorage.info/
  • Hey Allan I'm trying these new save/load callbacks from the examples (fnStateLoad seems to have the wrong signature in the docs) but I'm implementing something pretty similar to this. I have checked my object o that is returned at the end and it looks ok, but the table seems to ignore the visibility flags that are in the data. Is there something I need to do to get around this? Also I'm wondering if I need to do anything extra to have the table remember column order etc with the plugins on the table or if I can just return the serialized oData object and the plugins will know what to do with it.

    "fnStateLoad": function (oSettings) {
    var o;

    // Send an Ajax request to the server to get the data. Note that
    // this is a synchronous request.
    $.ajax( {
    "url": "/state_load",
    "async": false,
    "dataType": "json",
    "success": function (json) {
    o = json;
    }
    } );

    return o;
    }
    } );
  • fnStateLoad seems to have the wrong signature in the docs

    This is a bug in the docs which is fixed in the git repo, but because the docs are tired to each release, it will be the 1.9.1 before the docs on the site are updated.

    I have checked my object o that is returned at the end and it looks ok

    That looks okay to me as well - can you link me to your page please, so I can see what might be happening.

    Also I'm wondering if I need to do anything extra to have the table remember column order etc with the plugins on the table or if I can just return the serialized oData object and the plugins will know what to do with it.

    Assuming the state loading works okay, then the ColReorder plug-in should deal with restoring state, since it hooks into the DataTables state saving API.

    Allan
  • I'm just working locally right now unfortunately, our software is for download (and is web based) so I don't really have this current version hosted anywhere. I'll see if we have some kind of QA server I can upload this to in the meantime. Neither the ColVis nor the ColReorder plugins seem to be able to get their state back though, it just defaults to all columns being visible even if I can see false returned in the config object for bVisible. Things like the # of displayed rows (10, 25, 50) are able to restore though.
  • hey until I can hopefully host this somewhere can you tell me if iCreate is important in the saving/loading process? fnStateSave seems to be fired twice most times when I'm selecting or deselecting a column using the ColVis plugin.
  • hey Allan

    http://airtime-dev.sourcefabric.org/ here is a public dev version of the site. The table I'm trying to save/load using a db storage is on the page "playlist builder" The fnSaveState and fnLoadState are written in library.js starting around line 226.
    Thanks again if you could take a look at it!
  • hey I figured it out

    oData.abVisCols it gives you an array like ["true", "false"], but to actually load properly the values need to be actual booleans [true, false] etc or of course it was just thinking "false" was actually true so I always got all my columns loading.
  • Hi - thanks for putting up the example! Great to hear you've got a solution - I'm slightly confused though, DataTables is storing boolean values in its state saving from what I've just tested, or is there a conversion to a string somewhere in in your code, or am I missing something completely!?

    Allan
  • oh sorry about that just checked again, yes it wasn't any fault of datatables, just when the data was sent to the server to save the settings all the booleans were turned into strings (used php's serialize after I got the request data with ZF). So annoying! Anyways it's working great now :D
  • That's most frustrating - and I suspect not a valid thing to do for a "strict" JSON parser.... true !== "true" :-).

    Anyway - great to hear you've got it sorted out!

    Regards,
    Allan
  • Is there a simple way to 'go back' to the old way of storing? I know cookies aren't nice but unfortunately I need to support IE7 so local storage isn't a possibility.
  • Would it be possible to save the state in the app database? Then you could have a list of views to select.
  • Yes absolutely - no reason why that wouldn't be possible :-)

    Allan
  • Since I set the option to save the state of the DataTables (in the old way), I'm having trouble. Sometimes, my application crashes (getting the error 502 - Bad Request) and I found out that is some kind of cookie problem.

    So now I'm trying to change this to localStorage, but my DataTable isn't storing the external filters (which I have created manually and I'm using them with aoData.push method). How can I make the DataTable to store these filters too?

    Thanks
  • error 502 - Bad Request

    Sounds like the cookie is too large - there should be protection in DataTables to stop that, but 4KiB isn't much - if you have a lot of columns then it can overflow.

    my DataTable isn't storing the external filters

    DataTables will store column filters applied by fnFilter (is that what you are using?), but it won't restore them, since it knows nothing about your input controls. You would need to use fnStateLoadParams to get the saved parameters and display them in the document.

    Allan
  • Yes, I'm using fnFilter to filter my table.

    Is there a way that I can solve the problem of the error 502 without change the entire system to localStorage? Or change is the best workaround?

    Thanks
    Thiago
  • You could use fnStateSaveParams to remove the parameters that you don't want to be saved from the data object that will be stored in the cookie - that would certainly help. But ultimately yes localStorage is a much better option.

    How many columns do you have in your table? As I say, DataTables should have protection code that stops it breaking, but it sounds like there might be a bug in there.

    Allan
  • My datatable has only 6 columns, but yes, I can remove 3 of them if I need.

    Otherwise, I'll change my application to use this localStorage functionality.

    Thanks for the help.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Support

Get useful and friendly help straight from the source.

In this Discussion