This tutorial assumes that you have already installed the following:

The ColdFusion Flex 2 Adapter comes with installation instructions that must be followed very carefully. (Most initial problems are the result of the Adapter not be installed or configured correctly).
The Application
The application that you will be building is a simple data drill-down application which uses the sample data that is installed with ColdFusion MX 7.0.1. On startup, the application displays a drop down combo box containing a list of artists. Selecting any artist displays that artist’s art, and clicking on art items displays an image.
Setup
Create a folder for your new application under your web root. The default I am using in this tutorial has a folder named flex under the web root, and a folder for this application named ArtCatalog in the flex folder. (On a default installation on a Windows machine this will therefore be c:cfusionmx7wwwrootflexartcatalog).
The Backend
The backend for this application is a simple ColdFusion Component named art.cfc which contains two methods. GetArtists() returns the artist list, and GetArt() accepts an artistid and returns that artist’s art. The CFC itself is very simple:






SELECT RTrim(lastname) + ', ' + RTrim(firstname) AS artist,
artistid
FROM artists
ORDER BY lastname, firstname


SELECT artist AS label, artistid AS data
FROM artists
ORDER BY label









SELECT artid, artname, description, issold,
largeimage, mediaid, price
FROM art
WHERE artistid=
ORDER BY artname


SELECT artid, artname, description, issold,
'http://localhost:8500/cfide/gettingstarted/tutorial/images/' + largeimage AS image,
mediaid, price
FROM art
ORDER BY artname




Notice that both methods query for data, and then query that query. There are two reasons for this. One, there is a bug in the current adapter whereby database query column names may not be converted to lowercase properly, querying the query solves this problem. Two, some Flex controls (like ) have specific column name requirements, and the second query in GetArtists() renames the columns to the naming convention needed by that control.
It is generally a good idea to thoroughly test CFCs using simple ColdFusion calls before using them in your Flex apps. The following file named arttest.cfm can be used to test that art.cfc is functioning properly:





Defining The Service
Flex 2 applications access ColdFusion Components via Flash Remoting using a service name. This name must be defined in an XML file, mapping a destination name to a source (the path to the CFC).
When you installed the ColdFusion Adapter you copied a file named coldfusionsamples.xml into the WEB-INFflex folder. Open that file, and add the following destination definition. The source here specifies flexartcatalogart as the path to the CFC (the .cfc extension should not be included), if you are using a different path make the necessary changes to the source.



flex.artcatalog.art
true

Once you have made the change and saved the xml file, you will need to restart ColdFusion.
Creating The Project
Here are the steps needed to create the new Flex Builder project:

  1. Open Flex Builder 2.
  2. Select File, New, Flex Project.
  3. Specify ArtCatalog as the project name.
  4. Specify the project location (you can use the same folder as where you created art.cfc).
  5. The default Main Application File and Output Folder are ok, so click Finish to create the project.
  6. Right click on the new project in the Navigator panel, and select Properties to open the project Properties dialog.
  7. Select Flex Compiler.
  8. In the Additional compiler arguments field enter: -services=C:CFusionMX7wwwrootWEB-INFflexflex-services.xml (or modify the path to match your installation).
  9. Click OK.

Building The Application
Now you can start building the application. The first thing you need to do is tell Flex how to find your CFC. You do this using the tag, as follows:


Now, whenever you refer to artSvc Flex will be able to connect to art.cfc using the previously created mapping.
Next you’ll define the artist drop down combo box. Here is the code (make sure to place it between the tags, after the tag):





Save the code and run the application (click on the run button, the one with the white arrow in a green circle). The application should run, but the combo-box will not be populated . This is actually the correct behavior, you never called the CFC method, so there were no results to populate it with.
You want the GetArtists() method to be invoked automatically on application startup. To do that, create a ActionScript function named InitApp() as seen here:

Next, modify the tag. Go to the end of the tag and press space, you should see a popup of all available properties and methods. Select the property named creationComplete and specify InitApp() as the value. The opening tag should now look like:

