03 - jQuery UI Droppable

Introduction

You can make any HTML element droppable, making it a target for draggable elements using a simple jQuery UI method: droppable. To create a droppable element, we have to make the element that needs to be moved draggable using the draggable method. Then the target element needs to be made droppable using droppable method. In other words, we need to use the draggable method along with the droppable method to implement this functionality. You can also control the behavior of the element during dropping if you want using a number of options and methods. You need to specify the options as key/value pairs and you can directly call methods inside the droppable method.

Syntax

The syntax of draggable method is

    $(selector).droppable();

    OR

    $(selector).droppable({option1:value1, option2:value2,……..});

    OR

    $(selector).droppable("method_name", [parameters]);

The options will set the behaviour of the element while dropping. The option and its corresponding value are set as key value pairs. While specifying actions using method names, we need to pass the method name along with its parameters (if any) to the droppable method. We will see all the popular options and methods one by one with the help of code samples. While trying the code samples, make sure that you add reference to the jQuery UI related files (one .css file and two .js files) correctly.

The droppable() Method

Once you make an element draggable, it is obvious that it can be dropped anywhere. So, to differentiate the drop in a droppable area and a usual drop (anywhere), I write the code in such a way that the content of the box dropping in will be changed only if it is dropped inside the actual droppable area.

Open a new file and add the following lines of code:

<!DOCTYPE html>
<html>
  <head>
    <title>Sample Code</title>
    <link rel="stylesheet" href="jquery-ui.min.css">
    <script src="jquery.js"></script>
    <script src="jquery-ui.min.js"></script>
    <style>
      #target
      {
         width: 400px;
         height: 400px;
         border:2px solid black;
         background-color:pink;
         float:left;
      }
      #source
      {
        width:100px;
        height:100px;
        border:1px solid black;
        margin:15px;
        background-color:aqua;
        float:left;
        font-size:20px;
      }
    </style>
    <script>
       $(document).ready(function(){
       $("#source").draggable();
       $("#target").droppable({drop:function(event,ui){
       $("#source").html("Yes!!!I am in!!!");
       }});
       });
    </script>
   </head>
   <body>
     <div id="source"class="ui-widget-content">
        Drop me inside the pink box!!!
     </div>
     <div id="target"class="ui-widget-header">
     </div> 
   </body>
</html>

Save the file as index.html. Open it using your browser and you will get a screen like this:


                

Once you drop the blue box into the pink box, your screen will look like this:

              

On the other hand, if you drop the small box somewhere outside the pink box, the message will not be changed.

Setting Values to accept and scope Options

You can control which draggable elements can be dropped into the droppable element by setting the accept option. Inside the droppable method, you have to specify the elements to be accepted (id or class) as the value of accept key. The scope option can also be used to control which draggable elements can be dropped into the droppable element. The draggable element that has the same scope value that of a droppable element will only be accepted.

Open a new file and add the following lines of code:

