Clear table data and saved state of the table

Clear table data and saved state of the table

kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

Hello Team,

I am saving the state of the table with stateSave option as the data is being added to the table. What i am trying to achieve is, when a button "Empty Table" is clicked, I need all the data in the table to be removed and also clear the saved state to start all over again.

Here is my test case demonstration.

The problem is :-

It seems to work the first time you click on "Empty Table" and as long as you don't refresh the page. And when you refresh the page, the "Add Row" stops working, it doesn't add any items to the table anymore.

Then, It starts working again, if you refresh the page one more time.

To recreate the problem:-

Add a couple of rows by clicking on "Add Row" button, then click on "Empty Table" to remove all rows from the table. Now, refresh the page and try to click on "Add Row". It stops working, until you refresh the whole page again.

Answers

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited May 2020

    To clear the saved state:

    With:

    So "localStorage.clear()" is all you need.

    Alternatively: https://datatables.net/reference/api/state.clear()

    To clear the Data Table:
    https://datatables.net/reference/api/clear()

  • kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

    @rf1234

    As you can see in my test case, I am already using table.clear().draw() and table.state.clear() but it is not working as expected.

    I also tried using localStorage.clear() per your suggestion, but the behavior still the same.

    I simply want a table with CRUD operations with table with state and data in the table saved in the browser until the data is ready to be submitted to the server via a POST action.

    Everything seems to be working fine at the beginning, but when the data and state is cleared using table.clear().draw() and table.state.clear() and then if the page is refreshed, everything stops working.

    Please take a look at this demonstration of the test case and to recreate the issue i am facing.

    I am very close in achieving what i am looking for with datatables but this issue is blocking everything. I am not sure where am i going wrong. Any help would be greatly appreciated.

    One error i see when the page is refreshed followed by table.clear().draw() and table.state.clear() is below, not sure what it is complaining about.

    Uncaught TypeError: Cannot read property 'length' of undefined

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    Hi, the error is here. "rows" is not defined.

    The strange thing: You only have the error initially. Then it disappears. I deleted the state and the error came back. I never added rows manually to a Data Table. I always use ajax. I have never seen this before. Sorry.

    What I would be searching for: Why does the error only occur with an empty state? Are you trying to add a row with no data? If that is the case this might explain the error. You'll figure it out ...

    Right now everything looks fine (retrieving state data):

  • kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

    @rf1234 , Thank you for your response.

    In the test case, there is no case where there is a row being added with no data.

    This is clearly demonstrated in the test case. The issue only occurs when table and state is cleared and the page is refreshed.

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    This works now. It was about the not existing rows ...
    http://live.datatables.net/newirepu/1/edit

    I changed this to be initialized as an empty array.

    var addedRows = [];
    

    and made sure rows.add() isn't called with something undefined or empty.

    'initComplete': function () {
          if (typeof addedRows !== 'undefined') {
            if ( addedRows !== [] ) {
              this.api().rows.add(addedRows).draw();
            }
          }      
          this.api().state.save();
          },
    
  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    yep, something odd going on there, we'll take a nose and report back. I've added debug and it shows what I'd expect in the saved state info, so something deep in the internals.

    Colin

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited June 2020

    http://live.datatables.net/micujamo/1/edit

    If you take a look at the test case above: It was enough to just initialize the addedRows variable as an empty array. I could eliminate all checks for empty array and undefined. The problem must have been that rows.add() was called with a variable that wasn't an array. An empty array doesn't cause a problem. But to call rows.add() with a string variable is not working.

    The docs confirm this:
    https://datatables.net/reference/api/rows.add()

  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    Nice. Not sure why mine didn't work, but yours is definitely doing the trick!

    Colin

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    Hey Colin, and I screwed up as well :smile:

    I put a few console.logs in there. I found out when you do a page refresh with an empty Data Table "data.added" is undefined when "stateLoadParams" is being executed. So I added this in "stateLoadParams"

    if ( typeof data.added !== "undefined" ) {
       addedRows = data.added;
    }
    

    Now the console looks fine
    - stateLoadParams is executed before initComplete
    - when finishing stateLoadParams "addedRows" is still an empty array and not overwritten by something undefined
    - initComplete is executed thereafter and rows.add() is called with an empty array which is ok.

    http://live.datatables.net/fexiqido/1/edit

  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    Yeah, I was doing that check, so surprised mine wasn't playing along. But no point dwelling, busy day :)

    Thanks for fixing,

    Colin

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    @Colin, normally I can find these bugs fairly quickly using Chrome's debugger. I don't really know how to use it with the demo tool. All I can use is console.log which I never use for my own stuff because the Chrome debugger is so much better.

    Do you know how to use the Chrome debugger with the demo tool?

  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    I do, but need to improve - my history is systems software - so this is all a learning curve. It's on the to-do list :)

    Colin

  • kthorngrenkthorngren Posts: 20,322Questions: 26Answers: 4,774

    Do you know how to use the Chrome debugger with the demo tool?

    Click on the "Live Preview" button. The upper/right facing arrow in the Output tab. You can use the debugger form there. A bit of a pain though when making changes.

    Kevin

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    Thanks, Kevin!

  • kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

    @rf1234 @colin Thank you very much. I really appreciate your time and help.

    That resolved the empty table and refresh issue.

    We are getting close.

    There are just two more outstanding issues now.

    1. When individual rows are deleted by clicking on 'Delete' button in each row. The table state is not being saved. The page refresh brings deleted rows back in to the table.

    2. When quantity value is changed, it should update the subtotal column. This is only working when the page is refreshed twice. And i don't see any errors in the console.

  • colincolin Posts: 15,146Questions: 1Answers: 2,587
    1. yep, you would need to remove that value from the array that gets written on state change
    2. you would need to modify that value in something like drawCallback, or invalidate the cell with cell().invalidate() so it gets re-rendered.

    Colin

  • kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

    Thanks @colin

    1. Got this one resolved by resolved by removing the element from the array, like below.

      var idx = table.row($(this).parents('tr')).index();
      addedRows.splice(idx, 1);
      table.row($(this).parents('tr')).remove().draw();
      table.state.save();
      
    2. Tried using cell().invalidate() like below but is not working for me. Would you please help me with this.

      table.cell(this, 4).invalidate().draw(); 
      table.cell(this, 4).data( subtotal ).draw();
      

    Here is the updates test case.

    http://live.datatables.net/ribaxeqo/5/edit

  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    That looks like the wrong test case, there isn't an cell().invalidate() in that one, could you take a look please.

    Colin

  • kevintivolikevintivoli Posts: 18Questions: 4Answers: 0

    @colin Sorry about that. Here it is.

    http://live.datatables.net/ribaxeqo/7/edit

  • colincolin Posts: 15,146Questions: 1Answers: 2,587

    The code was more or less right, the delegated event was wrong, and you need to use change to capture both the arrows and the keyboard.

    http://live.datatables.net/ribaxeqo/8/edit

    Colin

This discussion has been closed.