Step 6: Dynamic Functionality
The basics work, so now I want to tie it to a database to make it dynamic, pulling data from the database and sending new links to the database. While there are many possible ways to do this in Flex, I know how to do this easily with Access databases and ColdFusion components as Web Services so that's how I went. I created my Access database and a CFC to use as a Web Service then called the service in Flex. I'm still rusty with ColdFusion, so my examples here, while functional, may not be the best.
| LinkID (Autonumber) | Category (Text) | Description (Text) | URL (Text) |
|---|---|---|---|
| 0 | Kids | Disney Kids | http://www.disneykids.com |
| 1 | Programming | Planet Source Code | http://www.planet-source-code.com |
<cfcomponent>
<cffunction name="getLinks" returntype="query" access="remote" output="false">
<cfquery name="qryLinks" datasource="links">
SELECT *
FROM tblLinks
ORDER BY Category;
</cfquery>
<cfreturn qryLinks />
</cffunction>
</cfcomponent>
When we process the Web Service, we receive back a Query as the result, not an
XML tree. Unlike an
mx:DataGrid, we can't simply bind the query to the mx:Tree and
have it work, we have to process the data.Thanks to Ben Forta's great Flex/CFC
Dashboard2 example and Dimitrios Gianninas' information on
looping through a query, I created a query2tree function to process the
query.
// Turn a CF query into Flex tree XML
function query2tree(src) {
// Define tree object
var tree:XML = new XML();
var curCategory:String="";
for( var i = 0; i < src.length; i++ ) {
if (src[i].CATEGORY != curCategory) {
// if not first category, append last node
if (i != 0) tree.appendChild(node);
// New category
var node:XMLNode=tree.createElement('node');
curCategory=src[i].CATEGORY;
node.attributes['label']=src[i].CATEGORY;
}
// add leaves
var leaf:XMLNode=tree.createElement('node');
leaf.attributes['label']=src[i].DESCRIPTION;
leaf.attributes['nodeURL']=src[i].URL;
node.appendChild(leaf);
}
tree.appendChild(node); // append last node
// Return complete XML tree
return tree;
}
Then at last we add the Script and Web Service to our Flex file, call the web service on initialization of our Tree, then bind our processed result to the Tree's data provider.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:WebService id="svcLinks" wsdl="http://localhost:8500/linkdata.cfc?wsdl" fault="alert('Error: ' + event.fault.faultstring,'Error')" showBusyCursor="true">
<mx:operation name="getLinks" />
</mx:WebService>
<mx:Binding source="query2tree(svcLinks.getLinks.result)" destination="treLinks.dataProvider"/>
<mx:Script source="query2tree.as"/>
<mx:Script source="linkfunc.as"/>
<mx:Panel height="100%" title="My Links" fontSize="18">
<mx:Tree initialize="svcLinks.getLinks.send()" id="treLinks" change="loadPage(event);" fontSize="10" defaultLeafIcon="@Embed('leaf.png')">
</mx:Tree>
<mx:ControlBar>
<mx:VBox horizontalAlign="right" fontSize="10">
<mx:FormItem label="URL">
<mx:TextInput width="250" id="txtURL"/>
</mx:FormItem>
<mx:FormItem label="Description" required="false">
<mx:TextInput width="250" id="txtDescription"/>
</mx:FormItem>
<mx:FormItem label="Category">
<mx:ComboBox width="200" id="cboCategory"/>
</mx:FormItem>
<mx:Button label="Add Link"/>
</mx:VBox>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
References:

