Switch On The Code RSS Button - Click to Subscribe
Jul
17

Simple Flex Drag and Drop

flex icon

Today I am going to run through a smallish tutorial on creating and using drag and drop in Flex using the DragManager class, which is a utility provided to make drag and drop easy. I should also mention, right off the bat, that some things like lists already have various drag and drop features built in. I however will be showing an example that is useful for any custom drag jobs you might need to do.

The application below shows the functionality that I will be building today. It is a very simple demo that has a few games up at the top that can be added to your shopping cart by dragging them down into the basket area. Once dropped into the "basket" they will show up in the shopping cart list. The interface is simple and the code is simple - and you can grab that code using this link: Drag and Drop Source Code.




Like most Flex tutorials I am going to quickly take a glance at the user interface which includes a couple canvases, labels, and a datagrid. The most important pieces are the images of the games and the basket drop canvas. As seen below, all the images have the MouseDown event hooked up and the basket canvas has the dragEnter and dragDrop events setup. The handlers for these events are going to do all the work to make the drag and drop to run nicely.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute" width="374" height="406">

  <mx:Label x="0" y="210" text="Games"
    width="118" height="42" fontSize="28" color="#818181"/>

  <mx:Image name="Bioshock" x="2" y="2"
    source="{bioshock_icon}" mouseDown="doDrag(event)" />

  <mx:Image name="Crysis" x="120" y="2"
    source="{crysis_icon}" mouseDown="doDrag(event)" />

  <mx:Image name="Halo" x="240" y="2"
    source="{halo_icon}" mouseDown="doDrag(event)" />

  <mx:Image name="Neverwinter Nights" x="50" y="110"
    source="{neverwinter_icon}" mouseDown="doDrag(event)" />

  <mx:Image name="World of Warcraft" x="200" y="110"
    source="{wow_icon}" mouseDown="doDrag(event)" />

  <mx:Canvas x="0" y="255" width="174" height="151"
    borderStyle="solid" backgroundColor="#12976A"
    dragEnter="dragAccept(event)"
    dragDrop="dragDrop(event)">

    <mx:Label x="0" y="0" text="Basket"
    width="118" height="42" fontSize="28" color="#FFFFFF"/>

  </mx:Canvas>
  <mx:DataGrid dataProvider="{cartContents}"
    x="173" y="255" width="201" height="151">

    <mx:columns>
      <mx:DataGridColumn headerText="Name" dataField="name"/>
      <mx:DataGridColumn headerText="Quantity" dataField="num"
        width="65"/>

    </mx:columns>
  </mx:DataGrid>
  <mx:Label x="272" y="235" text="Shopping Cart" color="#3A3A3A"
    fontWeight="bold" fontSize="12"/>

</mx:Application>

One of the first things you might notice in the above code is the references to the icons as the source for the images. Well we are going to embed these into the application. To do this we are going to add a Script tag to our application and embed the images into the appropriate variables of type Class. The first iteration of our Script tag is below.

<mx:Script>
  <![CDATA[

  [Embed("assets/bioshock_small.png")]
  private var bioshock_icon:Class;
 
  [Embed("assets/crysis_small.png")]
  private var crysis_icon:Class;
 
  [Embed("assets/halo_small.png")]
  private var halo_icon:Class;
 
  [Embed("assets/neverwinternights_small.png")]
  private var neverwinter_icon:Class;
 
  [Embed("assets/wow_small.png")]
  private var wow_icon:Class;
  ]]>
</mx:Script>

The datagrid in the interface has the dataProvider property bound to the variable called cartContents which also needs to be added to our list of variables. We will later add the items dropped in our basket to the cartContents ArrayCollection.

[Bindable]
private var cartContents:ArrayCollection = new ArrayCollection();

Getting into the meat of the tutorial we are going to look at the functions that take care of creating and accepting the drag and drop actions. First we look at the function doDrag which starts the drag and drop action.

private function doDrag(event:MouseEvent):void
{
  var img:Image = event.currentTarget as Image;
  var dragImg:Image = new Image();
  dragImg.source = img.source;
 
  var dsource:DragSource = new DragSource();
  dsource.addData(img, 'img');
 
  DragManager.doDrag(img, dsource, event, dragImg);
}

Starting off I first get the image that is being clicked on. This is pulled simply by using the currentTarget of the event. We then create an image to use for the drag indicator and set the source to same thing as the image being dragged. Next I create a DragSource which is an object to hold data that needs to be passed with the drag event. I add a single piece of data which is a reference to the image being clicked and name the data "img" - which is the name I will later pull it out with. All that is left to do is actually start the drag event using the function doDrag on the DragManager class. I need to pass the object that is initializing the drag, the data source, the mouse event, and image for the drag indicator. That takes care of starting the drag.

We now want to allow the game to be dropped into the canvas that is labeled "basket". This is going to be done using the dragEnter event on the canvas. Which will fire when the item being dragged enters the canvas area. This function is simply going to add the canvas to the list of acceptable drop areas by adding itself using the function acceptDragDrop on the DropManager class.

private function dragAccept(event:DragEvent):void
{
  var dropTarget:Canvas = event.currentTarget as Canvas;
  DragManager.acceptDragDrop(dropTarget);
}

Once an item is dropped onto the canvas we probably want to do something. This is accomplished using the dragDrop event on the canvas. Once the drop happens we get the image from the data source that we passed along with the drag action and second we add the game to our shopping cart. This is done using the helper function addToCart which check to see if the game is in the cart and if so it increase the quantity and otherwise adds the game to the cart. I did however create a Game class (included in the source) to hold the name of the game and the number in the cart - done for data binding reasons. Both of the functions follow.

private function dragDrop(event:DragEvent):void
{
  var img:Image =
    event.dragSource.dataForFormat('img') as Image;
  addToCart(img);
}

private function addToCart(img:Image):void
{
  for(var i:int = 0; i <cartContents.length; i++)
  {
    if(cartContents[i].name == img.name)
    {
      cartContents[i].num++;
      return;
    }
  }
  cartContents.addItem(new Game(img.name, 1));
}

That takes care of drag and drop in Flex. Yes, it's that easy to do simple drag and drop and also very easy to expand to complex situations using the same techniques. I also need to give props to Belia0166 over at deviantArt for creating the icons that I used in the application. If anyone has any questions feel free to leave a comment. Also don't forget about the Drag and Drop Source Code.



Posted in Flex, All Tutorials by The Fattest |

One Response

  1. Brad Simo Says:

    Greetings:
    I’m developing a Flex website and am trying to figure out the best way to integrate a shopping cart into it. I would rather not have to build one from scratch. On your blog, I looked at some of your examples that could be used as parts of a cart, but obviously I would have to add a bunch.

    Do you have any info on what would be the best what to do develop a shopping cart for a flex site or is there company that sells a shopping cart that can integrate into a Flex site?

    I would even be open to integrating with Yahoo, ebay or Amazon if there was a simple solution to do that. I’m just looking for a simple way to do this.

    Any thoughts for suggestions would be GREATLY appreciated.

    Thanks,
    Brad

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Powered by WP Hashcash