Opened 5 years ago

Closed 5 years ago

#9730 closed bug (invalid)

when triggered drop and greedy = true, if DOM changed, drop event occurs again to others

Reported by: trasyia Owned by: trasyia
Priority: minor Milestone: none
Component: ui.droppable Version: 1.10.3
Keywords: Cc:
Blocked by: Blocking:

Description

This is because, drop function calls each droppable and it's not stop until all loop is done.

When drop occurs actually, DOM can be changed and this loop can detect another droppable object.

So, the loop must be stopped when greedy.

drop function is here,

    drop: function(draggable, event) {

        var dropped = false;
        $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {

            if(!this.options) {
                return;
            }
            if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
                dropped = this._drop.call(this, event) || dropped;
            }

            if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                this.isout = true;
                this.isover = false;
                this._deactivate.call(this, event);
            }

        });
        return dropped;

    },

and solutions maybe...

    drop: function(draggable, event) {

        var dropped = false;
        $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {

            if(!this.options) {
                return;
            }
            if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
                dropped = this._drop.call(this, event) || dropped;
                if (dropped && this.options.greedy) return false;
            }

            if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
                this.isout = true;
                this.isover = false;
                this._deactivate.call(this, event);
            }

        });
        return dropped;

    }

Change History (4)

comment:1 Changed 5 years ago by Scott González

Owner: set to trasyia
Status: newpending

Please provide a reduced test case showing the problem. Also, as the red box says, please do not paste large blocks of code into tickets.

comment:2 Changed 5 years ago by trasyia

Status: pendingnew

Ok, let's see the logical flow...

'drop' works like this

foreach (droppable_dom)
{
    if (there is no child droppable_dom that is greedy and intersect) {
        do drop;
    }
}

Let the DOM 1,2,3,4,5,6 is all 'greedy' and 'pointer tolerance' options, and nested like [1 [2 [3 ] ] ] [4 [5 [6 ] ] ].

When the DOM5 dropped to DOM3, there is possibility, DOM2 or DOM4 get drop event.

Because 'foreach' loop run for all droppable DOM 1,2,3,4,5,6, and after DOM5 dropped to DOM3, DOM size can be changed and DOM4 can interset to dropped point.

Or, (I don't know the reaseon) when 'foreach' run for DOM2, DOM3 is not detect as 'child droppable_dom'.

So, I suggest 2 way

  1. If dopped DOM is greedy, end foreach loop
  2. Check all droppable DOM first, then do actual drop later.
Last edited 5 years ago by trasyia (previous) (diff)

comment:3 in reply to:  2 Changed 5 years ago by tj.vantoll

Status: newpending

Replying to trasyia:

Ok, let's see the logical flow...

'drop' works like this

foreach (droppable_dom)
{
    if (there is no child droppable_dom that is greedy and intersect) {
        do drop;
    }
}

Let the DOM 1,2,3,4,5,6 is all 'greedy' and 'pointer tolerance' options, and nested like [1 [2 [3 ] ] ] [4 [5 [6 ] ] ].

When the DOM5 dropped to DOM3, there is possibility, DOM2 or DOM4 get drop event.

Because 'foreach' loop run for all droppable DOM 1,2,3,4,5,6, and after DOM5 dropped to DOM3, DOM size can be changed and DOM4 can interset to dropped point.

Or, (I don't know the reaseon) when 'foreach' run for DOM2, DOM3 is not detect as 'child droppable_dom'.

So, I suggest 2 way

  1. If dopped DOM is greedy, end foreach loop
  2. Check all droppable DOM first, then do actual drop later.

Hi trasyia,

Can you please provide a test case that shows this behavior in action? You can use this as a starting point: http://jsfiddle.net/tj_vantoll/8RtqV/. I'm mostly wondering what specific DOM changes you are making in the drop event such that it affects other droppables.

comment:4 Changed 5 years ago by trac-o-bot

Resolution: invalid
Status: pendingclosed

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

Note: See TracTickets for help on using tickets.