Search code examples
jquery-uijquery-ui-droppable

Jquery UI Droppable on overlapped (but not nested) elements


I'm facing a trouble with droppable/draggable plugin of Jquery UI. If I have two elements, not-nested, but overlapped due to css structure, the drop function is thrown for both elements. How can I prevent to the background element to get the drop?

This is an example: https://jsfiddle.net/vq4x0b8L/2/

HTML

<div id="contenitore"> 
    <div id="carrello"> 
        <p>Drop here</p> 
    </div> 
    <div id="carrello2"> 
        <p>Drop here</p> 
    </div> 
  <div id="fagioli"> 
        <p>Drag me</p> 
    </div> 
</div>

JS

$(function() {
    $( "#fagioli" ).draggable();
    $( "#carrello" ).droppable({
        greedy: true,
        drop: function( event, ui ) {
            $( this )
            .find( "p" )
            .html( "Dropped." );
        }        
    });  
  $( "#carrello2" ).droppable({
        greedy: true,
        drop: function( event, ui ) {
            $( this )
            .find( "p" )
            .html( "Dropped." );
        }        
    }); 
});

CSS

#contenitore {position: relative; width: 500px; height: 500px;}
#carrello {background: #ccc;width:400px;height:500px;}
#carrello2 {background: #ddd; width:300px;height:250px; position: absolute; bottom: 0px;}
#fagioli {background: #822222;width:70px;height:90px;position: absolute; top: 200px; right: 10px;}
#fagioli:hover {cursor:move}

I tried the "greedy" option, but it doesn't work, probably it is designed for nested elements.


Solution

  • I found a way to do it.

    Example: https://jsfiddle.net/Twisty/dezt5bmf/10/

    JavaScript

    $(function() {
      $("#fagioli").draggable();
      $("#carrello").droppable({
        drop: function(event, ui) {
          console.log("Dropped on " + $(this).attr("id"));
          $(this)
            .find("p")
            .html("Dropped.");
        }
      });
      $("#carrello2").droppable({
        tolerance: "touch",
        drop: function(event, ui) {
          console.log("Dropped on " + $(this).attr("id"));
          $(this)
            .find("p")
            .html("Dropped.");
          $("#carrello").droppable("option", "accept", "*");
        },
        over: function(event, ui) {
          $("#carrello").droppable("option", "accept", ".snowflake");
        }
      });
    });
    

    When the Draggable is Over the 2nd droppable, we adjust the accept option to something that is not the draggable element. This way when drop happens, it is not interested in it. Once the dropped is performed, we can switch it back to accept all items.

    You can also disable the dropables, yet this causes additional Styles to be applied. Changing the accept does not.