Marcos Placona Blog

Programming, technology and the taming of the web.

A more elaborated jQuery Drag & Drop (with cloning)

Reading time: 6 – 9 minutes

I’ve decided to get back at jQuery draggable and droppable to a personal project I’ve been working on. In the past, I’ve demonstrated how to do basic drag and drop, but this time I needed something a little bit more elaborated.
I won’t spoil my personal project by showing what it before it gets done, but I’ll show here an example of what I wanted to accomplish which will use pretty much the same functionality, but in other application.
The idea is:
I have a stage where I have a bunch of components that should be dragged from one side to another. Those components have to be cloned, and not totally dragged as I might want to use them more than one time.
A sketch of it would be on the lines of:
jQuery drag & Drop Example
As you can see, my icons need to stay on the left, but a clone of it can always be dragged to the right. This is not a finished version, but show pretty much all of the steps I had to follow in order to accomplish it. It’s not a simple solution, and did involve loads of researching and asking around. The jQuery’s documentation is not really vast, and does not cover (and should not really) every single example.
I start with importing all my necessary libraries from Google Servers.

<!-- import necessary libraries -->
<script src="http://www.google.com/jsapi" type="text/javascript">
</script>
<script type="text/javascript">
   google.load("jquery", "1.3.2");
   google.load("jqueryui", "1.7.3");
</script>
<!-- Include stylesheets -->
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" media="all" />

Then I start with my JavaScript code for draggable and droppable:

$(document).ready(function () {
    //Counter
    counter = 0;
    //Make element draggable
    $(".drag").draggable({
        helper: 'clone',
        containment: 'frame',
        //When first dragged
        stop: function (ev, ui) {
            var pos = $(ui.helper).offset();
            objName = "#clonediv" + counter
            $(objName).css({
                "left": pos.left,
                "top": pos.top
            });
            $(objName).removeClass("drag");
            //When an existiung object is dragged
            $(objName).draggable({
                containment: 'parent',
                stop: function (ev, ui) {
                    var pos = $(ui.helper).offset();
                    console.log($(this).attr("id"));
                    console.log(pos.left)
                    console.log(pos.top)
                }
            });
        }
    });
    //Make element droppable
    $("#frame").droppable({
        drop: function (ev, ui) {
            if (ui.helper.attr('id').search(/drag[0-9]/) != -1) {
                counter++;
                var element = $(ui.draggable).clone();
                element.addClass("tempclass");
                $(this).append(element);
                $(".tempclass").attr("id", "clonediv" + counter);
                $("#clonediv" + counter).removeClass("tempclass");
                //Get the dynamically item id
                draggedNumber = ui.helper.attr('id').search(/drag([0-9])/)
                itemDragged = "dragged" + RegExp.$1
                console.log(itemDragged)
                $("#clonediv" + counter).addClass(itemDragged);
            }
        }
    });
});

The code above is responsible for the dragging and dropping iterations.
I just want to highlight that even though the draggable component has an attribute called helper, and you can set it to clone, it does not necessarily clone the objects, but give a “false impression” of objects being dragged.
The object only is cloned when it’s dropped at the stage.
Just after I’ve created my JavaScript, I create some HTML to hold it all. It’s really simple and crude, but will do the job and show what’s to be shown.

<div id="wrapper">
  <div id="options">
    <div id="drag1" class="drag">
    </div>
    <!-- end of drag1 -->
    <div id="drag2" class="drag">
    </div>
    <!-- end of drag2 -->
    <div id="drag3" class="drag">
    </div>
    <!-- end of drag3 -->
    <div id="drag4" class="drag">
    </div>
    <!-- end of drag4 -->
    <div id="drag5" class="drag">
    </div>
    <!-- end of drag5 -->
    <div id="drag6" class="drag">
    </div>
    <!-- end of drag6 -->
  </div>
  <!-- end of options -->
  <div id="frame">
    <span id="title">
    <h2>
      What do you know?
    </h2>
    </span>
    <table id="tbldevs" border="1">
      <thead>
        <tr>
          <th>
            <span id="names">John</span>
          </th>
          <th>
            <span id="names">Paul</span>
          </th>
          <th>
            <span id="names">George</span>
          </th>
          <th>
            <span id="names">Ringo</span>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
        <tr>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
          <td>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
  <!-- end of frame -->
</div>
<!-- end of wrapper -->

It really is very simple and only creates some divs (which will be manipulated), and a table with a bunch of lines.
The css is then applied, so all the images load, and show the pretty stuff.
I’ve added comments to my code, so I think it’s pretty simple to follow it. I’ll be using this same code for a next example which will add a little more functionality to it. In the meantime, you can check the working example or download the code.
And that’s my take on it. Obviously someone might have a better way of doing it, so if you do, by all means  bring it on, and I shall update this post.
Hope you enjoy it!

112 Comments

  1. OK. Julio from previous comments had an answer.

    Replace: objName = “#clonediv” + counter

    WITH

    objName = “#clonediv” + counter++;

  2. Hi,
    how can we drag the clone,which is dropped in the drop div ? Any solution ?

  3. I want to use the margin property instead of top and left so that I can save the dragged data in database and reuse in some other pages. any thoughts?

  4. Hi, but why this code dont work:

    $(function() {
    $( “.draggable” ).resizable();
    $( “.draggable” ).draggable({
    revert: ‘invalid’,
    helper: ‘clone’, // <—-
    snap: "#drop_here td",
    opacity: 0.7
    });
    $( "#drop_here td" ).droppable({
    accept: '.draggable',

    });
    });

  5. hi, Marcos Placona !!

    first of all thanks for your post, i have a question here,
    i want to save the dragged images(layout) in to database.
    can you help regarding this…….

  6. how drag and drop, clone inputs not divs ty

  7. I am doing drag and drop for shopping cart and I place all my products in list items with float left. And I applied this drag and drop jquery functionality, if we drag 2nd element this clone is coming from first item not from the 2nd item. How can I solve this?
    Please help me out

  8. Hello Marcos,

    Thanks for your post, is the best example I find (for drag and cloning images). I doing a little very simple game for kids for add leaves and fruits in one tree, but I have the same problem as explain PRAKASH in the last post.

    By other hand, they are one other issue concerning all the devises using the touch interface, I try in iPhone, smartphones and tablets Android, but the code did not work. I try by many wais to add scripts for emulate the mouse, but unfortunately I dont find a solution for this.

    Please, can you help me for find a solution for this…

  9. heloo… Seems its supper interesting… Can I use textboxes, textareas instead of using images and, drop them where I need to place.

  10. this scenario fails the setup.

    1. drag a draggable onto the droppable.

    2. drag a draggable back onto the draggable parent container.

  11. HI , i’ve used your code for the drag and drop, but my problem is, i want the draggable to be dropped in div which is in frame. If i try doing that the draggable is disappearing after i drop it.. why is it so? can anyone help? Thanks.

  12. sir i have multiple products images so i want to add only single product image in cart when we choose another product image how can i remove previous selected product image before add new product image in cart…………..Please Reply Thanks So Much.

3 Pingbacks

  1. 10 jQuery Drag and Drops | jQuery4u
  2. I am a published author - jQuery Drag-and-Drop Grids How-to | Books | Marcos Placona Blog
  3. how can i restrict the droppable area in drag/drop jquery? | QueryPost.com

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>