Flex Drag-and-Drop: The Definitive Tutorial
Drag-and-drop lets you move components and transfer data in a Flex application via the mouse and ubiquitous "click-drag-drop" paradigm. All Flex components support drag-and-drop operations with the proper enablement.
We're going to follow these steps to learn about Drag-and-Drop in Flex:
- Create a Project and Application
- Create some Boxes (one for dragging, one for dropping)
- Make the Red Box Draggable
- Make the Blue Box a Drop Target
- Handle the Drop
- Show Feedback
- Use Drag Source
Step 1: Create a Project and Application
Create a Flex Project: FlexTutorials
First we'll want to create a Flex Project to hold this, and potentially other, tutorial applications. If you've already completed another Flex After Dark Tutorial, you can use the same project, or a different one.
To create a new Flex project using Flex/Flash Builder:
- Select File > New Flex Project
- Give your project a name (i.e. FlexTutorials)
When you create a Flex project using Flex/Flash Builder it will automatically create an application with the same name as the project. However, we are not going to use that application in this tutorial. In the next step we'll create another application specifically for this Drag-and-Drop tutorial.
Create a Flex Application: DragDrop.mxml
Next we'll create a new MXML Application called "DragDrop" (or anything you want really). This MXML file will hold all of our code for this tutorial.
To create a new Flex project using Flex/Flash Builder:
- Select File > New MXML Application
- Give your application a filename (i.e. DragDrop)
The fresh application will look something like the following code.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> </mx:Application>
Let's update the application code a little:
- Change the layout attribute to be "vertical"
- Add a name attribute with a value of "Drag and Drop Tutorial"
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" name="Drag and Drop Tutorial"> </mx:Application>
Add an init() function
Next we're going to finish our application setup by adding a <mx:Script> block and init() function.
The <mx:Script> block will hold our application's ActionScript and
the init() function will be called when our application starts.
Add the <mx:Script> and init() function:
- Add a
<mx:Script>block to your application - Add an
init()function (empty for now) - Call the
init()function oncreationComplete
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" name="Drag and Drop Tutorial" creationComplete="init()"> <mx:Script> <![CDATA[ public function init():void { } ]]> </mx:Script> </mx:Application>
We're going to use the <mx:Script> block in a future step to setup listeners.
Step 2: Create some Boxes
Create a Red Box and a Blue Box
Next were going to use MXML to create a Red Box and a Blue Box for our application.
We'll add the following code inside our <mx:Application> tag in application's MXML file.
<mx:HBox horizontalGap="100"> <mx:Canvas id="redBox" width="100" height="100" backgroundColor="Red" /> <mx:Canvas id="blueBox" width="100" height="100" backgroundColor="Blue" /> </mx:HBox>
We can now launch our application for the first time and see the results.
To launch your DragDrop application using Flex/Flash Builder:
- Select Run > Run DragDrop from the main application menu
The result should look like this, with a Red Box and Blue Box.
We'll start the fun drag-and-drop stuff in the next step.
Step 3: Make the Red Box Draggable
Initiation of a drag-and-drop operation occurs when a "drag-enabled" component is selected with the mouse and moved while holding down the mouse button. The component selected and dragged is called the drag initiator.
Red Box listens for Mouse Event
To kick off a drag-n-drop, we'll need to listen for a "mouse down" MouseEvent for the component to be dragged.
- Add listener for
MouseEvent.MOUSE_DOWNto theinit()function - Determine drag initiator and call
DragManager'sbeginDrag()function
public function init():void { // a mouseDown event will start the drag this.redBox.addEventListener( MouseEvent.MOUSE_DOWN, beginDrag ); } public function beginDrag( mouseEvent:MouseEvent ):void { ... }
We'll cover the beginDrag() method in the next step...
Start the Drag using DragManager
Dragging occurs when the user, still holding down the mouse button, moves the drag initiator component around the application.
The mx.managers.DragManager class is used for managing drag-and-drop
operations for Flex applications.
All its methods and properties are static, so you do not need to create an instance of it.
Here we'll fill in our beginDrag() function that handles our "mouse down" event.
import mx.core.DragSource; import mx.core.IUIComponent; import mx.managers.DragManager; ... public function beginDrag( mouseEvent:MouseEvent ):void { // the drag initiator is the object being dragged (target of the mouse event) var dragInitiator:IUIComponent = mouseEvent.currentTarget as IUIComponent; // the drag source contains data about what's being dragged var dragSource:DragSource = new DragSource(); // ask the DragManger to begin the drag DragManager.doDrag( dragInitiator, dragSource, mouseEvent, null ); }
The above code accomplishes the following:
- We use the mouse event's
currentTarget(the Red Box) as the drag initiator - We create a drag source object (we'll come back to this later in the tutorial)
- We call the
DragManager.doDrag()function to begin the drag operation
The Red Box is now draggable (though you can't yet drop it anywhere).
Note the new imports we used in the above code:
- import mx.core.DragSource;
- import mx.core.IUIComponent;
- import mx.managers.DragManager;
Step 4: Make the Blue Box a Drop Target
Our next step is to make the Blue Box a drop target capable of accepting a drop.
To do this we must first add an event listener for the DragEvent.DRAG_ENTER event to our Blue Box.
The DragEvent.DRAG_ENTER event occurs when a drag initiator is dragged over another component
during a drag-drop operation.
import mx.events.DragEvent; ... public function init():void { // a mouseDown event will start the drag this.redBox.addEventListener( MouseEvent.MOUSE_DOWN, beginDrag ); // accepting a drag/drop operation... this.blueBox.addEventListener( DragEvent.DRAG_ENTER, acceptDrop ); } public function acceptDrop( dragEvent:DragEvent ):void { ... }
We'll code out the acceptDrop function next to actually accept the drop.
Note the new import we used in the above code:
- import mx.events.DragEvent;
Accept the Drop using DragManager
To accept the drop we must notify the DragManager with a drop target (the Blue Box)
in response to the DragEvent.DRAG_ENTER event.
public function acceptDrop( dragEvent:DragEvent ):void { var dropTarget:IUIComponent = dragEvent.currentTarget as IUIComponent; // accept the drop DragManager.acceptDragDrop( dropTarget ); }
Now that we have accepted the drop we can let go of the Red Box on the Blue Box. Nothing exciting happens when we drop, yet, that'll be in our next step when we handle the drop.
The Red Box can be dragged to and dropped on the Blue Box.
Step 5: Handle the Drop
Handling the drop is the magic step of a drag-drop operation where your application performs the "business logic" of dragging an initiator to a target.
We are notified of a drop by adding a DragEvent.DRAG_DROP event listener on a drop target.
public function init():void { // a mouseDown event will start the drag this.redBox.addEventListener( MouseEvent.MOUSE_DOWN, beginDrag ); // accepting a drag/drop operation... this.blueBox.addEventListener( DragEvent.DRAG_ENTER, acceptDrop ); // handling the drop... this.blueBox.addEventListener( DragEvent.DRAG_DROP, handleDrop ); } public function handleDrop( dragEvent:DragEvent ):void { var dragInitiator:IUIComponent = dragEvent.dragInitiator; var dropTarget:IUIComponent = dragEvent.currentTarget as IUIComponent; Alert.show( "You dropped the Red Box on the Blue Box!" ); }
When the listener function of a DragEvent.DRAG_DROP event is called we can get the
drag initiator and drop target from the event as seen in the code above.
Our example for this tutorial simply shows an Alert message when a drop is completed.
When the Red Box is dropped on the Blue Box we get alerted.
Note the new import we used in the above code:
- import mx.controls.Alert;
Step 6: Show Feedback
The DragManager provides a static showFeedback() function that can be used to display
what type of drop operation will be performed.
The feedback is shown as a small icon next the cursor when the drag initiator is over an accepting
drop target.
DragManager feedback types:
COPY- signifies that the drop will copy some dataLINK- signifies that the drop will link some dataMOVE- signifies that the drop will move some dataNONE- no feedback (default)
public function acceptDrop( dragEvent:DragEvent ):void { var dropTarget:IUIComponent = dragEvent.currentTarget as IUIComponent; // accept the drop DragManager.acceptDragDrop( dropTarget ); // show feedback DragManager.showFeedback( DragManager.COPY ); }
The last line of code above shows how we call DragManager.showFeedback() passing the DragManager.COPY
value.
Notice now when the Red Box is held over the Blue Box we get a green "copy" icon next to the cursor
showing the drag-drop operation will copy some data.
Thanks to feedback, the drop icon is now different, showing a "copy" action will be performed.
Step 7: Use Drag Source
Back in Step 3 when we started the drag operation you may remember that we created a DragSource
object to pass to the DragManager.doDrag() function.
A DragSource object is used to communicate data between the components of a drag-drop operation.
We do this by putting data in the drag source when the drag begins that we can then inspect when deciding
whether or not to accept a drop.
Below we'll modify our beginDrag() code to add data to the drag source using the addData() function.
The addData() function takes two arguments:
- data:Object - object that specifies the drag data
- format:String - specifies the format of the data
public function beginDrag( mouseEvent:MouseEvent ):void { // the drag initiator is the object being dragged (target of the mouse event) var dragInitiator:IUIComponent = mouseEvent.currentTarget as IUIComponent; // the drag source contains data about what's being dragged var dragSource:DragSource = new DragSource(); // add some information to the drag source dragSource.addData( "Red", "color" ); // ask the DragManger to begin the drag DragManager.doDrag( dragInitiator, dragSource, mouseEvent, null ); }
Now we'll modify our acceptDrop() function to only accept the drag-drop if the drag source has
format data for the color (which we added above).
To do this we get the dragSource property from the dragEvent and check if it has data
of a specified format by calling dragSource.hasFormat() passing the format we're looking for
("color").
public function acceptDrop( dragEvent:DragEvent ):void { var dropTarget:IUIComponent = dragEvent.currentTarget as IUIComponent; var dragSource:DragSource = dragEvent.dragSource; // accept the drop if the drag source has a "color" format if( dragSource.hasFormat( "color" ) ) { DragManager.acceptDragDrop( dropTarget ); } }
Obviously the drag source example we've used is quite simple, but we could put any data/format in the drag source to enable smart drag-drop operations.
Use DragSource to communicate data between the components of a drag-drop operation.
We're Done, Thank You!
Thank you for following along. If you found this tutorial helpful, please spread the word with a blog post or via Twitter.
Let others know about this tutorial via Twitter
@flexafterdark The Definitive Tutorial on Flex Drag-and-Drop: http://bit.ly/kWh0K