Save the code and run it again. This time the combo box should be automatically populated because the dataProvider points to artSvc.GetArtists.result (the result returned by the call to GetArtists in the artSvc service).
Next you’ll create the data grid to display artist’s art. Here is the code, place it after the tag:










This code creates a grid containing four columns. (The grid columns could have been omitted, but then all columns would have been displayed, and you’d also have lost the ability to fine-tune the appearance of specific columns as you will see shortly). The grid’s dataProvider points to the result of artSvc.GetArt().
Which means that method must be invoked. Modify the and add the following property and value:
change="{artSvc.GetArt(artistsCB.selectedItem.data)}"
This way, any time the combo box changed, GetArt() will be called. GetArt() requires that an argument be passed to it, the id of the artist who’s art you wish to obtain. This argument is passed to GetArt() as artistsCB.selectedItem.data (the data value for the currently selected item in artistsCB).
Now save and run the application. You should be able to select any artist to populate the data grid with his or her art.
Now add the following code so as to display an image of the art when an art item is selected in the grid. Place it after the tag and before the closing tag:

This code creates a panel, setting the title to the artname currently slected in the data grid, and populate the source on an tag with the image URL as returned by GetArt().
Using Cell Renderers
The default display in the data grid is fine for simple text data, but there are two columns that don’t look right here. The Sold column is displaying true or false, which is not very intuitive. And the Price column is not formatting the values as currency values. Both of these problems can easily be addressed using cell renderers. Basically, a cell renderer is code that Flex should use to render cells instead of any default rendering.
The Sold column could use a checkbox to display a check if sold and not if not. To do this, simply add the following property to the appropriate tag:
cellRenderer="mx.controls.CheckBox"
If you run the application now you’ll see that a checkbox is displayed, and will automatically be checked if true and not if false.
To format the Price column you will use a custom cell renderer, a new component. To create a new component do the following:

  1. Right click on the ArtCatalog project in the Navigator panel.
  2. Select New, MXML Component.
  3. Specify ArtPrice as the File name, and select VBox as the Base component.
  4. Click Finish.

Flex Builder will create a new component (based on ) for you to use. When a component is called as a cell renderer, an object named dataObject is passed to it containing the row to be rendered.
Add the following code in between the tags:


creates a formatter that knows how to format values as currency values. The

