stateLoadCallback - Specify table to reload state only when column visibility is updated

stateLoadCallback - Specify table to reload state only when column visibility is updated

ad824aad824a Posts: 20Questions: 4Answers: 1
edited March 2021 in DataTables 1.10

Hi,

Is there a way to set the stateLoadCallback to only reload the state when the column visibility is updated? I do not want to save/ load the state of the table when column filters are updated

This question has accepted answers - jump to:

Answers

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    The easiest way would be to have a function in stateLoadParams which deletes out of the object anything you don't want to have an effect. You could do the same with the save with stateSaveParams but that would be called more often,

    Colin

  • ad824aad824a Posts: 20Questions: 4Answers: 1

    Hi Colin thanks for the help. I already deleted data.search using stateSaveParams and I deleted data.columns.search before the ajax call in stateSaveCallback:

    `

      "stateSaveCallback": function (settings, data) {//specifies saving the state of the table externally rather than in localstorage
        //remove search values from every column
        for (const column in data.columns) { //I do not want to save the search criteria to the database. It could make the string too long
          delete data.columns[column].search;
        }
        // Send an Ajax request to the server with the state object
        $.ajax( {
          "url": "StateSave.php",
          "data": {
            "td" : data,
            "id": ID
          }, 
          "dataType": "json",
          "type": "POST",
          "success": function (data) {
          }
        } );
      },
     stateSave: true, //saves current state of DT (colvis, row order)
      stateSaveParams: function (settings, data) {
        delete data.search;
        delete data.order;
      },
      stateLoadCallback: function (settings, callback) {//specifies loading the state of the table externally rather than in localstorage
        data = {'id': ID};
        $.ajax( {
            url: 'StateLoad.php',
            "data": data,
            dataType: 'json',
            "type": "POST",
            success: function (json) {
              if (json != null) {
                //manipulate the data to get it in the right format
                Data = JSON.parse(json.Data); //parse the json string to get an object
                Data.time = new Date().getTime(); //change timestamp to current time in seconds
                for (const column in Data.columns) { // change column visibility from string to bool
                  if (Data.columns[column].visible == "true") {
                    Data.columns[column].visible = true;
                  } else {
                    Data.columns[column].visible = false;
                  }
                }
                callback(Data); 
              }
            }
        } );
      },`
    

    However, now that I have added stateLoadCallback, the column filtering for the table does not work. Once the user starts typing into the column search bars, the table filters down to 0 rows. It seems like even though I have removed all of the search keys from the data, the table still tries to load a filter during stateLoadCallback.

    Here is the data I save to the database and reload:

    {"time":1615298360113,"start":"0","length":"10","columns":[{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true},{"visible":true}],"ColReorder":["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26"]}

    You can see in stateLoadCallback that I have to reformat the data once I pull it back from the db.

    Once again, the filtering does work if I remove stateLoadCallback, any idea why?

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    The state load code should only work on initialisation, and have no effect after that, so something else is doing odd stuff there.

    We're happy to take a look if you can please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • ad824aad824a Posts: 20Questions: 4Answers: 1

    Alright I've put together a test case using live.datatables. Hopefully the issue will be obvious by just reading through the code, because the stateSave/stateLoad doesnt actually work since the AJAX URLs aren't valid. I changed my logic and decided to save the state of the search values, so I've removed stateSaveParams.

    live.datatables.net/curohubi/1/edit

    Here are the trouble points I found after more troubleshooting yesterday:

    • If I typed one character into a column search bar, stateSaveCallback would fire once per column (if there are 30 columns in the table, I would see the console.log on line 17 print 30 times)
    • The search value would be applied to every column in the stateSave data object. Strangely, even if I typed a search value into column 3, the console.log on line 17 would show the search being applied to the FIRST column, then the SECOND column, and so on until the search was applied to all 30 columns (weird)
    • I finally realized that the code for the column search function (lines 100-126) was redrawing the tables once per column, and causing the state to save 30 times.

    I'm not sure why that code is calling .draw so much. I assumed it would only be called on the single column that the user was typing into.

    Thanks again for your help

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Your test case didn't run, but I think I get the gist of it. I recreated it here, very stripped down, and I'm not seeing the behaviour you mentioned in those three bullet points above. Could you look at that, please, and see if it helps. If it's still not working for you, please can you update my example, or link to your page, so that we can see the problem.

    Cheers,

    Colin

  • ad824aad824a Posts: 20Questions: 4Answers: 1
    edited March 2021

    Great! Changing the column search logic and using #filterboxrow stopped the stateSaveCallback from firing multiple times (stateLoadCallback is currently commented out).

    So now the filters work and the state saves. However uncommenting stateLoadCallback removes the column search :( .

    • If I comment stateLoadCallback out entirely, the table is formatted with column searches.
      //stateLoadCallback: function (settings, callback) { },

    • Once I uncomment stateLoadCallback and callback(Data), the column filter inputs disappear
      callback(Data);

    As the page is loading, I see the inputs for a split second, then they are removed and the table is formatted like the screenshot above. Something about stateLoadCallback removes the inputs...

    It's worth noting that is is actually loading that state back properly

    Here is a snapshot of the data I'm getting back from stateLoad:

    I think we are really close to getting it working. Thanks so much for the help

  • kthorngrenkthorngren Posts: 21,305Questions: 26Answers: 4,947
    Answer ✓

    See if this thread helps with the column search and stateSave.

    Kevin

  • ad824aad824a Posts: 20Questions: 4Answers: 1
    edited March 2021 Answer ✓

    Thanks for everything guys! Here's the solution to save/load the state and reinitialize the column searches:

    http://live.datatables.net/curohubi/2/edit

    -Amanda

This discussion has been closed.