Adobe Flex 3 Help

Drag and drop examples

Example: Using a container as a drop target

To use a container as a drop target, you must use the backgroundColor property of the container to set a color. Otherwise, the background color of the container is transparent, and the Drag and Drop Manager is unable to detect that the mouse pointer is on a possible drop target.

In the following example, you use the <mx:Image> tag to load a draggable image into a Canvas container. You then add event handlers to let the user drag the Image control within the Canvas container to reposition it:

<?xml version="1.0"?>
<!-- dragdrop\DandDImage.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
            //Import classes so you don't have to use full names.
            import mx.managers.DragManager;
            import mx.core.DragSource;
            import mx.events.DragEvent;
            import flash.events.MouseEvent;

            // Embed icon image.
            [Embed(source='assets/globe.jpg')]
            public var globeImage:Class;

            // The mouseMove event handler for the Image control
            // initiates the drag-and-drop operation.
            private function mouseMoveHandler(event:MouseEvent):void 
            {                
                var dragInitiator:Image=Image(event.currentTarget);
                var ds:DragSource = new DragSource();
                ds.addData(dragInitiator, "img");               

                DragManager.doDrag(dragInitiator, ds, event);
            }
            
            // The dragEnter event handler for the Canvas container
            // enables dropping.
            private function dragEnterHandler(event:DragEvent):void {
                if (event.dragSource.hasFormat("img"))
                {
                    DragManager.acceptDragDrop(Canvas(event.currentTarget));
                }
            }

            // The dragDrop event handler for the Canvas container
            // sets the Image control's position by 
            // "dropping" it in its new location.
            private function dragDropHandler(event:DragEvent):void {
                Image(event.dragInitiator).x = 
                    Canvas(event.currentTarget).mouseX;
                Image(event.dragInitiator).y = 
                    Canvas(event.currentTarget).mouseY;
            }
        ]]>
    </mx:Script>
    
    <!-- The Canvas is the drag target --> 
    <mx:Canvas id="v1" 
        width="500" height="500"  
        borderStyle="solid" 
        backgroundColor="#DDDDDD"
        dragEnter="dragEnterHandler(event);" 
        dragDrop="dragDropHandler(event);">
        
        <!-- The image is the drag initiator. -->
        <mx:Image id="myimg" 
            source="@Embed(source='assets/globe.jpg')" 
            mouseMove="mouseMoveHandler(event);"/> 
    </mx:Canvas>
</mx:Application>

The executing SWF file for the previous example is shown below:

Example: Specifying the drag proxy

In the event handler for the mouseDown or mouseUp event, you can optionally specify a drag proxy in the doDrag() method of the DragManager class. If you do not specify a drag proxy, Flex uses a default proxy image. The doDrag() method takes the following optional arguments to specify the drag proxy and its properties.

Argument

Description

dragImage

The image that specifies the drag proxy.

To specify a symbol, such as a JPEG image of a product that a user wants to order, use a string that specifies the symbol's name, such as myImage.jpg.

To specify a component, such as a Flex container or control, create an instance of the control or container, configure and size it, and then pass it as an argument to the doDrag() method.

xOffset

Number that specifies the x offset, in pixels, for the dragImage. This argument is optional. If omitted, the drag proxy is shown at the upper-left corner of the drag initiator. The offset is expressed in pixels from the left edge of the drag proxy to the left edge of the drag initiator, and is usually a negative number.

yOffset

Number that specifies the y offset, in pixels, for the dragImage. This argument is optional. If omitted, the drag proxy is shown at the upper-left corner of the drag initiator. The offset is expressed in pixels from the top edge of the drag proxy to the top edge of the drag initiator, and is usually a negative number.

imageAlpha

A Number that specifies the alpha value used for the drag proxy image. If omitted, Flex uses an alpha value of 0.5. A value of 0 corresponds to transparent and a value of 1.0 corresponds to fully opaque.

You must specify a size for the drag proxy image, otherwise it does not appear. The following example modifies the example in Example: Using a container as a drop target to use a 15 pixel by 15 pixel Image control as the drag proxy:

