Drag and Drop
- How to write JavaScript code to drag and drop an element.
- How to use the script.aculo.us library to create sophisticated drag-and-drop applications.
Drag and Drop Basics
We will start by creating a page that demonstrates the basic drag-and-drop code. The steps are as follows:
- Create an HTML element for dragging:
<div id="DragDiv"></div>
- Assign some CSS properties to the element. Most importantly, the element must be positioned either absolutely or relatively.
#DragDiv { height:100px; width:100px; background-color:blue; position:relative; } - Create global JavaScript variables for tracking the draggable element and its current status (whether it's being dragged or not).The Dragging variable is set to true when the user clicks down on the DragDiv element.
var DragDiv; var Dragging = false; window.onload = function() { DragDiv = document.getElementById("DragDiv"); DragDiv.onmousedown = function() { Dragging = true; } } - Add code to track mouse movement. If Dragging is true, the DragDiv element should follow the mouse pointer.
document.onmousemove = function(e) { if (!e) e = window.event; if (Dragging) { DragDiv.style.left = e.clientX + "px"; DragDiv.style.top = e.clientY + "px"; } } - Add code to drop the draggable element when the user releases the mouse button. We do this by simply setting Draggable to false.
document.onmouseup = function() { Dragging = false; }
The complete code is shown below:
Code Sample: DragAndDrop/Demos/SimpleDrag.html
<html>
<head>
<style type="text/css">
#DragDiv
{
height:100px;
width:100px;
background-color:blue;
position:relative;
}
</style>
<script type="text/javascript">
var DragDiv;
var Dragging = false;
window.onload = function()
{
DragDiv = document.getElementById("DragDiv");
DragDiv.onmousedown = function()
{
Dragging = true;
}
}
document.onmousemove = function(e)
{
if (!e) e = window.event;
if (Dragging)
{
DragDiv.style.left = e.clientX + "px";
DragDiv.style.top = e.clientY + "px";
}
}
document.onmouseup = function()
{
Dragging = false;
}
</script>
<title>Simple Drag</title>
</head>
<body>
<div id="DragDiv"></div>
</body>
</html>
Open the page up in a browser to see how it works.
Although the element is draggable, the page has some shortcomings:
- The draggable element always jumps to the right and bottom of the mouse pointer. To fix this, we would have to write code that calculated the distance between the mousedown event and the top-left corner of the draggable element.
- The code uses a global variable, Dragging, to determine when the draggable element should track the mouse. This would become a problem if there were multiple draggable elements on the page.
Luckily, there is a terrific library called script.aculo.us that makes dragging and dropping very easy.
script.aculo.us
script.aculo.us is a JavaScript library built on top of Prototype.js. It is freely available at http://script.aculo.us/downloads. It includes many neat visual effects for showing and hiding, moving, scaling, and highlighting elements. We will be looking at script.aculo.us's built-in drag-and-drop functionality.
script.aculo.us comes with several source files, but they are all loaded by the script.aculo.us.js file. So to include the complete script.aculo.us library, you need only to include prototype.js and script.aculo.us.js as shown below.
<script language="javascript" src="lib/prototype.js"></script> <script language="javascript" src="src/script.aculo.us.js"></script>
Draggables
Draggables are HTML elements that can be dragged by the user. They are created as follows:
new Draggable(ElementId,Options);
The code sample below creates a page similar to the one we saw earlier in the lesson.
Code Sample: DragAndDrop/Demos/SimpleDrag-Scriptaculous.html
<html>
<head>
<style type="text/css">
#DragDiv
{
height:100px;
width:100px;
background-color:blue;
position:absolute;
}
</style>
<script type="text/javascript" src="../../prototype.js"></script>
<script type="text/javascript" src="../../scriptaculous_src/scriptaculous.js"></script>
<script type="text/javascript">
window.onload = function()
{
new Draggable("DragDiv");
}
</script>
<title>Simple Drag</title>
</head>
<body>
<div id="DragDiv"></div>
</body>
</html>
As you can see, this is a bit easier to write than the one we saw before. It also works better as it doesn't make the draggable element jump to bottom-right of the mouse pointer. And the best thing is that it's easily extensible by passing additional options to the Draggable() constructor. These options are passed in as properties of an object. They are listed in the table below.
Draggable Options Option Default Description handle (none) Sets whether the element should only be draggable by an embedded handle. The value must be an element reference, an element id, or a class name. revert false If true, the element returns to its original position when it is dropped. revert can also be set to a callback function to be called when the Draggable is dropped. The draggable element is passed into the callback function. snap false If not set to false, creates a snapping effect. Valid formats are xy or [x,y] or function(x,y){ return [x,y] }. zindex 1000 The zindex of the draggable element. constraint (none) Makes the element only vertically (vertical) or horizontally (horizontal) draggable. The code sample below shows how these options are used.
Code Sample: DragAndDrop/Demos/Drag-ScriptaculousWithOptions.html
---- Code Omitted ----.Handle { height:10px; width:10px; background-color:red; float:right; margin:4px; }---- Code Omitted ----<script type="text/javascript"> window.onload = function() { new Draggable("DragDiv", {handle:"Handle",constraint:"horizontal",revert:Dropped}); } function Dropped(DRAGGABLE) { document.getElementById("Message").innerHTML = ("Dropped " + DRAGGABLE.style.left + " from the left."); } </script> <title>Drag With Options</title> </head> <body> <div id="DragDiv"><div class="Handle"></div></div> <div id="Message"></div> </body> </html>
Disabling Draggables
Draggables can be disabled (i.e, made undraggable) with the destroy() method. The syntax is shown below:
var mydrag = new Draggable(ElementId,Options); mydrag.destroy();
Droppables
Droppables are HTML elements that Draggable elements can be dropped into. They are created as follows:
Droppables.add(ElementId,Options);
As with Draggables, new Droppables can be created with options. Some options listed in the table below.
| Option | Default | Description |
|---|---|---|
| accept | (none) | Can be set to a CSS class name or an array of CSS class names. The Droppable will only register if a Draggable with one of the accepted class names is dropped on it. If not set, the Droppable will accept all Draggables. |
| hoverclass | (none) | Sets the class name for the Droppable when an acceptable Draggable is hovering over it. |
| onDrop | (none) | Sets the callback function to be called when a Draggable is dropped on the Droppable. The callback function gets three arguments passed in: the Draggable, the Droppable, and the mouse event. |
The code sample below shows how Droppables are used.
Code Sample: DragAndDrop/Demos/SimpleDrop-Scriptaculous.html
<html>
<head>
<style type="text/css">
#DragDiv1
{
height:100px;
width:100px;
background-color:blue;
position:absolute;
}
#DragDiv2
{
height:100px;
width:100px;
background-color:red;
position:absolute;
left:100px;
}
#DropDiv
{
height:200px;
width:200px;
background-color:yellow;
position:absolute;
top:100px;
left:300px;
}
.DropHover
{
border:1px dashed green;
}
#Message
{
position:relative;
left:110px;
}
</style>
<script type="text/javascript" src="../../prototype.js"></script>
<script type="text/javascript" src="../../scriptaculous_src/scriptaculous.js"></script>
<script type="text/javascript">
window.onload = function()
{
new Draggable("DragDiv1");
new Draggable("DragDiv2");
Droppables.add("DropDiv",{onDrop:Dropped,accept:"OK",hoverclass:'DropHover'});
}
function Dropped(DRAGGABLE,DROPPABLE,MOUSEEVENT)
{
document.getElementById("Message").innerHTML = ("Dropped " + DRAGGABLE.style.left + " from the left.");
DROPPABLE.innerHTML = "Accepted";
}
</script>
<title>Simple Drop</title>
</head>
<body>
<div id="DropDiv"></div>
<div id="DragDiv1" class="OK"></div>
<div id="DragDiv2" class="notOK"></div>
<div id="Message"></div>
</body>
</html>
Disabling Droppables
Droppables can be disabled with the remove() method. The syntax is shown below:
Droppables.remove(ElementId);
A More Interesting Example
If you're interested in seeing a more interesting example of drag-and-drop menus, open DragAndDrop/Demos/drag.html in your browser. This example uses an Ajax technique to get the user's preferences and displays the menus according to those preferences. When the user drags and drops the elements, Ajax is used again to record the new preferences. This example uses some pretty sophisticated code, but it would be far more complicated trying to write this without the use of the script.aculo.us library.
Drag and Drop Conclusion
In this lesson of the Ajax tutorial, you have learned how to create drag-and-drop elements using the script.aculo.us library.
