Discard saved state accross postbacks with different data

Discard saved state accross postbacks with different data

sd_zuosd_zuo Posts: 78Questions: 1Answers: 0
edited August 2010 in General
I've set the bStateSave = true to keep the status of a DataTable, which is generated from database queries.

A user inputs "abc" in the search box, posts the form, then result A is returned and filled into the table. The user pages down to page 3. He can click a link in the table and navigate to another page to see the detail of the corresponding item, and then hit the "Back" button of the browser. When he comes back, page 3 is displayed since bStateSave = true.
Here's our problem:
After the user goes to page 3, he inputs "xyz" in the search box, and posts the form on the same page again. Result B is returned at this time. When bStateSave is true, the table will display page 3 of the result of "xyz" instead of the first page of the result. However, the user wants to see page 1 first, since he has posted a new query.

How to meet this requirement?

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    What you would need to do is to delete the cookie from the browser when this state occurs. Another option might be to notice that state and set bStateSave to false when it occurs at initialisation time.

    Allan
  • sd_zuosd_zuo Posts: 78Questions: 1Answers: 0
    edited August 2010
    Thanks for the reply. I can detect the number of records before each initialization, since the result set is queried from the database and filled to the client-side JavaScript as an array. I'll use one more cookie to record the number of records and use it to set bStateSave accordingly.
  • sd_zuosd_zuo Posts: 78Questions: 1Answers: 0
    I met with another problem.
    As I set the bStateSave = false in order to prevent the previously saved state from being loaded, I still need DataTable to save the new state for the next time's use.
    Is there any API can be used to save the state manually even when bStateSave = false?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    What you would need to do is basically what the internal state saving does - which is to store the 'interesting' variables from the settings object in the cookie, and then when needed, read the variables out of the cookie and into a settings object. So there is an API there, although not really designed for that... :-)

    I think (although I've not actually tried it) that state saving could be enabled during run time, if that would help? ...fnSettings().oFeatures.bServerSide = true might do it - after DataTables has be initialised.

    Allan
  • sd_zuosd_zuo Posts: 78Questions: 1Answers: 0
    Maybe the state saving flag can be enabled after initialization, however, the state saving function is not called after that. We need to activate that function. It appears no API does the job.

    The work flow of this problem is like the following:
    1, User enters a search page.
    2, User fills in the query form and submits the form.
    3, Result set is returned and a DataTable is filled.
    4, Since the table is displayed at the first time, the state is saved, and the number of records are recorded as cookie (_prevNum).
    5, User fills the query form again to perform another query.
    6, New result set is returned and the DataTable is filled with new data.
    7, Since the table is loaded the second time, and the number of records at this time does not equal to _prevNum, so the state is not loaded.
    8, After the DataTable is initialized the number of records are stored into cookie (_prevNum).
    9, And the new state is saved overwriting the previous cookie.

    I studied the source code and found that in step 7, bStateSave can be used to 1) load previously saved state, and 2) hook _fnSaveState on each table redrawing. If the flag is turned off, the state is not loaded, but the _fnSaveState function is not hooked and no state saving afterward.

    If there's a flag bStateLoad (default = bStateSave), and the state will not be loaded if the flag is false, but the new state is still saved. Everything afterward is settled.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Hmm yes it is a little more complicated these days (I'd forgotten about the change I made to the draw callbacks...).

    Something like this might do the job (although it's untested :-) ):

    [code]
    var oTable = $(...).dataTable(...);
    oTable.fnSettings().aoDrawCallback.push( {
    "fn": oTable.oApi._fnSaveState,
    "sName": "state_save"
    } );
    [/code]
    Allan
  • sd_zuosd_zuo Posts: 78Questions: 1Answers: 0
    edited August 2010
    Oh, yes. Thanks for replying.
    We've got to use the "private" API _fnSaveState in this case :)
    I guess that it won't harm to make _fnSaveState a public API.
    Here's the code I am using
    [code]
    $(function() {
    var prevCount = Cookie.Get(window.location.pathname);
    $("#Results").css("width", "100%").dataTable({
    "aaData": d,
    bStateSave: d.length > 0 && (prevCount == null || prevCount == d.length.toString()),
    ....
    });
    if (d.length > 0) {
    var dt = $("#Results").dataTable();
    if (d.length != prevCount && !dt.fnSettings().oFeatures.bStateSave) {
    dt.fnSettings().oFeatures.bStateSave = true;
    dt.fnSettings().aoDrawCallback.push( {
    "fn": dt.oApi._fnSaveState,
    "sName": "state_save"
    });
    }
    Cookie.Set(window.location.pathname, d.length.toString());
    }
    });
    [/code]
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Good stuff - thanks for posting your code.

    Yes it could be made a 'first class' public function - although it is public at the moment in a way... Something for me to consider in future.

    Allan
This discussion has been closed.