<?xml version="1.0"?>
<!-- dragdrop\DandDImageProxy.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
            //Import classes so you don't have to use full names.
            import mx.managers.DragManager;
            import mx.core.DragSource;
            import mx.events.DragEvent;
            import flash.events.MouseEvent;

            // Embed icon image.
            [Embed(source='assets/globe.jpg')]
            public var globeImage:Class;

            // The mouseMove event handler for the Image control
            // initiates the drag-and-drop operation.
            private function mouseOverHandler(event:MouseEvent):void 
            {                
                var dragInitiator:Image=Image(event.currentTarget);
                var ds:DragSource = new DragSource();
                ds.addData(dragInitiator, "img");               

                // The drag manager uses the Image control 
                // as the drag proxy and sets the alpha to 1.0 (opaque),
                // so it appears to be dragged across the Canvas.
                var imageProxy:Image = new Image();
                imageProxy.source = globeImage;
                imageProxy.height=15;
                imageProxy.width=15;                
                DragManager.doDrag(dragInitiator, ds, event, 
                    imageProxy, -15, -15, 1.00);
            }
            
            // The dragEnter event handler for the Canvas container
            // enables dropping.
            private function dragEnterHandler(event:DragEvent):void {
                if (event.dragSource.hasFormat("img"))
                {
                    DragManager.acceptDragDrop(Canvas(event.currentTarget));
                }
            }

            // The dragDrop event handler for the Canvas container
            // sets the Image control's position by 
            // "dropping" it in its new location.
            private function dragDropHandler(event:DragEvent):void {
                Image(event.dragInitiator).x = 
                    Canvas(event.currentTarget).mouseX;
                Image(event.dragInitiator).y = 
                    Canvas(event.currentTarget).mouseY;
            }
        ]]>
    </mx:Script>
    
    <!-- The Canvas is the drag target --> 
    <mx:Canvas id="v1" 
        width="500" height="500"  
        borderStyle="solid" 
        backgroundColor="#DDDDDD"
        dragEnter="dragEnterHandler(event);" 
        dragDrop="dragDropHandler(event);">
        
        <!-- The image is the drag initiator. -->
        <mx:Image id="myimg" 
            source="@Embed(source='assets/globe.jpg')" 
            mouseMove="mouseOverHandler(event);"/> 
    </mx:Canvas>
</mx:Application>

The executing SWF file for the previous example is shown below:

To use a control with specific contents, such as a VBox control with a picture and label, you must create a custom component that contains the control or controls, and use an instance of the component as the dragProxy argument.

Example: Handling the dragOver and dragExit events for the drop target

The dragOver event occurs when the user moves the mouse over a drag-and-drop target whose dragEnter event handler has called the DragManager.acceptDragDrop() method. This event is dispatched continuously as the user drags the mouse over the target. The dragOver event handler is optional; you do not have to define it to perform a drag-and-drop operation.

The dragOver event is useful for specifying the visual feedback that the user gets when the mouse is over a drop target. For example, you can use the DragManager.showFeedback() method to specify the drag-feedback indicator that appears within the drag proxy image. This method uses four constant values for the argument, as the following table shows:

Argument value

Icon

DragManager.COPY

A green circle with a white plus sign indicating that you can perform the drop.

DragManager.LINK

A grey circle with a white arrow sign indicating that you can perform the drop.

DragManager.MOVE

A plain arrow indicating that you can perform the drop.

DragManager.NONE

A red circle with a white x appears indicating that a drop is prohibited. This is the same image that appears when the user drags over an object that is not a drag target.

You typically show the feedback indicator based on the keys pressed by the user during the drag-and-drop operation. The DragEvent object for the dragOver event contains Boolean properties that indicate whether the Control or Shift keys are pressed at the time of the event: ctrlKey and shiftKey, respectively. No key pressed indicates a move, the Control key indicates a copy, and the Shift key indicates a link. You then call the showFeedback() method as appropriate for the key pressed.

Another use of the showFeedback() method is that it determines the value of the action property of the DragEvent object for the dragDrop, dragExit, and dragComplete events. If you do not call the showFeedback() method in the dragOver event handler, the action property of the DragEvent is always set to DragManager.MOVE.

