Cell invalidation without destroying its content

Cell invalidation without destroying its content

TalaganTalagan Posts: 7Questions: 1Answers: 0

Hi all,

Is it possible to invalidate cells without destroying their inner dom content ? Suppose that you've built a complete widget inside your cell (in createdRow or in the drawCallback e.g.) , with css styling, event callbacks & more, I would expect that, when invalidating the cell data, the cell content would not be destroyed but still present at the next draw so that a simple visual update would be needed (i.e. css class and style update & so on). Atm, rebuilding is the cell is the only option.

Destroying the cell content on invalidation is costy since you get the overhead of recreating the inner dom and on complex tables, this performance matter can be an issue if you perform a mass invalidation.

Ben

This question has accepted answers - jump to:

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    Hi @Talagan ,

    You could pass dom to cell().invalidate(), so that will use the data currently in the DOM.

    Hope that does the trick,

    Cheers,

    Colin

  • TalaganTalagan Posts: 7Questions: 1Answers: 0

    Hi Colin,

    First, thanks a lot for your answer! Maybe there's something that I don't fully understand but it does not behave exactly as I would expect. My DataTable uses a strict data source (pure js objects). When I call invalidate('dom'), it won't effectively destroy the cell's dom (that's good), BUT it will patch back my original data with the dom content of the cell (that's bad)!

    See attached demo, you can load it in a browser and call in the console :

    datatable.rows().invalidate('dom'); datatable.data();

    You will see that the original 'color' fields are replaced the cell dom's content.

    So with invalidate('data') the cells are destroyed but the data is not patched.
    But with invalidate('dom') the cells are not destroyed but the data is patched.

    I think I miss an option to invalidate the data (this is actually for sorting and searching purposes) but leave the cells dom intact to perform a light update in the draw method.

    Ben

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736

    I think the problem is the createdRow is not intended to change the cell data. You would use columns.render for this and you probably will want to use orthogonal data to build the desired HTML for the cell for the display type. This way the original data stays intact for sorting and searching.

    Kevin

  • TalaganTalagan Posts: 7Questions: 1Answers: 0

    Ok, I think I have managed to gather all pieces now :-)

    That's my current implementation (demo attached) :

    1) Create the cell content in the render function (for type 'display')
    2) Create the cell events in createdRow
    3) Write the cell visual update code in rowCallback
    4) Use cells().invalidate('dom') (name is a bit misleading) to avoid the cells to be recreated but inform the datatable that the inner data has changed.
    5) Very important! In the column declaration, use data: null or the column won't behave as expected. Took me a while to figure this out (thanks to the doc).

    Is everything done the right way? I think the beast is a bit tricky to tame. But powerful if things are done well.

    Ben

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    Answer ✓

    Looks good. I think the only difference between createdRow and rowCallback is that createdRow is called once at initialization but rowCallback is called each draw. Depending on your needs will determine which to use.

    In your modifyData() function you could update the Datatables data directly. Looks like you might want to use cell().data() in this particular case. Then in this click event:

          $(".modifybutton").click(function() {
            modifyData();
            datatable.cells().invalidate('dom').draw(false);
          });
    

    You could use datatable.draw(false); instead of using invalidate. It might be more efficient to update the data directly, but you will need to test to see.

    Kevin

  • TalaganTalagan Posts: 7Questions: 1Answers: 0
    edited February 2019

    Thanks for your worthy answers.

    Concerning the data modification, your explanation is very clear. My example is a very simplified version of a realtime case, so in practice, it's gonna be complicated to patch every cell data on each field change, so I use a mass invalidate. But I completely get the idea of using the data() method. Looks great for precise data patching.

    Also, for anyone stumbling on this thread I've attached here a final version (the color column is sorted by luminosity, so it's a good example of orthogonal data, with numerical custom sorting).

    Thanks again for your very precious help.

    Ben

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    Answer ✓

    y example is a very simplified version of a realtime case, so in practice, it's gonna be complicated to patch every cell data on each field change, so I use a mass invalidate

    That works fine. Just wanted to highlight the data() methods. There are also row().data(), column().data() and the plural rows and columns methods as well.

    Kevin

  • TalaganTalagan Posts: 7Questions: 1Answers: 0

    Awesome. Really powerful once you get it.

This discussion has been closed.