Build a Drag-and-Drop XML Image Viewer

In this Flex tutorial, we are going to create a drag & drop xml driven image viewer that when the user drags a thumbnail and drops it inside a box it will display the image’s bigger version.

View DemoDownload Source

1. Create a new flex project named GalleryDragDrop, set the name of the main MXML application file to Main.mxml and set its layout to vertical. Set its horizontalAlign property to “center”.

2. All of the informations about the images showcased in the gallery are stored in an XML file. Create an xml file that follows this structure and save it as datas.xml in the src directory :

<?xml version="1.0"?>
<gallery>
	<image>marilyn1.jpg</image>
	<image>marilyn2.jpg</image>
	<image>marilyn3.jpg</image>
	<image>marilyn4.jpg</image>
	<image>marilyn5.jpg</image>
</gallery>

3. Next, create an assets folder, and inside it create a “thumbs” folder where you store your thumbnail image files with names matching the xml file, and create a “big” folder to put the big images.

4. To load the datas from the xml use the HTTPService component :

<mx:HTTPService id="service" url="datas.xml" result="serviceHandler(event)"/>

5. Next create a Script section. Declare a variable named images as an arraycollection and defined as bindable. This variable will hold the datas retrieved from the xml in the serviceHandler function :

<mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
           
            [Bindable]
            private var images:ArrayCollection;
            
            private function serviceHandler(event:ResultEvent):void{
                images = event.result.gallery.image;
            }
                     
        ]]>
</mx:Script>

6. In order to finish this process of loading the xml datas, call the send method of the HTTPService :

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" 
     horizontalAlign="center" creationComplete="service.send()" >

7. To display the thumbnails use a Repeater and bind its dataProvider with the images variable.
Inside, add an Image component to display the thumbnail.

<mx:HBox>
		<mx:Repeater dataProvider="{images}" id="rep">
			<mx:Image source="assets/thumbs/{rep.currentItem}" />
		</mx:Repeater>
	</mx:HBox>

8. Beneath, add a VBox container with a black background that will be the drop zone for the thumbnails. Add an Image component with an id of “bigImage” to diplay the big image.

<mx:VBox width="340" height="350" backgroundColor="#000000" 
	      horizontalAlign="center" verticalAlign="middle">
			<mx:Image id="bigImage" showBusyCursor="true"/>
</mx:VBox>

9. Now let’s add the drag and drop interactions between the thumbnails and the black box.
In order to be able to drag the thumbnails, add a mouseMove event listener.

<mx:HBox>
		<mx:Repeater dataProvider="{images}" id="rep">
			<mx:Image source="assets/thumbs/{rep.currentItem}"
				mouseMove="initiateDrag(event,event.currentTarget.getRepeaterItem())" />
		</mx:Repeater>
</mx:HBox>

10. The initiateDrag function handles the mouseMove event. Inside this function, we instantiate a dragInitiator, a dragSource that holds the data being dragged and we also specify a dragProxy which is displayed while the object being dragged.

private function initiateDrag(event:MouseEvent,value:String):void{
             	
       var dragInitiator:Image= event.currentTarget as Image;   
             	
       var dragSource:DragSource = new DragSource();
       dragSource.addData(value, 'value');
             
       var dragProxy:Image = new Image();
       dragProxy.source = event.currentTarget.source;
       dragProxy.width = 100 ;
       dragProxy.height = 100 ;
              
       DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
} 

11. Next, in order to have a functional drop black box to display the big image, add the dragEnter and dragDrop event listeners.

<mx:VBox width="340" height="350" backgroundColor="#000000" 
	      horizontalAlign="center" verticalAlign="middle"
	      dragEnter="dragEnterHandler(event)"
	      dragDrop="dragDropHandler(event)">
			<mx:Image id="bigImage" showBusyCursor="true"/>
</mx:VBox>

12. The dragEnterHandler function determines whether the data being dragged is in a format that the target accepts. If so, to accept the drop, we call the DragManager.acceptDragDrop() method.

private function dragEnterHandler(event:DragEvent):void {
     var dropTarget:VBox =event.currentTarget as VBox;
      if (event.dragSource.hasFormat('value')) {
            DragManager.acceptDragDrop(dropTarget);
      }
}		   

13. Finally the dragDropHandler function, which is called when a thumbnail is dropped inside the black box, set the source of the big image to the appropriate value.

