In this article I’ll show the same application I presented at FlexCamp Bucharest Romania 2008 - the video from the conference is available here and although it is in Romanian it might be useful. In the presentation I’m showing the power of Flex: doing complex applications with a few lines of codding.
With this article we are just starting because everything is explained in the powerpoint presentation and by the comments inside the source code found at the end of this article.
The application is simple - only one mxml file - and we will study:
- Multiple Drag and drop (events)
- HTTPService
- FileReference
- URLRequest
On the server-side:
- dir.php - browsing (http service) – no parameters needed – returns a simple XML
- download.php - download (url request) – array with the paths that will be included in archive as parameters – returns an archive (tgz)
- archive.php - class to create arhives
On the client-side:
- Tree ⇒ HTTPService ⇒ dir.php ⇒ HTTPService ⇒ Tree
- Refresh ⇒ HTTPService ⇒ dir.php ⇒ HTTPService ⇒ Tree
- Download ⇒ List ⇒ URLRequest ⇒ FileReference ⇒ file download
We are using multiple selection and dragging so you can drag more that one item from the list. Also the delete key erases the selected items from the list on the right. You can start over by pressing refresh button.
This is the start of it and you can get into it more and more reading the powerpoints and trying the source codes. All this can be downloaded from the end of this article.
Working example is bellow:
What can be added in the future:
- download progress with cancellation possibility
- upload functionality
- user account functionality
The last two points are more difficult because it involves some work on the server-side but is doable.
I’ve posted also the whole flex source code because it is easier to follow the article and study the code in the same page.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="439" creationComplete="init()" height="271"> <mx:HTTPService id="dir" url="{SERVER_URL}dir.php" resultFormat="e4x" /> <mx:Tree id="leftTree" x="10" y="10" height="250" width="204" dataProvider="{dir.lastResult}" labelField="@name" showRoot="false" dragEnabled="true" dropEnabled="false" allowMultipleSelection="true" click="showThumb(event)"/> <mx:List id="downloadList" x="222" y="10" height="135" width="207" allowMultipleSelection="true" dataProvider="{fileListProvider}" dragEnter="handleDragEnter(event)" dragOver="handleDragOver(event)" dragDrop="handleDragDrop(event)" dragExit="handleDragExit(event)" click="showThumb(event)" keyUp="handleKeyUp(event)"/> <mx:Button id="downloadButton" x="347" y="153" label="Download" enabled="false" click="initializeDownload(event)" /> <mx:Button id="refreshButton" x="347" y="239" label="Refresh" click="refresh(event)" width="82"/> <mx:Canvas id="imageHolder" x="222" y="153" width="117" height="108"> <mx:Image id="imageThumb" x="0" y="0" width="117" height="108" source="{currentPhotoPath}"/> </mx:Canvas> <mx:Script> <![CDATA[ import mx.messaging.channels.StreamingAMFChannel; /* File downloading application Drag and drop between two different controlers: tree and list */ import mx.rpc.events.ResultEvent; import mx.collections.ArrayCollection; import mx.controls.listClasses.ListBase; import mx.core.UIComponent; import mx.managers.DragManager; import mx.core.DragSource; import mx.controls.List; import mx.events.DragEvent; // internet - on flexer public const SERVER_URL:String = "http://www.flexer.info/wp-content/uploads/2008/05/"; // bindable variable used for the list [Bindable] public var fileListProvider:ArrayCollection = new ArrayCollection(); // bindable variable used for thumbnail [Bindable] public var currentPhotoPath:String = ""; public var fRef:FileReference = new FileReference(); public function init():void { /* initialization function */ // file reference events - used for debug purposes fRef.addEventListener(Event.CANCEL, doEvent); fRef.addEventListener(Event.COMPLETE, doEvent); fRef.addEventListener(Event.OPEN, doEvent); fRef.addEventListener(Event.SELECT, doEvent); fRef.addEventListener(HTTPStatusEvent.HTTP_STATUS, doEvent); fRef.addEventListener(IOErrorEvent.IO_ERROR, doEvent); fRef.addEventListener(ProgressEvent.PROGRESS, doEvent); fRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doEvent); // getting folder content dir.send(); }
private function handleDragEnter(event:DragEvent):void { /* this function validates the drop */ if (event.dragInitiator is Tree) { var ds:DragSource = event.dragSource; // check if the format is what we need - treeItems if (!ds.hasFormat("treeItems")) return; var items:Array = ds.dataForFormat("treeItems") as Array; for (var i:Number=0; i < items.length; i++) { var item:XML = XML(items[i]); // we want only files to be dragable if (item.@type != "file") return; } // check for the item to be unique var paths:ArrayCollection = downloadList.dataProvider as ArrayCollection; for (var j:Number=0; j < paths.length; j++) { if (item.@path == paths[j].path.toString()) return; } } // accept the drop DragManager.acceptDragDrop(UIComponent(event.currentTarget)); }
private function handleDragOver(event:DragEvent):void { /* this function shows feedback to the user */ // show feedback icon DragManager.showFeedback(DragManager.COPY); } private function handleDragDrop(event:DragEvent):void { /* this function adds new items to the list */ // getting source var ds:DragSource = event.dragSource; // getting target var dropTarget:List = List(event.currentTarget); // tempoaray array used to add items to list var arr:Array; // getting the nodes dragged // multiple selection is allowed so we have arrays if (ds.hasFormat("items")) { arr = ds.dataForFormat("items") as Array; } else if (ds.hasFormat("treeItems")) { arr = ds.dataForFormat("treeItems") as Array; } // adding the dragged nodes to list for (var i:Number=0; i < arr.length; i++) { // getting node var node:XML = XML(arr[i]); // creating new list item var item:Object = new Object(); // setting item's properties item.label = node.@name; // we set path also which is needed for download item.path = node.@path; // add to data provider fileListProvider.addItem(item); } // finish drag handleDragExit(event); } private function handleDragExit(event:DragEvent):void { /* this function finishes the drag and drop */ // we hide the feedback var dropTarget:ListBase=ListBase(event.currentTarget); dropTarget.hideDropFeedback(event); // we check the data provider to enable the download button if (dropTarget.dataProvider.length > 0) downloadButton.enabled = true; } private function showThumb(event:MouseEvent):void { /* this function shows the thumbnail used for both tree and list click events */ // if click is on the tree if (event.currentTarget.name == "leftTree") { // folders cannot show thumbnail // other file types than images are automatically not shown if (leftTree.selectedItem.@type == "file") currentPhotoPath = SERVER_URL + leftTree.selectedItem.@path; else currentPhotoPath = ""; // if click is on the list } else if (event.currentTarget.name == "downloadList") { currentPhotoPath = (downloadList.selectedItem ? SERVER_URL + downloadList.selectedItem.path : ""); } } private function handleKeyUp(event:KeyboardEvent):void { /* this function is used for deleting items from the list */ // if we have pressed the DELETE key and // also there is at least one item selected if (event.keyCode == Keyboard.DELETE && downloadList.selectedIndex > -1) { var removeItems:Array = downloadList.selectedIndices; // remove selected items for (var i:Number = 0; i < removeItems.length; i++) { downloadList.dataProvider.removeItemAt(removeItems[i]); } currentPhotoPath = ""; // if the list is empty we disable the download button if (downloadList.dataProvider.length <= 0) downloadButton.enabled = false; } } private function initializeDownload(event:MouseEvent):void { /* this function starts the download we use FileReference to download */ // get the items dragged in the list var paths:ArrayCollection = downloadList.dataProvider as ArrayCollection; // initialize the query/url string var qStr:String = ""; // compose the query/url string // we are sending an array to the server for (var i:int = 0; i < paths.length; i++) qStr += "&name[]="+escape(paths[i].path.toString()); // get the file // the file download.php on the server gets the array // and in the memory creates an tgz archive // and sends it back as being a file (using http headers) // we are using FileReference for this fRef.download(new URLRequest(SERVER_URL + "download.php?" + qStr),"archive.tgz"); } private function doEvent(evt:Event):void { /* Function is displaying events reached when downloading For debug purposes */ var fr:FileReference = evt.currentTarget as FileReference; // for debug purposes */ //trace("type:"+evt.type+", eventString:"+evt.toString()); //trace(fr.creationDate); //trace(fr.creator); //trace(fr.modificationDate); //trace(fr.name); //trace(fr.size); //trace(fr.type); } private function refresh(evt:Event):void { /* Function is refresing both the tree and the list and disables the download button */ // empty the list downloadList.dataProvider = new ArrayCollection(); // disable the download button downloadButton.enabled = false; // refresh the tree dir.send(); } ]]> </mx:Script> </mx:Application>
This is it! As I just wrote at the beginning of the article, the power and beauty of Flex framework is that you can do great things with a few lines of codding. So enjoy Flex!
Popularity: 100%
| ||
| ||
| ||
|
Tags: application, download, drag, drop, FileReference, HTTPService, URLRequest
This post was written by Andrei Ionescu
Views: 2705



















[…] the power of Flex: doing complex applications with a few lines of codding. Read full tutorial and download support files - Possibly related posts: (automatically generated) Tutorial - Desktop RSS with Adobe AIR, Creating HTML AIR Applications […]