<!DOCTYPE html>
<html>
  <head>
    <title>Sample Code</title>
    <link rel="stylesheet" href="jquery-ui.min.css">
    <script src="jquery.js"></script>
    <script src="jquery-ui.min.js"></script>
    <style>
      .major
      {
        display:table-row-group;
        border:2px solid black;
      }
      .target
      {
        width: 250px;
        height: 250px;
        border:2px solid black;
        background-color:pink;
        float:left;
        margin:10px;
      }
      .sourceOne, .sourceTwo
      {
    width:100px;
        height:100px;
        border:1px solid black;
        margin:15px;
        background-color:aqua;
        float:left;
        font-size:20px;
      }
    </style>
    <script>
      $(document).ready(function(){
      $(".sourceOne").draggable();
      $("#target1").droppable({accept:"#source1", drop:function(event,ui){
      $(ui.draggable).html("Yes!!!I am in!!!");
      }});
      $("#source3").draggable({scope:"fruit"});
      $("#target2").droppable({scope:"fruit", drop:function(event,ui){
      $(ui.draggable).html("Yes!!!I am into the " + $("#target2").html() + " box!!!");
      }});
      $("#source4").draggable({scope:"veg"});
      $("#target3").droppable({scope:"veg", drop:function(event,ui){
      $(ui.draggable).html("Yes!!!I am into the " + $("#target3").html() + " box!!!");
      }});
      });
    </script>
  </head>
  <body>
    <div class="major">
      <div class="sourceOne" id="source1" class="ui-widget-content">
         Drop me inside the pink box!!!
      </div>
      <div class="sourceOne" id="source2" class="ui-widget-content">
         Try to drop me inside the pink box!!!
      </div>
      <div class="target" id="target1" class="ui-widget-header">
      </div>
    </div>
    <h3>Put fruit in the Fruits box and vegetable in the Vegetables box</h3>
    <div class="major">
      <div class="sourceTwo" id="source3" class="ui-widget-content">
          Grapes
      </div>
      <div class="sourceTwo" id="source4" class="ui-widget-content">
          Brinjal
      </div>
      <div class="target" id="target2" style="background-color:silver;" class="ui-widget-header">
          Fruits
      </div>
      <div class="target" id="target3" style="background-color:silver;" class="ui-widget-header">
         Vegetables
      </div>
    </div>
  </body>
</html>

Save the file as options1.html. Open it using your browser and you will get a screen like this:


            

First try to put the first box “Drop me inside the pink box!!!” into the big pink box. Once the small box is dropped, you could find that the message inside the small box changes like this:

At the same time, if you try to put the second box “Try to drop me inside the pink box”, you could find that it is not actually droppable in the pink box. Even if you drop it in the pink box, the message is not changing which means that it is not an actual drop. Instead it is a normal drop that happens for any draggable element. Here we have used the accept attribute and set its value to the id of the first box. Hence only the first box is accepted by the big droppable box.

Next try to put the Grapes box into the Vegetables big box and you could find that it is not accepted. Similarly, the Brinjal box is not accepted by the Fruits box.

              

At the same time, if you try to put the Grapes box into the Fruits box, you could find that the message inside the Grapes box changes like this. Similar is the case if you try to put the Brinjal box into the Vegetables box.

       

If you analyze the code, you could find that the value of the scope options is the same, that is a fruit, for Fruits box and Grapes box. For the Vegetables box and Brinjal box, the value of the scope options is veg.

Setting Values to disabled and tolerance Options

You can make a droppable element disabled by setting the value of disabled option to true. By default, its value is false. The tolerance option is used to decide when a draggable element needs to be considered as dropped inside the droppable element. If the value of tolerance is set to fit, the draggable element is considered to be dropped only if it is completely inside the droppable element. If the value of tolerance is set to touch, then the draggable element is considered to be dropped as soon as its border touches the border of the droppable element. If the value of tolerance is set to pointer, the draggable element is considered to be dropped when the mouse pointer overlaps the droppable element. If the value of tolerance is set to intersect, then the draggable element is considered to be dropped if 50% of the element is entered inside the droppable element. By default, the value of tolerance is intersect.

Open a new file and add the following lines of code:

