Dynamic FlexBook powered by ColdFusion

Word Count: 259

The Flex 3 Pre-Release tour stopped here in Cleveland and it really revived my interest in Flex & ActionScript 3. With that I was able to come up with some ideas for projects at work. As these smaller projects come through I hope to share as much as I can. The project was to create an interactive Flash component for viewing our Clients Newspaper ads. I can not share the exact details of the project but I will use a substitute for the examples. If you want to spoil the fun and jump to the example there is a link at the end of this article.

I was looking around and came across the FlexBook Component that happens to be written by Ely a member of the Flex team. On a side after reading through his entries and digging through his code I have come up with the conclusion that he is a genius! After checking out all of the examples of the FlexBook I knew this is exactly what I needed. After downloading the code and checking out the source I could see that the component loaded the images from an XML file. This would work out well because the client needed to change the images every week. I figured I can just create a directory to hold these images, have the client upload the images to this directory and using ColdFusion I could scan the directory for all images.

Before we take a look at the solution we need to discuss one major problem. This is not really a problem with the component but the needs for our project were different from the examples. The example uses the following code to read in the XML file.

<XML id="dataSet" source="data/images.xml" />

If you have done any Flex work before then you will know that this is a compile time tag. This means that at the time of compilation it will read the xml file and store the images. This of course will not work for the project I am working as we need the images to be dynamic. This of course is no problem, let's take a look at the solution.

For our example we will build a similar component to the one I built but we will use Best Buy since everyone knows who they are. The first step is to fire up Flex Builder and create a new Flex Project. I am going to place this project in a folder named BestBuyAds right under my web root.



Next we need to create some folder for our project. The assets folder holds our loading image that was provided in the FlexBook download, our data folder will hold the ColdFusion template that will generate xml for our images and the images folder will contain all of the ad images.



Finally you will notice that I put all of the FlexBook code in the libs folder (qs.*). If we tried to use those classes right now nothing would work. We need to tell the Flex compiler where else to look for libraries. If you select Project > Properties > Flex Build Path you will see the screen below. Here we need to do a couple things. First we will add our lib folder to our source path. Now any additional external libraries that we add to this folder will be found as well. Next we need to set an output folder URL. If you have been debugging Flex applications you know that it will open the actual file location by default. We want to open the file up on our web server. Save your changes and the compiler will be updated.

We are all set to go, now we can start coding. First lets create the application. This is pretty basic stuff, create the application and give the external libraries a prefix. We also add a creationComplete method. This just says when the application is setup call this method.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   layout="vertical"
   xmlns:controls="qs.controls.*"
   backgroundColor="#000000"
   creationComplete="init();">


</mx:Application>

With that setup we can add our FlexBook component to the stage. As you can see we create this component as we would any other compnent except we are using the prefix we described above. The rest are just a bunch of properties for the component.

<controls:FlexBook id="book" width="614" height="453" horizontalCenter="0"
   animateCurrentPageIndex="true"
   showCornerTease="true"
   edgeAndCornerSize="150"
   itemRenderer="ImagePage"
   animatePagesOnTurn="true"
   />

In our case we are going to use the init method to call our ColdFusion template. Remember early I said that <mx:XML was a compile time tag, <mx:http:service is not. You could create it in Flex, I did it in ActionScript.

private function init():void {
dataSet = new HTTPService();
dataSet.url = ("data/images.cfm");
dataSet.resultFormat = "e4x";
dataSet.send();
dataSet.addEventListener(FaultEvent.FAULT, onFault);
dataSet.addEventListener(ResultEvent.RESULT, onResult);
}

Once the data is recieved it will call our onResult method. This is where I really struggled because of a lack of knowledge. In all of the examples for the FlexBook the data provider is set as a component attribute. This works great when the xml is available but in our case the component is created first then the data is retrieved. It is because of that that we have to wait until we have the data to set its content. The examples also show inline attributes for the TurnStart and End methods. Because we have no data to load when the component is created we will to add Listeners after the data is ready.

private function onResult(e:Event):void {
var thumbs:XMLList = dataSet.lastResult.image.@thumb;

// data binding is done here when the data set is ready book.content = dataSet.lastResult..image;
book.addEventListener(FlexBookEvent.TURN_START,loadContent);
book.addEventListener(FlexBookEvent.TURN_END,loadContent);
}

Finally we have our ColdFusion template. All this template does is read our images directory and create the xml that the FlexBook component is looking for. In my case I knew all of the images were always going to be JPEG and that they would be numbered in order of priority. As you know cfdirectory will return a query. The query name is treated as alpha numeric and therefore will not be sorted how we want it. This is a quick fix but I just turned the query into an array and used arraySort() to sort the images in ascending order.

<cfprocessingdirective suppressWhiteSpace = "yes">

   <cfdirectory action="list" directory="#expandPath('..')#/images" name="dirlist" filter="*.jpg"/>

   <cfset images = arrayNew(1)>
   <cfloop query="dirlist">   
      <cfset arrayAppend(images,left(dirlist.name,len(dirlist.name)-4))>
   </cfloop>

   <cfset arraySort(images,"numeric","asc")>
   
   <cfxml variable="xmlImages">
   <images>
      <cfloop from="1" to="#arrayLen(images)#" index="x">
      <cfoutput><image source="images/#x#.jpg" thumb="images/#x#.jpg"/></cfoutput>
      </cfloop>
   </images>
   </cfxml>
   
   <cfcontent reset="yes" type="text/xml; charset=UTF-8"><cfoutput>#xmlImages#</cfoutput>

</cfprocessingdirective>

This may seem like a lot if you have not done much Flex work but I can assure you it is not. I bet there is probably a better way to do this but it works for me, any suggestion / comments are welcomed. I am really enjoying AS3 and do not see myself putting these books down for along time :) A link to the exmple is below. If you right click on the screen you will be able to view the source. I probably should have kept the help text but you can click on any part of the page to move through the pages. Any questions please feel free to ask!

http://www.danvega.org/examples/bestbuyads/bestbuyads.html


Comments

#1 Posted By: anthonymds@hotmail.com Posted On: 5/6/08 2:30 PM
Thank you mate; you saved my day


Post Your Comment







Show Captcha

If you subscribe, any new posts to this thread will be sent to your email address.

Copyright © 2007 Dan Vega | BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.