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. Marcos Placona

    November 2, 2011 at 09:54

    That’s very kind of you Hary. I will test that and should it work, modify the code (giving due credit).

  2. Hi Marcos!

    Thanks so much! This gave me a great head start on a project. Question, if I understand, are element positions are being stored in a class rather than as id attributes? I’m trying to capture the X,Y coordinates in an array and then write the coordinates to a MySql database with a PHP script.

    The JavaScript function to capture the data in an array is set to look for the coordinates as element ID attributes, and I think that’s why it’s not working. It just returns 0s as if there is no data there. The JS function works elsewhere is is set up this way because I need the data for each of the unique multiple elements being cloned.

    So, yea or nay, and any suggestions?

  3. hi marcos i want to rotate image option with handle in drop?is it possible ?if s let me know and also clone an image using a button

  4. Hi Marcos -
    Very Cool Tutorial. I have a question however. How would I remove a specific div after it has been dropped. I wrote the following remove routine within the droppable feature but when I click on the remove button, it removes all instances of the class, rather than just the one I want to remove:


    $("#frame").draggable({
    ...
    $("#clonediv"+counter).hover(
    function () {
    $("."+itemDragged).append($(""));
    //Remove a Table

    $("#remove_table").click(function () {

    $("."+itemDragged).remove();
    $('.status #notice').html('AWE CRAP!!! I hope that table was meant to be removed, cause otherwise...it can\'t be resurrected.');
    $(".status").fadeIn('500');

    //$("#notice").html('Your div has been removed! There is no undoing that however...boo hoo.');
    });

    },
    function () {
    $(this).find("span:last").remove();
    }
    );
    );

    Any thoughts or considerations?

  5. Hi Marcos -
    Very Cool Tutorial. I have one question . How would I run this code without internet because we using http://www.google.com/jsapi.
    Is it possible to run this code without internet ??

  6. Marcos Placona

    November 10, 2011 at 08:32

    To run this without internet, simply download the jquery library locally, and use a reference to that instead.

  7. Hi Marcos, thanks a lot for the code..just one thing I noticed.
    Is this a bug or expected behavior?
    If I drop an element into the container it sticks as per normal.
    But If I pick up a new, other one but then let it go (don’t drop it in the correct container) the last element I dropped jumps back to the position of the element which I failed to drop.

    steps to produce:
    1. drop the element in the container. It drops as expected.
    2. pick up another element, drag it maybe 2px away from the starting point then let go.

    you will see that the element from step 1 bounces back to where the element in step2 should’ve been.

    Any ideas?

  8. James Harvey, im no an expert, but you are removing elements with an specific class(.), so many elements can have an specific class(.), you need to remove an element with a specific id(#).

  9. Problem: when drag an element outside div#frame, the last element cloned desapear.

    Solution: add double plus (++) in the next line of code.

    Before

    objName = "#clonediv"+counter;

    After

    objName = "#clonediv"+counter++;

  10. add this param in draggable

    revert : 'invalid',

    To have an smooth return effect

    (( sorry for my english ))

  11. Marcos Placona

    December 3, 2011 at 21:13

    That’s very nice Julio, thanks for collaborating. And your English is fine ;-)

  12. Your welcome!

    Hey Marcos, im trying to get the xy position of the cloned element when is moved (xy position inside the div#frame),

    This is my modified version :

    http://www.sistemus.com/dragdrop/

    can you help me ??

    Thanks !

  13. Marcos Placona

    December 4, 2011 at 21:44

    Hi Julio,

    I’ve just looked at your example, and it already seem to be getting the x & y coordinates. So think you’ve already nailed it ;-)

    Cheers

  14. Dear Marcos Placona,

    Many thanks for your posting, and at last i find a way for my work. I found jquery documentation and i didt get the solution, but here i got the green light. Many thanks.

    Here is what i copied and edited

    http://bzone2.makeeitsolutions.com/jothirajan/map/map.html
    http://bzone2.makeeitsolutions.com/jothirajan/map/style.css

    But while i drag and place the icon inside the frame, the icon will go to some width. But in your site it is staying on where it is dragged and placed :). Could you please help me on this part

    Many thanks
    Joel

  15. Can somebody help me?
    This is my modified code:

    http://www.sistemus.com/dragdrop/

    I added to div#frame the css position:relative,
    and when clone an element added the css position:absolute.
    With this i get the position XY inside the div#frame,
    BUT…
    when drop the element inside div#frame it cloned outside the div#frame.

    Can somebody help me to cloned inside?

    maybe is a css trick, but i dont get it.

    I realy apreciate it, Thanks.

  16. hi julio, u r code is working fine and in which browser you got the problem.

  17. Hi Harry, I just run, the only problem is that it moves a few pixels when it is cloned.

    Im using firefox 8.0

  18. I am building an open source web app to help children learn programming and I would like to know if I could get your permission to adapt your code to a part of the project?

  19. ITS ALIVE!!!!!!!!!!!!!!!!!!!!!!!!!!!

    It works :D

    http://www.sistemus.com/dragdrop/

    Thank you for you code Marcos Placona !!! :D

  20. Marcos Placona

    December 7, 2011 at 18:01

    That’s really cool Julio. well done. Do you mind if I use bits of your code to improve the sample I have here?

    Cheers

  21. You can use all the code if you want it.

    Thanks to your code i did it.

  22. Marcos Placona

    December 8, 2011 at 11:31

    Sure thing, as long as you give credits with the URL.

    Cheers

  23. When I drag and drop my moveable elements, they jump across the page when I drop them. Do you have any advice on how to fix this? The website I provided is a link to the site where I am using this code. Thanks!

  24. Marcos Placona

    December 12, 2011 at 09:50

    See Julio’s answer a few posts down, as he’s fixed this in his example.

    Cheers

  25. Hi,
    I used your example “A more elaborated jQuery Drag & Drop (with cloning)” in my project. But i am facing one problem in it please send me any suitable solution for this. The problem is as,
    I need to call one function on dragged element so, for it i add the below line
    $(“#clonediv”+counter).attr(‘onclick’, ‘test_test()’);
    of code in “.droppable” function.
    Now this function is successfully called in firefox but can’t be called in IE and Chrome browser. So please send me any solution for this problem.

  26. Hi,thx for this great example,i used it as a base
    but can u explain is it possible to add resize to the clone which was dropped in the work area?

  27. Hello Marcos,first af all thank you for this article , this code really helped me a lot but when i tried to execute de script on my plateforme, many options desapears like the fact that we can drop the same image many time, i’m woundering why?? can yoy help me please.Thanks

  28. Nice Article,
    But when i dragged in another Div, it is not allowing me to dragged it in same Div . How to Overcome from this ??

  29. Hi!,
    Just thanks a lot for the code. It is just i need ;).

  30. how to use this with jquery 1.4+ and jquery ui 1.8+ ?

  31. Hi everybody, this is half of what I’ve been looking for. I want to do something like Marcos’ original page, dragging cloned objects into squares.

    Next, I want to be able to capture what John, Paul, George and Ringo can do and submit in a form.

    It’s late, so I’ll work on it tomorrow, but if anybody has any ideas, I’m all ears.

    Thanks all.

  32. Hi,
    I’m using your code for drag and drop functionality. Its really useful and good. I have requirement as I need to drag at time multiple div’s or say images. How can I do that?

  33. I have to drop clone and save the position.Is it possible?

  34. Hi, fantastic example, this is exactly what i was searching. Just one thing, it’s not working in iexplorer 9, do you know why?
    Thanks for all this great work! Gracias!

  35. Thanks a lot Marcos, apreciate your work!

  36. hi,
    thanks for the best tutorial.i have question the code is working fine i want to rotate a cloned image .how can i achieve this.

    thank you

  37. Hey, thanks for the code!

    But how can I apply this to my website and have them saved in a database to be viewed/edited later on?

  38. Great example – just wondering if possible for 2 other features, re-sizable clones and the ability to remove clones

  39. Nice work,sir i just want that the dropped image should be resizable, can you help me in this regard.

  40. Hi,
    Great script!
    Maybe someone may help me, I am looking for a way to use drag and drop over a grid with different shapes library.
    Rectangles, squares of differents size picked up froma library and clipping together side by side over a grid.

    Anyone know how ?

  41. hey, Nice Script, I was woundering if it has sortable it will make my day and i m sure rest other will have the great use of it…i m not very good at Java script if you can make it sortable only in one column if possible.

    Thanks

  42. hi when i am dropping the div on another div my div is moving to some pixel dont know why, please help me out why is it so?
    Thanks in advance..

  43. Hi ,

    1. Your code does not work. When you download it.
    Solution add this code :
    google.load(“search”, “1″);
    google.load(“jquery”, “1.4.2″);
    google.load(“jqueryui”, “1.7.2″);

    2. I do not see any use of table columns and rows as nothing adds up in that :) .

    Thanks.

    Thanks,

  44. Hi Marcos. I have a very simple question for you (I’m no jQuery expert). I need to drag a box into another, bigger box (not unlike your example here), but when the box is over the container I can’t make it slide by itself to exactly fit its new container. I know it’s a small piece of code, but I don’t seem to make right. I will appreciate your help.

  45. Hi Marcos, I’ve used your code as a base for a drag and drop, but I want to sort the dragable elements on the left side in tabs, but cant seem to get it to work. I’m very new on jQuery and i think the problem lies with trying to use diffrent jquery librarys. How would you set up the tab script to work with this?

    Hopefully you understand my question, english is not my native tongue.

    Regards

  46. Hi,
    Good evening sir,
    I want to drag a image and save it as like facebook. I don’t no how to do. So, Please give me some suggestion.

  47. Hi , I have downloaded your code but it is not working for me .can please provide me the correct code which is working. I want to copy a image by dragging .the original image should not be moved only clone of that should be dragged. Thanks in Advance…

  48. doesn’t work, nice effort though. Thanks

  49. Marcos Placona

    December 17, 2012 at 22:14

    It does work. I’ve now updated the source to specify the correct version of jQuery

  50. Nice work, but I am having an issue with it. The first time you drag something out of the available area, it denies that. After you have moved something, you are then able to move the icon anywhere on the page and removes the last thing you moved. Oh.. let me review the other comments to see if anyone discovered that.

3 Pingbacks

    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>