Flex Tutorials – Drag-and-Drop in Flex

June 14, 2010 at 12:12 am Leave a comment

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.

Overview of Drag-and-Drop

Drag-and-drop operations have three main stages: initiation, dragging, and dropping.
Initiation, Dragging, and Dropping
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. A drag source object is created for holding data related to the drag session.

Dragging occurs when the user, still holding down the mouse button, moves the drag initiator component around the application. While a component is being dragged Flex will display an image called a drag proxy.
Dropping is the action of releasing the drag initiator component over a drop target. A potential drop target can inspect the drag source and determine whether to allow (or accept) a drop.

Example:

We’re going to follow these steps to learn about Drag-and-Drop in Flex:
1.Create a Project and Application
2.Create some Boxes (one for dragging, one for dropping)
3.Make the Red Box Draggable
4.Make the Blue Box a Drop Target
5.Handle the Drop
6.Show Feedback
7.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:
1. Select File > New Flex Project
2. Give your project a name (i.e. FlexTutorials)

I’ve created a Flex Project for holding my tutorial application.


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.

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&quot; 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&quot; layout="vertical"
name="Drag and Drop Tutorial">

</mx:Application>

I’ve created a Flex Application for holding my Drag-and-Drop tutorial code.


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 on creationComplete

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml&quot; 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.
I’ve added an init() function to my application’s <mx:Script>.


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.
I’ve created two boxes, one red and one blue, in MXML.


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_DOWN to the init() function
Determine drag initiator and call DragManager’s beginDrag() 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…
I’ve made the Red Box draggable by adding a "mouse down" listener.


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).
I’ve drag-enabled the Red Box by passing it as a drag initiator to the DragManager.

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.
By adding a "drag enter" event listener.
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.
I’ve drop-enabled the Blue Box by passing it as a //drop target// to the DragManager.


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.
I’ve handled the drop by adding a "drag drop" event listener to the Blue Box.
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 data
LINK – signifies that the drop will link some data
MOVE – signifies that the drop will move some data
NONE – 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.
I’ve enhanced the drag-drop by adding feedback support via the DragManager.


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.
I’ve enhanced the drag-drop by adding information to the DragSource object.
 

Click here to view the Demo

Entry filed under: Flex for Beginners.

AIR Tutorials – How to keep WindowApplication on top of the applications in AIR Hello world!

Leave a comment

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendar

June 2010
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

Most Recent Posts