<!DOCTYPE html>
<html>
  <head>
    <title>Sample Code</title>
    <link rel="stylesheet" href="jquery-ui.min.css">
    <script src="jquery.js"></script>
    <script src="jquery-ui.min.js"></script>
   <style>
     .parent
     {
    width: 130px;
    height: 130px;
    border:2px solid black;
    background-color:pink;
    float:left;
    margin:5px;
     }
     #source1
     {
    width:70px;
    height:70px;
    border:1px solid black;
    margin:15px;
    background-color:aqua;
    font-size:15px;
     }
   </style>
   <script>
     $(document).ready(function(){
     $("#source1").draggable();
     $(".parent").droppable({drop:function(event,ui){
     $(ui.draggable).html("Yes!!!I am in!!!");}});
     $("#btnEnable").click(function(){
     $("#parent1").droppable({disabled:false});
     alert("The pink box is now droppable!!!");
     });
     $("#btnDisable").click(function(){
     $("#parent1").droppable({disabled:true});
     alert("The pink box is now not droppable!!!");
     });
     $("#parent2").droppable({tolerance:"touch"});
     $("#parent3").droppable({tolerance:"fit"});
     $("#parent4").droppable({tolerance:"pointer"});
     });
   </script>
  </head>
  <body>
    <button id="btnEnable">Enable</button>
    <button id="btnDisable">Disable</button>
    <div id="source1" class="ui-widget-content">
      Drop me inside different boxes!!!
    </div>
    <div class="parent" id="parent1" class="ui-widget-header">Enable and Disable &nbsp;& &nbsp;Intersect Tolerance</div>
    <div class="parent" id="parent2" style="background-color:gray;" class="ui-widget-header">Touch Tolerance</div>
    <div class="parent" id="parent3" style="background-color:silver;" class="ui-widget-header">Fit Tolerance</div>
    <div class="parent" id="parent3" style="background-color:#99FF66;" class="ui-widget-header">Pointer Tolerance</div>
  </body>
</html>

Save the file as options2.html. Open it using your browser and you will get a screen like this:

        

If you try to put the small box inside the pink box, it will be dropped and the message inside the small box will be changed like this:

         

Again refresh your browser and click the Disable button. Now if you try to put the small box inside the pink box, it will not be droppable. If you try again after clicking the Enable button, it will be again droppable. We are setting the value of disable option to true and false in the Disable and Enable buttons respectively. After enabling the button, when you drop the small box inside the pink box, you could find that the message in the small box changes as soon as half of the small box enters the pink box. This is because that the tolerance option is intersect by default. As soon half of the small box enters the pink box and you release the mouse, you will get a message like this:

            

     Before half of the small box is entered

             

     Once half of the small box is entered

If you try to drop the small box inside the dark gray box, you could find that as soon as the border of the small box touches the big box, it is considered as dropped and the message in the small box changes.

            

If you try to drop the small box inside the light gray box, you could find that the message in the small box changes only when the small box enters the big box completely.

              

     Before the small box completely enters the big box

             

     Once the small box completely enters the big box

If you try to drop the small box inside the green box, you could find that the message in the small box changes when the mouse pointer touches the big box.

Setting Value to greedy Option

When you drop an element on nested droppable elements, every droppable element gets the dropped element. You can decide which nested droppable elements should receive the dropped element by setting the value of greedy option. If you set the value of greedy to true, parent droppable will not accept the element. Instead, only the child droppable element will get the dropped element. By default, the value of greedy option is false.

Open a new file and add the following lines of code:

<!DOCTYPE html>
<html>
  <head>
    <title>Sample Code</title>
    <link rel="stylesheet" href="jquery-ui.min.css">
    <script src="jquery.js"></script>
    <script src="jquery-ui.min.js"></script>
    <style>
      #parent1, #parent2
      {
        width: 250px;
        height: 250px;
        border:2px solid black;
        background-color:pink;
        float:left;
        margin:5px;
      }
      #child1, #child2
      {
        width: 150px;
        height: 150px;
        border:2px solid black;
        background-color:silver;
        float:left;
        margin:25px;
      }
      #source
      {
        width:70px;
        height:70px;
        border:1px solid black;
        margin:15px;
        background-color:aqua;
        font-size:15px;
      }
    </style>
    <script>
      $(document).ready(function(){
        $("#source").draggable();
        $("#parent1, #child1").droppable({
                drop: function(event, ui) {
                $(this).find('p').html('Dropped!');}
        });
        $("#parent2, #child2").droppable({
            greedy: true,
            drop: function(event, ui) {
                $(this).find('p').html('Dropped!');
            }
        });
      });
    </script>
   </head>
   <body>
     <div id="source" class="ui-widget-content">
    Drop me inside
     </div>
     <div id="parent1" class="ui-widget-header"><p>Outer Box</p>
        <div id="child1" class="ui-widget-header"><p>Inner Box (NOT GREEDY)</p></div>
     </div>
     <div id="parent2" class="ui-widget-header"><p>Outer Box</p> 
    <div id="child2" class="ui-widget-header"><p>Inner Box (GREEDY)</p></div>
     </div>
  </body>
