Shaun Mccran

My digital playground

24
M
A
R
2011

JQuery Drag and Drop to multiple div elements

My only previous experience with Drag and Drop web development was with Flex 2, which I have to say was a bit of a nightmare. There was an astronomical amount of setup to do in terms of event listeners and mouse watching services, so I was reluctant to get back into 'Drag and Drop' with any other technology.

This article explains how straight forward the JQuery Drag and Drop interfaces are to use, and how I constructed a Drag and Drop example using multiple divs.

There is an example of a JQuery Drag and Drop demo here. http://www.mccran.co.uk/examples/jquery-drag-drop

What I needed to do was create a draggable element that could be dropped into one of several different divs. Think of the scenario where you are dropping a ballet paper into one of many possible selections. Based on this I needed to create a draggable element, and several 'target' divs that can be uniquely identified when the drag element is dropped within their bounds.

My first recommendation is to go and check out the JQuery UI demos here: http://jqueryui.com/demos/draggable/. It is a great resource for JQuery UI examples, a lot of this article is based on several of the demo's from the site.

I've started off by including all the JQuery UI js files, the JQuery library and some CSS.

view plain print about
1<link rel="stylesheet" href="jquery.ui.all.css">
2
3<s/cript type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
4
5<s/cript src="jquery.ui.core.js"></script>
6<s/cript src="jquery.ui.widget.js"></script>
7
8<s/cript src="jquery.ui.mouse.js"></script>
9<s/cript src="jquery.ui.draggable.js"></script>
10<s/cript src="jquery.ui.droppable.js"></script>
11
12<link rel="stylesheet" href="demos.css">
13
14<style>
15.droppable { width: 150px; height: 150px;
16            padding: 0.5em; float: left; margin: 10px; }
17
18.draggable { width: 100px; height: 100px;
19        padding: 0.5em; float: left; margin: 10px;
20        cursor: hand; cursor: pointer;
21border: 1px solid #000;}
22</style>

Next create the div elements that make up the draggable element and the target elements.

view plain print about
1<div class="draggable" class="ui-widget-content">
2    <p>I return home when I'm not dropped in the right place</p>
3</div>
4
5<div class="droppable ui-widget-header" id="element 1">
6    <p>Drop me here</p>
7</div>
8
9<div class="droppable ui-widget-header" id="element 2">
10    <p>Drop me here</p>
11</div>
12
13<div class="droppable ui-widget-header" id="element 3">
14    <p>Drop me here</p>
15</div>

I've given each of them unique ID's to show that they are being uniquely identified later.

Next create a function to handle the draggable element. I've set the value of 'revert:invalid' here as I want the div to snap back into its original position if it does not match a destination element.

view plain print about
1<s/cript>
2$(function() {
3    $( ".draggable" ).draggable({ revert: "invalid" });
4
5    $( ".droppable" ).droppable({
6        activeClass: "ui-state-hover",
7        hoverClass: "ui-state-active",
8        drop: function( event, ui ) {
9
10            var targetElem = $(this).attr("id");
11
12            $( this )
13                .addClass( "ui-state-highlight" )
14                .find( "p" )
15                .html( "Dropped! inside " + targetElem );
16
17                alert(targetElem);
18
19        }
20    });
21});
22</script>

Next inside the droppable function I've specified a few design classes, and a handler for a drop event. This is the event that will 'catch' when a user releases a div onto the target. You can interact with the target div in the same way as other JQuery elements like $(this). In this way you can identify exactly which element a user dropped the dragged object on.

There is an example of a JQuery Drag and Drop demo here. http://www.mccran.co.uk/examples/jquery-drag-drop

TweetBacks
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Amit's Gravatar Shaun your example is very good. I would like to know few things from your example.
1. How could I restrict the drop facility to a particular element, lets take, I want to drop it only on 2nd container not on other two.
2. If I take out the dropped element from the container, how could I able to change the container's colour back to original.
3. Is this possible with the multiple elements dropping in a specific container. I mean, suppose there are 2 dropping element and I want to drop them to specific container only, i.e. dropping element1 to container1 only and dropping element2 to container2 only.
# Posted By Amit | 25/05/2011 14:54
Shaun McCran's Gravatar Hi Amit,
Glad you liked the example. To answer your questions:
1. You can restrict the elements that can be dropped on by removing the JQuery selector class. In my example I am using .droppable as the class. If you remove this from the elements you don't want to drop on, they wont be usable anymore.

2. There is a JQuery listener on draggable elements, so when a user picks it up you could use the $().removeclass('classname') then $().addclass('classname') methods to change the properties of the element.

3. Yes, you could map the drag and drop elements to different containers. I'd probably do it in a slightly short cut way, create groups of classes (draggable1, droppable1 and draggable2, droppable2) that way you can pair them up.

If I get a chance I'll try and mock an example up.
# Posted By Shaun McCran | 27/05/2011 10:28
sam's Gravatar Hi Shaun
I have been battling with this functionality on and off for a while now. The major use to reorder CFM pages in within a section of a basic CMS. Would be great to be able to drag from one section to another, but just happy to get within a section working and order to be saved ! Anyhow excited about finding your post. thanks very much in advance, SAm
# Posted By sam | 30/05/2011 02:47
Shaun's Gravatar Hi Sam,
Apologies for the delay, I've migrated this site to a new server, took longer than I imagined.

I like the sound of the functionality that you mentioned. I think I'd do an initial query to get each page and its section, and display them in order. Assign their record id to each div, then when they are moved I'd fire an ajax request straight back to the server. You could pass back their new position and the parent div id, which would be the section reference.

How does that sound?
# Posted By Shaun | 04/06/2011 13:58
Sam's Gravatar No probs Shaun. I got busy too! I have it so the pages are coming out of the database now, and they are displaying based on a section of the website. Say for "Services" section, all sub pages come out. I have "handles" (the cursor changes to a handle) on each of the rows now, so you can "grip" them and move them to the new position. Nice. We like this. However, I still cant get it to write back to the db, but i must be close. I can see it being able to be extended, so you could drag around the output order of the "sections", but yeah... :)
# Posted By Sam | 08/06/2011 14:21
Shaun's Gravatar Good stuff Sam!

Do you have an example? Can you host a flat version of it, then I can add in the JSON request and you can see how I'd do it.
# Posted By Shaun | 08/06/2011 14:41
Sajid's Gravatar Hi I get help from your blog. Thanks dude
# Posted By Sajid | 30/09/2011 00:09
Shaun mccran's Gravatar Hi,
Good! Glad I could help.

Were you have problems with JQuery drag and drop then?
# Posted By Shaun mccran | 30/09/2011 00:14
Mark's Gravatar This a great script. How can I get the original source id as well as the target id. I want to send both as aparams in an ajax request.

Can I set both dragagble and droppable to each of a grid of div or td elements which represent games and the id numbers are the game record id numbers.
# Posted By Mark | 05/10/2011 04:19
Shaun McCran's Gravatar Hi Mark, glad you liked it.

I think this article may be closer to what you are looking for: http://www.mccran.co.uk/index.cfm/2011/6/17/JQuery...

Its very similar but in it I am picking up the id of the dropped element. Its a kind of shopping basket example. There is a working set of code in the example as well.
# Posted By Shaun McCran | 05/10/2011 05:26
Mark's Gravatar Actually, this example seems closer to what i want. My idea is to do something like

drag: function( event, ui ) { sourceElem = $(this).attr("id");

where source elem is a global var. Then I could pick that up ,in the function you invoke in the drop event and create an ajax request. Does that sound like the best way? All I need is an ajax request with both id numbers as params.
# Posted By Mark | 05/10/2011 05:37
dAnjou's Gravatar Saved my ass, thanks :)
# Posted By dAnjou | 09/12/2011 16:56
Shaun McCran's Gravatar @dAnjou, Thanks, glad you liked it. Did it fix your issue?
# Posted By Shaun McCran | 12/12/2011 09:23
ashu's Gravatar excellent & very helpfull example... i will help me in my final year project thanks... keep it up... :)
# Posted By ashu | 14/12/2011 10:47
Shaun McCran's Gravatar Hi Ashu, glad I could help. What sort of project are you writing for your final year?
# Posted By Shaun McCran | 18/12/2011 14:12
Degree In Medical Assisting's Gravatar site..
# Posted By Degree In Medical Assisting | 21/12/2015 23:35
jaipur to pushkar taxi's Gravatar I want to send both as aparams in an ajax request.

Can I set both dragagble and droppable to each of a grid of div or td elements which represent games and the id numbers are the game record id numbers.
# Posted By jaipur to pushkar taxi | 06/01/2016 02:45
site visitors's Gravatar I was reading your article and wondered if you had considered creating an on this subject. Your writing would sell it fast. You have a lot of writing talent.
# Posted By site visitors | 04/02/2016 03:13
Back to top