private function dragDropHandler(event:DragEvent):void {
       var value:String = event.dragSource.dataForFormat('value') as String;
       bigImage.source = "assets/big/"+value; 
}

14. Here’s the final code, run your application to see it in action.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
	horizontalAlign="center"
	backgroundGradientAlphas="[1.0, 1.0]" 
	backgroundGradientColors="[#FFFFFF, #FFFFFF]"  
	creationComplete="service.send()">
	
	<mx:Script>
		<![CDATA[
			import mx.core.DragSource;
			import mx.collections.ArrayCollection;
			import mx.rpc.events.ResultEvent;
			import mx.events.DragEvent;
            import mx.managers.DragManager;
			
			[Bindable]
			private var images:ArrayCollection;
			
			private function serviceHandler(event:ResultEvent):void{
				images = event.result.gallery.image;
			}
			
			private function initiateDrag(event:MouseEvent,value:String):void{
             	
             	var dragInitiator:Image= event.currentTarget as Image;   
             	
             	var dragSource:DragSource = new DragSource();
              	dragSource.addData(value, 'value');
             
              	var dragProxy:Image = new Image();
              	dragProxy.source = event.currentTarget.source;
             	dragProxy.width = 100 ;
              	dragProxy.height = 100 ;
              
              	DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
           	} 
            
			private function dragEnterHandler(event:DragEvent):void {
              var dropTarget:VBox =event.currentTarget as VBox;
          	  if (event.dragSource.hasFormat('value')) {
                DragManager.acceptDragDrop(dropTarget);
              }
            }
			                 
           	private function dragDropHandler(event:DragEvent):void {
              var value:String = event.dragSource.dataForFormat('value') as String;
              bigImage.source = "assets/big/"+value; 
            }
			
		]]>
	</mx:Script>
	
	<mx:HTTPService id="service" url="datas.xml" result="serviceHandler(event)"/>
	
	<mx:Label text="Drag a thumbnail image inside the black box and drop it to display its bigger version"/>

	<mx:HBox>
		<mx:Repeater dataProvider="{images}" id="rep">
			<mx:Image source="assets/thumbs/{rep.currentItem}"
				mouseMove="initiateDrag(event,event.currentTarget.getRepeaterItem())" />
		</mx:Repeater>
	</mx:HBox>
	
	<mx:VBox width="340" height="350" backgroundColor="#000000" 
	      horizontalAlign="center" verticalAlign="middle"
	      dragEnter="dragEnterHandler(event)"
	      dragDrop="dragDropHandler(event)">
			<mx:Image id="bigImage" showBusyCursor="true"/>
	</mx:VBox>
	
</mx:Application>

8 thoughts on “Build a Drag-and-Drop XML Image Viewer

  1. Offset26

    thank you
    nice like others
    so I have a question
    you know, the Flash Loader Component cant Load Video . and this component just use for Picture or MovieClip and SWF contents.
    also the FlvPlay component can import video files.
    so the question is do you know a flash component or class that can load files ( picture or video ) from xml file and show their ?
    like as Cooliris

    that check the file and if it Video show it with video Payer and if is picture show it with Loader

  2. Ravindran V

    This is very simple to use. When I try this as a project it works. But If I want to view in the different system I took all the files on bin-debug & assets folder. The Images are not coming up any reason for this.

  3. Ravindran V

    The Images are working internally. but when I publish to Web they are showing up. Any reason why is it os.
    How come it is displaying in your demo.

    Can you please help

  4. Sidney Bezerra

    I’m just arriving in FLEX world.

    And this example is just wath I need. But it has some trouble? I simply can’not see it working i’ve copied the source, and don’t work. then I wrote all the code as a new project in Flex Builder, and what happens is that the .swf file works once if I go to bin-debug and start it, but when running the project, or copying all the files in a server it don’t work.

    Could you help me ??

    Thanks
    Sidney Bezerra
    sidney.bezerra@gmail.com
    55+11 3624-2357
    São Paulo – Brasil

  5. Oz DiGennaro

    Very nice. Creating the thumbs and big images is a good exercise for user.
    To build with Flex 4 requires some changes: edit properties to remove the reference to “libs” in “Flex Build Path”.
    You’ll also have to let Flex Builder “recreate the HTML template”.
    After those minor fixes – it’s beautiful.
    Oz

Leave a Reply

Your email address will not be published. Required fields are marked *