Invalidating and drawing within Editor

Invalidating and drawing within Editor

johnblythejohnblythe Posts: 92Questions: 21Answers: 2

Hi there,

I'm using Editor and DT for a project. In one area of our project where we have Datatables without Editor in place there is a means of updating pricing. As the discount is applied to each row the final action before moving forward to the next row is
dt.rows(i).invalidate().draw() and voila the row updates.

I'm attempting to avoid the lengthy process of calling the Editor's edit().set().submit() chain of actions on each row by simply traversing through DT and updating the row. The simple invalidate+draw chain isn't applying for some reason, though. No errors are thrown, yet nothing occurs in the UI.

Is this a result of it being an Editor instance as well? I can certainly provide more code if that's not the case.

Thanks!

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,821Questions: 1Answers: 10,127 Site admin

    Hi,

    If you could provide the code that would be very useful. There should be no reason why you can't use rows().invalidate() on a table that also has an Editor instance (Editor only reads the data for a row when it is activated with edit() or the other editing methods).

    Allan

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2

    Sure thing.

    When the discount is applied, we run this:

    function processEditQueue()
        {
            if ($.active <= 0) {
                var item = editQueue.pop();
                if (item) {
                    editor
                        .edit( item.row, false )
                        .set( 'offerPriceUom', item.price )
                        .submit(processEditQueue);
                } else {
                    // kill curvoloader
                    dieCurvoLoader();
                }
            } else {
                setTimeout(processEditQueue, 100);
            }
        }
    

    To remove the discount, I'm opting to do the DB updates via ajax and then run this to update DT in the UI:


    var newPrices = []; // the returned data from having updated the DB previously via AJAX $.each(json.data, function (i, el) { newPrices[el.rowId] = { 'OfferPricePerUOM' : el.OfferPricePerUOM, 'projectedSpend' : el.projectedSpend }; }); $.each(dt.rows().indexes(), function(i, el) { // Get all the row data var rowData = dt.row(i).data(), rowId = $(dt.row(i).node()).attr("id"), // get the ID to match against newPrice = newPrices[rowId]; // set the new data if there is anything to be set if (rowData.offerItem !== "No cross") { rowData.offerPriceUom = newPrice.OfferPricePerUOM; rowData.projectedSpend = newPrice.projectedSpend; // redraw the row dt.row(i).invalidate().draw(); } })

    thanks for any assistance!

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2

    You know what, now that I'm thinking through it some more I am realizing the invalidate() is the wrong step. I borrowed some of the code from another area where we change the DOM directly instead of using Editor. As such it requires the invalidation of current DT data. Doh, silly me. Let me make some changes and see if I can get this sorted out.

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2
    edited March 2015

    Well, despite being right about it not helping the situation, removing the invalidate() method doesn't quite get us to the finish line either :\

    If I check the data() on a row before applying a discount, it's correct. After applying a discount (via Editor), it's now updated correctly. When I remove the discount and log it again it is once more correct (restored to the original). The draw() method, however, isn't doing anything. I've called it on the DT variable itself, on a specific row(), and on rows(). DT.clear() worked just fine :p

    TL;DR: the data in DT updates correctly upon each user action, but the final act doesn't showcase the updated data in the UI

  • allanallan Posts: 61,821Questions: 1Answers: 10,127 Site admin

    The draw() method, however, isn't doing anything.

    I'm not quite clear on what you are expecting it to do. It should re-order and re-search the table based on the latest data for the row. Is that not the case?

    Allan

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2

    I'm sorry for not being clear.

    We have price A on load. Price B can be applied (via Editor). User can revert to Price A. When they do so, this price doesn't show up in Datatable's UI, but it does get set in the data. The user still sees Price B despite having reverted to Price A.

    In some of the other areas of our application I've used DT I could update the UI according to changes made directly in the DOM (with invalidate().draw()). I was thinking that draw() would refresh what is presented according to what is in the data() object itself. Is this not the case? If not, then my options would include: 1) heading back to the server for the new data or 2) making a change directly to the DOM, invalidate, draw?

    Thanks!

  • allanallan Posts: 61,821Questions: 1Answers: 10,127 Site admin

    Is the price being calculated in a columns.render function or something else? It should be that invalidating the data will cause it to rerender.

    If you have a link to the page that would be quite useful.

    Allan

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2
    edited March 2015

    Sorry for my delay, been getting swamped!

    The original price is being dropped into the DOM on load. The DT/Editor init are upon a user event that produces a FancyBox modal with the new DT inside of it.

    When a discount is given it's using the processEditQueue() function mentioned above. This works as expected. When one is taken away it is using another method to get the job done: it runs some queries via AJAX to update the database table's records accordingly, sends those new entries back, and then on the success() of that AJAX call runs through DT and updates the row's data (the second code block above).

    A couple other points of clarification:

    1) I had misspoken originally when I referenced invalidate(). At least I think so. My understanding of invalidate is that it invalidates the data() in light of the DOM. I needed it to the opposite: refresh the DOM after successfully updating the data().

    2) I had gotten tunnel visioned with using rows() and thus hadn't checked out any of the column related methods. Silly me!

    3) I ended up getting it to work, just not as natively to DT as I had originally set out to do. This may or may not be the best solution. I'm using $(dt.row(i).node()).find("td:eq(6)").text(value) or something of that sort (going off of memory here) to update the DOM to match what data() is being updated with. Perhaps the column() related solution would be better?

  • allanallan Posts: 61,821Questions: 1Answers: 10,127 Site admin
    Answer ✓

    No worries - I know that feeling!

    1) I needed it to the opposite: refresh the DOM after successfully updating the data().

    row().invalidate() will actually handle both cases. By default it will automatically detect if your original data source is DOM or an object. It will assume that the original is the most up-to-date and therefore update the other. i.e. if your table is DOM sourced and you update the DOM, then call invalidate() it will read the data from the DOM.

    However, if you have a DOM sourced data and you update the object/array (likewise for a data sourced table and you update the DOM), then you need to tell row().invalidate() where the data should be read from. That is done by using the first parameter passed into row().invalidate().

    Does that help at all?

    Allan

  • johnblythejohnblythe Posts: 92Questions: 21Answers: 2

    I'm facepalming right now, Allan!

    I'd totally forgotten about that parameter. I'd used it way back when we first started using DT, but had since totally forgotten about it since we went another route with implementation. Silly me for looking everywhere else but at the docs for invalidate() :\

    Thanks!

This discussion has been closed.