39 thoughts

  1. Hey Ben, your code for arttest.cfm doesn’t work because it uses the incorrect column name in your result. Instead of artistid it should be data.

  2. Ugh, good catch, Ray. I uploaded the version I used to test before I put the QofQ in there. Thanks. Post and ZIP file have been updated.

  3. The data grid, the price line, as an extra quote at the end. Pretty easy to fix – but just so you know.

  4. Philippe, yep, but no dataField (that I know of), so renaming is still needed.
    Ray, I’ll fix that one, thanks.

  5. also, ben, there is a missing "s" in the getArt function.
    <cfset var art="">
    <cfset var result="">
    should be
    <cfset var art="">
    <cfset var results="">
    right?
    tony

  6. Is this the same app that was taught in the MAX 2005 session "Building Your First Rich Forms Application with Flex and ColdFusion (RA101H)"? It seems similar….
    Man, I LOVE Flex and how good it’s going to make my projects look! We (at my company) are planning to completely redo our corporate website based around a new Flex interface… we already use ColdFusion, so intergration’ll be a snap!

  7. Dave, um, I did not see that one, and wrote this one for a demo I needed over the weekend. So, if it is similar, that’s a freaky coincidence. šŸ˜‰

  8. Great Tutorial Ben.
    I didn’t download the files you provided.
    Instead I followed along, and everything ran smoothly, without any modifications or changes needed.
    Thanks for helping me get started in Flex.
    And please keep the tutorials coming, I look forward to the intermediate level.
    Ali

  9. This would have come in very handy for Art Intersect Science. If we ever get funding to upgrade our ColdFusion server we’ll most likely build our own gallery and auction software next time.

  10. Working beautifully here!
    Two minor details worth mentioning:
    1) the flex compiler argument syntax has one leading dash in this blog entry, but on the labs.macromedia.com CF Adaptor page it has two leading dashes. Not sure if this is important.
    2) The flex.artcatalog.art GetArt method refers to a hard-coded url, so folks might want to adjust to fit their system to get the images to display. In my case I have CFMX 6.1 and 7 on the same machine, so CF7 listens on 8501 rather than 8500.
    Thanks!

  11. I seem to be having a problem with the <mx:Image> tag. The example is working fin except for displaying images (i have altered the url to fit my setup). It just shows a fuzzy broken image icon, and does so for any tests I have done to get the image tag to work.
    Any idea where to look to check my setup?

  12. Doug, try running arttest.cfm and click on an artist name to see the artist data which includes the URL for images. They copy a few of the URLs into the browser to see if they resolve correctly there. The art cfc is returning this data to flex, so if the image url isn’t working in a browser then it won’t work from flex either. See my comment earlier because this was the problem I was having.

  13. Steve, I meant to note that. Actually, I meant to define a variable to make that easily changeable. Thanks for pointing it out.

  14. Hi Ben,
    I have tried the arttest.cfm and pasted the URL’s which all work fine, it seems as though the image tag in flex is broke on my machine šŸ™ as I am having similar problems with even the simplist flex page.

  15. What do I have to do to run this app in a standard Windows/IIS configuration (inetpub/wwwroot)? My web root is not in the CF7 folder and no matter what I try I cannot get the connection to the CFC to work.

  16. Doug, have you tried other records? Not all have images.
    Steve, All that should need to change is the location of the files and the URL for images. Is the test .cfm file executing the CFC properly? What path are all the files in? And what did you specify in the XML file?

  17. Ben,
    I hope this is understandable.
    The error I receive is "Couldn’t establish connection to ‘ArtCatalog’".
    test.cfm work perfectly
    the file path on my webserver is C:inetpubwwwrootflexprojectsartcatalog
    The coldfusionsamples.xml file (still located in the CF7 WEB-INF folder):
    <properties>
    <source>flexprojects.artcatalog.art</source>
    <lowercase-keys>true</lowercase-keys>
    </properties>
    One thing I have noticed is that when you set "-services=C:CFusionMX7wwwrootWEB-INFflexflex-services.xml" in the the Flex Builder it is relative to your workspace and not the actual deployed file. Since I am using a network drive (P) for my web server I set this to read "-service=P:CFusionMX7wwwrootWEB-INFflexflex-services.xml". Which removed the error from my workspace, but neither resolved my issue.

  18. Hi Ben,
    This tutorial was just what I needed, thanks !
    I’ve got a problem though. The data is not populated when I run the application. If I click on the column labels I get the message below. I’m new to Flex and also a beginner of ColdFusion so I don’t really understand what this error message says.
    TypeError: Error #1006: Call attempted on an object that is not a function.
    at mx.collections::Sort/Sort$257$private::internalCompare()
    at mx.collections::Sort/findItem()
    at mx.collections::ListCollectionView/getItemIndex()
    at mx.collections::ListCollectionViewCursor/ListCollectionViewCursor$1502$private::collectionEventHandler()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.collections::ListCollectionView/dispatchEvent()
    at mx.collections::ListCollectionView/refresh()
    at mx.collections::ListCollectionView/set sort()
    at mx.controls.listclasses::ListBase/sortItemsBy()
    at mx.controls::DataGrid/sortByColumn()
    at mx.controls::DataGrid/mouseUpHandler()

  19. Steve,
    I have the same setup, my flex-services.xml file is on another server, not my local machine.
    This is what I do, and it works for me:
    firstly I use 2 "-"’s in front of services, then I use a UNC path, NOT the network drive number.
    "–services=\<network computer id>c$CFusionMX7wwwrootWEB-INFflexflex-services.xml"

  20. Seem to have resolved the problem, seemed like the flash plugin for firefox was doing something odd. Uninstalled the plugin and reinstalled it and hey presto.
    Any idea when the connector column name bug will be fixed, bit of a pain having to always do a query of queries.

  21. I can’t test it here but I think you can try using aliases in your query to keep the proper case.
    Ex : SELECT firstname AS firstname, lastname AS lastname from tblUsers …
    I m also not sure all databases support aliasing with the same name as the column

  22. I’ve followed all the instructions, but Eclipse is showing me this error:
    java.lang.RuntimeException: org/apache/xpath/CachedXPathAPI
    on resource: ArtCatalog
    location: Line -1
    And when I run the example the page opens, the Flash progress bar shows up, but then nothing happens or renders. Any idea what this could be?

  23. Brian, Ben,
    I ran into the same runtime exception (running CF multi server/Apache). In addition, firing up regular CF apps with mapped cfc’s throws returntype errors. Raymond Camden has blogged about the returntype issue and apparently a fix is in the pipe. Not sure about the CachedXPathAPI error though.

  24. I had something similar when i first tried, it turned out to be the JVM. You need to be running 1.4 for eclipse to compile flex stuff (I had 1.5 and it broke with that sort of error) also make sure the compiler option is set correctly for the flex project pointing to the flex-services.xml file.

  25. Having trouble getting data.
    The arttest.cfm is working.
    The page ArtCatalog.html comes up but with no data and the clock icon pointer just spinning away. Down in the status bar it says "Connecting to 10.3…." the server.
    I must not have the CF Adapter set up right. Any way to test.
    Thanks in advance.

  26. I’ve started CF from the command line.
    What looks like a relevant error while sartup of the service is:
    —————
    java.lang.ClassNotFoundException
    at coldfusion.bootstrap.BootstrapClassLoader.loadClass(BootstrapClassLoa
    der.java:229)
    AND
    1/15 07:59:25 user failed to load: flex.messaging.MessageBrokerServlet
    11/15 07:59:25 error Could not pre-load servlet: MessageBrokerServlet
    [1]java.lang.ClassNotFoundException
    at coldfusion.bootstrap.BootstrapClassLoader.loadClass(BootstrapClassLoa
    der.java:229)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at coldfusion.bootstrap.ClassloaderHelper.initServletClass(ClassloaderHe
    lper.java:95)
    —————-
    How do I fix this?
    Am I missing a CF update
    This is the Sys Info out of CF Admin
    System Information
    Server Details
    Server Product ColdFusion MX
    Version 7,0,1,116466
    Edition Enterprise (DevNet)
    Serial Number
    Operating System Windows 2003
    OS Version 5.2
    Update Level /C:/CFusionMX7/lib/updates/hf701-61119.jar

  27. Good tutorial for introducing integration between CF and Flex. I made some mods after successfully walking through and I ran into an issue of retrieving data from my CFC when it’s coming from SQL as apposed to the tutorial Access mdb. The CFC works fine if being accessed by a cfm file and running the Flex file doesn’t generate an error, but no data is returned. The debug says:
    ——————————————
    "Violation*** localhost:8500/flex2gateway/ halted – not permitted from file (file path)"
    ——————————————
    Is there a reason the flex file wouldn’t be able to retrieve data from a cfc referencing a SQL Server Datasource?

  28. J, the data file is one of the example files installed with ColdFusion (if you install the examples).
    Jeff, no, the type of data source makes no differance.

  29. I confirmed that the cfartgallery datasource is set up and contains data, which means there’s problem somewhere. I don’t get an error, but the drop-down list is blank. I downloaded the zip file and have made no modifications, other to add a new project and set the Flex Compiler properties.
    The arttest.cfm returns the artists names and clicking the artists name brings up the query with appropriate results.

  30. I think I’ve found a solution to the "Cannot Connect Problem".
    When I first downloaded the zip file and tried out the example, I had the same "Cannot Connect" problem.
    The problem seems to be the placement of the <mx:RemoteObject> tag. This tag needs to be at the bottom of the main mxml file. Once I put it down at the bottom, it works.
    Note: for some reason, after moving it to the bottom, I was able to connect. After that, I could move the <mx:RemoteObject> tag anywhere else on the page and it will still connect.
    I tried another experiment where I deleted the entire project and started with a fresh copy. Starting with a fresh copy, the problem came back.
    Another note: Please make sure that your Flex compiler setting is accurate, in my case it’s: –services=C:CFusionMX7wwwrootWEB-INFflexflex-services.xml
    Good luck and see if this works for you.
    Cheers Ben for the Example.

  31. Hoping someone will still read this!
    I’m very very new to Flash and we are using ColdFusion but are not using Flex Data Services. I’ve been trying to figure out how to populate a combobox from a database and I’m just not having any luck.
    My project is called "PreTraffic". I have my main file as "JobSearch.mxml" and a folder under the root named "cfc" with a file called "job.cfc".
    job.cfc contains the following code:
    <cfcomponent>
    <!— Get jobs —>
    <cffunction name="GetJob" access="remote" returntype="query" output="false">
    <cfset var job="">
    <cfset var results="">
    <cfquery datasource="discsdev" name="job">
    SELECT job_id, job_title
    FROM job
    WHERE status = ‘O’
    ORDER BY job_title
    </cfquery>
    <cfquery dbtype="query" name="results">
    SELECT job_title AS label, job_id AS data
    FROM job
    ORDER BY label
    </cfquery>
    <cfreturn results>
    </cffunction>
    </cfcomponent>
    And JobSearch.mxml has the following code:
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml&quot;
    xmlns="*"
    layout="absolute"
    backgroundGradientColors="[#ffffff, #d0d0d0]"
    creationComplete="InitApp()">
    <mx:Style source="style.css" />
    <mx:Script>
    <![CDATA[
    public function InitApp():void {
    jobSvc.GetJob();
    }
    ]]>
    </mx:Script>
    <!– ColdFusion CFC (via AMF) –>
    <mx:RemoteObject id="jobSvc" destination="PreTraffic" showBusyCursor="true" />
    <mx:VBox label="Job History" width="100%" height="100%" x="10" y="92">
    <mx:Label text="Search jobs by"/>
    <mx:Form label="Task" width="100%">
    <mx:FormItem label="Job Name:">
    <mx:ComboBox id="jobNameCB" dataProvider="{jobSvc.GetJob.results}"></mx:ComboBox>
    </mx:FormItem>
    </mx:Form>
    <mx:HBox>
    <mx:Button label="Search"/>
    <mx:Button label="Clear"/>
    </mx:HBox>
    </mx:VBox>
    </mx:Application>
    My Compiler thingy points to:
    -services "/Volumes/flexwwwroot/WEB-INF/flex/job-services-config.xml" -locale en_US
    and job-services-config.xml contains the following code:
    <destination id="PreTraffic">
    <channels>
    <channel ref="my-cfamf"/>
    </channels>
    <properties>
    <source>flex.pretraffic.cfc.job</source>
    <lowercase-keys>true</lowercase-keys>
    </properties>
    </destination>
    Well, when I run the app… the combobox is not populated… Can anyone help with what I’ve done wrong?
    Thanks!
    April

  32. April, did you ever find a solution?
    Im having a similar problem, whats happening for me is that if I try to specify the dataprovider for my mx:ComboBox as "mySvc.getArtists.result", i receive a runtime error telling me that ‘property result not found…’
    Ive noticed that Datagrids populate nicely when returning multiple colimns from a query, but mx:Combo Box and mx:List dont work for me.
    Im sure it has something to do with ArrayCollection being returned as opposed to Array, but not sure how to get results to display in these 2 types of elements

Leave a Reply to Shigeru Cancel reply