1

I'm using jQuery UI for Drag n Drop.

The UI shows a list of elems in several columns with each column having a total $ value (the sum of each elems $).

I'm having trouble updating this total when an elem moves from one column to the next.

It's firing either too early when the elem hasn't reached the new column yet or in the middle when it's kinda in both columns.

How can I fire my update totals method after the animation to the new column is complete (essentially once the elem has fully moved into the new column and is no longer in the old one)?

Here is my code:

dragUserInTable = function() {
    if (!$('.item').length) return;

    console.log("ok about to set up draggable and droppable");

    $(".item").draggable({
        addClasses: false,
        containment: '.workflows__table',
        cursor: "drabbing",
        snap: ".workflows__board-body",
        snapMode: "inner",
        revert: "invalid",
        helper: "clone",
        snapTolerance: 50,
        zIndex: 10,
        drag: ({ target }, elem) => {
            console.log('drag for '+target+ ' ' +elem);
            $(target).addClass('item--drag');
            $(elem.helper[0]).addClass('item--dragging');
            $(target).parents('.workflows__board-body').removeClass('ui-droppable-hover');
        },
        stop: ({ target }, elem) => {
            console.log('stop for '+target+ ' ' +elem);
            $(target).removeClass('item--drag');
            $(elem.helper[0]).removeClass('item--dragging');
            $(target).removeClass('item--lost');
        }
    });

    $('.workflows__board-body').droppable({
        accept: '.item',
        tolerance: "intersect",
        drop: ({ target }, elem) => {
            console.log('drop for '+target+ ' ' +elem);
            $(target).find('.workflows__users').append(elem.draggable[0]);
            $(elem.draggable[0]).removeClass('item--drag');
            $(target).find('.item--lost').removeClass('item--lost');
            valueUsersAndTotalValue(); // THIS METHOD NEEDS TO FIRE AFTER THE ABOVE 3 LINES are complete

        },
        over: ({ target }) => {
            console.log('over for '+target);
            $(target).parents('.workflows__table').find('.item--drag').addClass('item--lost').removeClass('item--drag');
        }
    });
};

I've tried using when.done or when.then but I seem to be missing understanding something because the lines of code are being returned to the deferred part rather than being executed.

    $.when(function(target, elemt) {
        $(target).find('.workflows__users').append(elem.draggable[0]);
        $(elem.draggable[0]).removeClass('item--drag');
        $(target).find('.item--lost').removeClass('item--lost');

        return true;
    }).then(function(result) {
        console.log(result);
        valueUsersAndTotalValue();
    });
Solvision
  • 193
  • 1
  • 11
  • Can you create a [simplified version](https://stackoverflow.com/help/mcve) which demonstrates the problem? [The Droppable docs include a simple example](https://jqueryui.com/droppable/#visual-feedback) which shows the `.drop()` method fires *after* the drop has finished. This doesn't match what you're describing - "*either too early when the elem hasn't reached the new column yet or in the middle when it's kinda in both columns*". Do you have some other effects/animation/something happening which might be conflicting? – Don't Panic Dec 06 '21 at 05:07
  • How is `dragUserInTable()` called? – Don't Panic Dec 06 '21 at 07:21
  • 1
    I don't believe any of the code in your `drop()` method is asynchronous. AFAIK the `.find()`, `.append()`, `.removeClass()` methods will all be complete by the time your `valueUsersAndTotalValue()` method is called. I've just searched for confirmation of this - https://stackoverflow.com/questions/5085228/does-jquery-append-behave-asynchronously, https://stackoverflow.com/questions/40933962/is-addclass-async. Hence my questions above - I think the problem is elsewhere. – Don't Panic Dec 07 '21 at 23:11

0 Answers0