</html>

Save the file as options3.html. Open it using your browser and you will get a screen like this:

            

If you try to put the small box inside the first gray box, then you will get an output like this which indicates that both the parent box (pink box) and child box (gray box) accepts the small box.

            

If you try to put the small box inside the second gray box, then the output will look like this which means that only the child box accepts the small box as the value of greedy option is set to true.

             

Managing the Look

You can manage the look of the droppable element when a draggable element starts moving using the activeClass method and when a draggable element is being hovered using the hoverClass method. You need to add the class in the CSS and just have to set the name of the class as the value of these methods.

Open a new file and add the following lines of code:

<!DOCTYPE html>
  <html>
    <head>
     <title>Sample Code</title>
     <link rel="stylesheet" href="jquery-ui.min.css">
     <script src="jquery.js"></script>
     <script src="jquery-ui.min.js"></script>
     <style>
       #main
       {
     width:350px;
     height:200px;
       }
       .droppable
       {
     width: 150px;
     height: 150px;
     border:2px solid black;
     background-color:silver;
     float:right;
       }
       #source
       {
     width:70px;
     height:70px;
     border:1px solid black;
     background-color:aqua;
       }
       .moving
       {
         background-color : red;
         border-color: green;
       }  
       .entering 
       {
         background-color :orange;
         border-color: silver;
     }
    </style>
    <script>
      $(document).ready(function()
      {
    $("#source").draggable();
    $("#target").droppable({
    drop: function(event, ui) {
        $("#source").html("Yes!!!I'm in!!!");},
            activeClass:'moving',
            hoverClass:'entering'
    });
      });
    </script>
  </head>
  <body>
   <div id="main">
   <div id="source">Drop me inside the gray box!!!</div>
   <div id="target" class="droppable"></div>
   </div>
  </body>
</html>

Save the file as options4.html. Open it using your browser and you will get a screen like this:

          

  

As soon as you start moving the small box and before releasing the mouse, your screen will look like this:

                  

 

This is the style added using activeClass method. As soon as the small box enters the big box at the required tolerance, your screen will look like this and it is set using the hoverClass method:

                    

Once you release the mouse, it will have its initial look, that is the big box will become gray.

Calling Methods

We can perform different actions on the droppable elements by passing the method that performs the action as the parameter of the droppable method. We can remove the droppable functionality forever by calling the destroy method. We can disable the droppable functionality temporarily calling the disable method and then enable it calling the enable method. You can get the values of all options as an object by calling the option method without passing any parameter. You can get the value of a specific option by calling the method named option with the name of the option as parameter. You can set the value of options by calling the option method and passing the option name and its corresponding value as parameters.

Open a new file and add the following lines of code:

<!DOCTYPE html>
  <html>
   <head>
     <title>Sample Code</title>
     <link rel="stylesheet" href="jquery-ui.min.css">
     <script src="jquery.js"></script>
     <script src="jquery-ui.min.js"></script>
     <style>
       .droppable
       {
     width: 150px;
     height: 150px;
     border:2px solid black;
     background-color:silver;
     float:left;
     margin:10px;
       }
       #source
       {
     width:70px;
     height:70px;
     border:1px solid black;
     background-color:aqua;
       }
    </style>
    <script>
      $(document).ready(function()
      {
    $("#source").draggable();
    $("#target1, #target2").droppable({
    drop: function(event, ui) {
        $("#source").html("Yes!!!I'm in!!!");}});
    $("#btnDestroy").click(function(){
        $("#target2").droppable('destroy');
        $("#target2").find('p').html("I'm not droppable any more!!!");
    });
    $("#btnEnable").click(function(){
        $("#target1").droppable('enable');
        $("#target1").find('p').html("I'm now droppable!!!");
    });
    $("#btnDisable").click(function(){
        $("#target1").droppable('disable');
        $("#target1").find('p').html("I'm not droppable now!!!");
    });
    $("#btnTolerance").click(function(){
        $("#target2").droppable('option',{tolerance:"touch"});
        $("#target2").find('p').append(" Just touch me to enter inside!!!");
    });
      });
    </script>
   </head>
   <body>
     <button id="btnTolerance">Change Pink Box's Tolerance</button>
     <button id="btnDisable">Disable Gray Box</button>
     <button id="btnEnable">Enable Gray Box</button>
     <button id="btnDestroy">Destroy Pink Box</button><br /><br />
     <div id="source">Drop me inside the gray box!!!</div>
     <div id="target1" class="droppable"><p>DROPPABLE</p></div>
     <div id="target2" class="droppable" style="background-color:pink"><p>DROPPABLE</p></div>
   </body>
</html>

Save the file as callingmethods.html. Open it using your browser and you will get a screen like this:

      

Click the Change Pink Box’s Tolerance button and try dropping the small box inside the pink box. You could see that the element gets dropped as soon as its border touches the border of the pink box. Thus, we have changed the tolerance of the pink box calling option method. Now refresh your browser and click the Destroy Pink Box button. If you try to drop the small box inside the pink box now, it will not be droppable. Same is the case if you try to drop the small box inside the gray box after clicking the Disable Gray Box button. But if you try to drop it after clicking the Enable Gray Box button, it will be droppable.

Managing Events on Droppable Elements

Different events get triggered in different stages of a droppable element. The create event will be triggered when a droppable element is created. The activate event is triggered when an accepted draggable element starts dragging and the deactivate event is triggered when an accepted draggable element stops dragging. The drop event is triggered when an accepted draggable element is dropped on the draggable. The out event is triggered when accepted draggable element is dragged out of the droppable element and the over event is triggered when the accepted draggable element is dragged over the droppable element.

Open a new file and add the following lines of code:

<!DOCTYPE html>
<html>
  <head>
    <title>Sample Code</title>
    <link rel="stylesheet" href="jquery-ui.min.css">
    <script src="jquery.js"></script>
    <script src="jquery-ui.min.js"></script>
    <style>
      #main
      {
     width:500px;
     height:500px;
      }
      .droppable
      {
     width: 150px;
     height: 150px;
     border:2px solid black;
     background-color:silver;
     float:left;
     margin:10px;
     float:right;
      }
      #source
      {
     width:70px;
     height:70px;
     border:1px solid black;
     background-color:aqua;
      }
    </style>
    <script>
       $(document).ready(function()
       {
    $("#source").draggable();
    $("#target1").click(function(){
      $("#target1").droppable({
          create: function(event, ui) {
        $("#target1").html("Yes!!!I'm now droppable!!!");},
        activate: function(event, ui) {
        $("#source").html("I start moving!!!");},
        drop: function(event, ui) {
        $("#source").html("Yes!!!I'm in!!!");},
        over: function(event, ui) {
        $("#source").html("I'm entering inside!!!");},
        out: function(event, ui){
        $("#source").html("I'm outside!!");}
        });
    });    
     });
   </script>
   </head>
   <body>
     <div id="main">
     <div id="source">I'm outside!!</div>
     <div id="target1" class="droppable">Click ME to make me DROPPABLE</div>
     </div>
   </body>
</html>

Save the file as eventmanagement.html. Open it using your browser and you will get a screen like this;

                   

The big box is not droppable initially. You have to click the big box to make it droppable. Then while dragging the small box, notice the different messages in the small box and you could understand the different events.

Summary

In this tutorial, we have seen how to make an HTML element droppable using jQuery UI by writing only a couple of lines of code. We have also seen a number of options, methods and events that can be used to change the behaviour of the element while dropping.

Like us on Facebook