Search code examples
jquery-ui-droppable

jQuery droppable issue


I've writen jQuery code that allows a user to create 2 boxes on screen, and then drag and drop one into the other. From an HTML perspective it would look like this...

<div id="1">
    <div id="2">
    </div>
</div>

If I then create another box and drag it over box 2 and drop it, it's always dropped into box 1 (i.e. box 2's parent). What I want is this...

<div id="1">
    <div id="2">
        <div id="3">
        </div>
    </div>
</div>

...but what I get is this...

<div id="1">
    <div id="2">
    </div>
    <div id="3">
    </div>
</div>

You [USED TO BE ABLE TO] can see this happening here... http://acarna.com/editor.php <- I've fixed the problem...see my answer below

Click the "H" button top left to create a box. Grab the grey square in the upper right corner of the box to drag it further down into the page. Move your mouse over the edge or corner of the box and resize it.

Then click "H" again to create box 2. Drag and drop box 2 into box 1. This works properly. If you use Firefox you can see box as it's added to box 1 on mouseover.

The problem I'm having is when creating box 3, moving it over box 2 and attempting to drop it inside. It's detecting only box 1 and dropping it in that.

Is there some trick I'm missing to have jQuery detect box 2 when box 3 is dragged over it, and have it added there instead?


Solution

  • I just had a moment of clarity after struggling with jQuery UI's (ahem) sparse documentation.

    The droppable option 'greedy' determines where an object will land when it's dropped on a tree of droppable objects.

    When set to false (the default) the dropped object will land on the lowest droppable object in the tree. When set to true the dropped object will land on the first (i.e. highest) droppable object in the tree.

    This can be demonstrated using the following mark up by way of example. Imagine the following divs are all droppable objects...

    <div id="bottom_container">
        <div id="level_2_container">
            <div id="level_3_container">
            </div>
        </div>
    </div>
    

    A draggable object (given id="all_new_container" below) is dropped on div#level_3_container. Here's the markup that results if greedy is false (i.e. the default)...

    <div id="bottom_container">
        <div id="level_2_container">
            <div id="level_3_container">
            </div>
        </div>
        <div id="all_new_container">
        </div>
    </div>
    

    And here's the markup that results if greedy is set to true...

    <div id="bottom_container">
        <div id="level_2_container">
            <div id="level_3_container">
                <div id="all_new_container">
                </div>
            </div>
        </div>
    </div>
    

    If you have Firebug you watch the above happening as you drop objects into other objects here... http://acarna.com/editor.php

    Please excuse the positioning bug that has new dropped elements land in the wrong place beyond level 2. I won't be fixing that in the above example, and it's not necessary to do so for the above demonstration.