The dragExit event is dispatched when the user drags the drag proxy off the drop target, but does not drop the data onto the target. You can use this event to restore any visual changes that you made to the drop target in the dragOver event handler.

In the following example, you set the dropEnabled property of a List control to true to configure it as a drop target and to use the default event handlers. However, you want to provide your own visual feedback, so you also define event handlers for the dragEnter, dragExit, and dragDrop events. The dragOver event handler completely overrides the default event handler, so you call the Event.preventDefault() method to prohibit the default event handler from execution.

The dragOver event handler determines whether the user is pressing a key while dragging the proxy over the target, and sets the feedback appearance based on the key that is pressed. The dragOver event handler also sets the border color of the drop target to green to indicate that it is a viable drop target, and uses the dragExit event handler to restore the original border color.

For the dragExit and dragDrop handlers, you only want to remove any visual changes that you made in the dragOver event handlers, but otherwise you want to rely on the default Flex event handlers. Therefore, these event handlers do not call the Event.preventDefault() method:

<?xml version="1.0"?>
<!-- dragdrop\DandDListToListShowFeedback.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    creationComplete="initApp();">

    <mx:Script>
        <![CDATA[
            import mx.managers.DragManager;
            import mx.events.DragEvent;
            import mx.collections.ArrayCollection;
    
            private function initApp():void {
                firstList.dataProvider = new ArrayCollection([
                    {label:"First", data:"1"},
                    {label:"Second", data:"2"},
                    {label:"Third", data:"3"},
                    {label:"Fourth", data:"4"}
                ]);
                secondList.dataProvider = new ArrayCollection([]);
            }

            // Variable to store original border color.
            private var tempBorderColor:uint;
            
            // Flag to indicate that tempBorderColor has been set.
            private var borderColorSet:Boolean = false;

            private function dragOverHandler(event:DragEvent):void {
            
                // Explpicitly handle the dragOver event.            
                event.preventDefault();
                
                // Since you are explicitly handling the dragOver event,
                // call showDropFeedback(event) to have the drop target
                // display the drop indicator.
                // The drop indicator is removed
                // automatically for the list controls by the built-in 
                // event handler for the dragDrop event.
                event.currentTarget.showDropFeedback(event);
            
                if (event.dragSource.hasFormat("items"))
                {
                    // Set the border to green to indicate that 
                    // this is a drop target.
                    // Since the dragOver event is dispatched continuosly 
                    // as you move over the drop target, only set it once.
                    if (borderColorSet == false) {                 
                        tempBorderColor = 
                            event.currentTarget.getStyle('borderColor');
                        borderColorSet = true;
                    }
                
                    // Set the drag-feedback indicator based on the 
                    // type of drag-and-drop operation.
                    event.currentTarget.setStyle('borderColor', 'green');
                    if (event.ctrlKey) {                    
                        DragManager.showFeedback(DragManager.COPY);
                        return;
                    }
                    else if (event.shiftKey) {
                        DragManager.showFeedback(DragManager.LINK);
                        return;
                    }
                    else {
                        DragManager.showFeedback(DragManager.MOVE);
                        return;
                    }
                }

                // Drag not allowed.
                DragManager.showFeedback(DragManager.NONE);                
            }
            
            private function dragDropHandler(event:DragEvent):void {
                dragExitHandler(event);
            }            

            // Restore the border color.
            private function dragExitHandler(event:DragEvent):void {
              event.currentTarget.setStyle('borderColor', tempBorderColor);
              borderColorSet = true;
            }
        ]]>
    </mx:Script>

    <mx:HBox id="myHB">
        <mx:List  id="firstList" 
            dragEnabled="true"
            dragMoveEnabled="true"/>

        <mx:List  id="secondList" 
            borderThickness="2"
            dropEnabled="true"
            dragOver="dragOverHandler(event);"
            dragDrop="dragExitHandler(event);"
            dragExit="dragExitHandler(event);"/>
    </mx:HBox>
    
    <mx:Button id="b1" 
        label="Reset"
        click="initApp()"
    />
    
</mx:Application>

The executing SWF file for the previous example is shown below: