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:

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!
Hi Marcos, I have a small question.
In the droppable i have one dragged element i want to clone that div using a button and apply all resizable to that clone div . Is it possible to make a dropped element clone using a button? If yes Let me Know
That’s very kind of you Hary. I will test that and should it work, modify the code (giving due credit).
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?
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
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?
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 ??
To run this without internet, simply download the jquery library locally, and use a reference to that instead.
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?
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(#).
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++;
add this param in draggable
revert : 'invalid',
To have an smooth return effect
(( sorry for my english ))
That’s very nice Julio, thanks for collaborating. And your English is fine
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 !
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
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.....p/map.html
http://bzone2.makeeitsolutions...../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
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.
hi julio, u r code is working fine and in which browser you got the problem.
Hi Harry, I just run, the only problem is that it moves a few pixels when it is cloned.
Im using firefox 8.0
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?
ITS ALIVE!!!!!!!!!!!!!!!!!!!!!!!!!!!
It works
http://www.sistemus.com/dragdrop/
Thank you for you code Marcos Placona !!!
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
You can use all the code if you want it.
Thanks to your code i did it.
Sure thing, as long as you give credits with the URL.
Cheers
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!
See Julio’s answer a few posts down, as he’s fixed this in his example.
Cheers
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.
[...] [...]
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?
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