Getting bStateSave to work with Ajax datasource + ColVis + TableTools

Getting bStateSave to work with Ajax datasource + ColVis + TableTools

maartenmachielsmaartenmachiels Posts: 13Questions: 0Answers: 0
edited September 2013 in General
Hi

I'm working on a CRM-project in which I use Datatables in combination with Colvis and TableTools. Also, I have implemented Individual Column Filtering (http://www.datatables.net/release-datatables/examples/api/multi_filter.html). I'm using AJAX JSON as datasource (not serverside processing). I'm using the latest version of DataTables (1.9.4) and plugins in combination with jQuery 1.9.1.

Now, using this setup, I am unable to get statesaving to work. My console does not mention any relevant errors (apart from some missing images warnings). Is statesaving possible in this setup and, if yes, could you please have a look at my source?

http://cmcrm.chocolata.be
username testuser
password 123456

If you click on "People", there you will find my datatable. Thanks in advance!

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Hi,

    Thanks for the link! The debug trace for your table says that there are 38 columns, so I'm reasonably certain that the problem is that the amount of information needed to be stored is greater than 4KiB - the cookie limit.

    So there are two immediate options that come to mind:

    1. Use localStorage as described in this blog post: http://datatables.net/blog/localStorage_for_state_saving

    2. Try DataTables v1.10 from the 1_10_wip branch in git. It uses localStorage rather than cookies for state saving.

    Regards,
    Allan
  • maartenmachielsmaartenmachiels Posts: 13Questions: 0Answers: 0
    Hi Allan

    Thank you so much for your expert answer. I had no clue the cookie size limit is 4KiB! Statesaving via localstorage does fix the problem completely. I have used your first suggestion.

    Very easy and practical solution. Find [code]"bStateSave": true,[/code] and add the following after it:
    [code]
    "fnStateSave": function (oSettings, oData) {
    localStorage.setItem( 'DataTables_'+window.location.pathname, JSON.stringify(oData) );
    },
    "fnStateLoad": function (oSettings) {
    return JSON.parse( localStorage.getItem('DataTables_'+window.location.pathname) );
    },
    [/code]

    Thanks so much!
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Excellent to hear that worked!

    Allan
  • maartenmachielsmaartenmachiels Posts: 13Questions: 0Answers: 0
    It's incredible how well it works. Even ColVis remembers the state! Really impressive.

    One slight snag though: the input fields below each column do not show the mentioned keyword after reload. Is there a quick solution for this, or is this a known issue?

    [code]
    function columnstatechange(){
    $("tfoot input").keyup( function () {
    var oSettings = oTable.fnSettings();
    var renderedIndex=$("tfoot input").index(this);
    var hiddenColumnsCount=0;
    var aoColumns=oSettings.aoColumns;

    for (i=0; i<=renderedIndex+hiddenColumnsCount; i++) {
    if (!aoColumns[i].bVisible) hiddenColumnsCount++;
    }
    oTable.fnFilter( this.value, renderedIndex+hiddenColumnsCount );
    } );
    $("tfoot input").focus( function () {
    if ( this.className == "search_init" ) {
    this.className = "";
    this.title = this.value;
    this.value = "";
    }
    } );
    $("tfoot input").blur( function (i) {
    if ( this.value == "" ) {
    this.className = "search_init";
    this.value = this.title;
    }
    } );
    }
    [/code]
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Because those controls are external from DataTables, it knows nothing about them and thus cannot automatically restore the values for you. What to do is to use the fnStateLoadParams option which will give you the data loaded in the state load and you can populate the input elements that way.

    Regards,
    Allan
  • maartenmachielsmaartenmachiels Posts: 13Questions: 0Answers: 0
    Thanks for pointing me in the right direction. I've created the following solution. Haven't been able to test very thoroughly, but it seems to work well.

    Firstly I've numbered the input fields at the bottom of my table columns on serverside via a custom attribute "data-colno". My inputs now look like this:
    [code]

    [/code]
    Then, using the "fnStateLoadParam" param, I've looped over all the inputs with classname "search_init", matching the "data-colno" attribute to the actual column numbers that you refer to in oData. The final code is the following:
    [code]
    "fnStateLoadParams": function (oSettings, oData) {
    $(oData.aoSearchCols).each(function(index,value) {
    if(value.sSearch != '') {
    $("input.search_init[data-colno='" + index + "']").val(value.sSearch);
    }
    });
    },
    [/code]

    So, I loop over oData, returned by fnStateLoadParams, matching the column numbers to my custom attribute I have set serverside, and setting the value of the input to the value in localstorage! Cool, isn't it? Any remarks?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Very nice :-). Looks good to me!

    Allan
  • maartenmachielsmaartenmachiels Posts: 13Questions: 0Answers: 0
    Super! Thanks for all your help!
This discussion has been closed.