I'm not saying Flex is easy, it's simple. I started going through the lessons that ship with Flex Builder 2 and as I finished each one my reaction was consistently, "is that all?"

Lesson: Retrieve and Display Data

The first lesson is basically a "Hello World" app, so I'll discuss the second lesson where you build a Blog Reader. Here's a screen shot of the final output:

Flex Blog Reader

The lesson teaches you how to retrieve an RSS feed and populate a DataGrid with its contents. When you select an item in the grid, the description for that entry will populate the TextArea. Finally, clicking the Button labeled "Read Full Post" will take you to the blog post you selected.

Old School: HTML and Javascript

Before we get into the Flex code, let's take a look at what it would take to create an HTML version of this interface.

Get the feed

I'm going to use CFHTTP instead of CFFEED so this example will work with CFMX 6, 7 and 8.

view plain print about
1<cfhttp url="http://www.iknowkungfoo.com/blog/rss.cfm?mode=full" result="rssFeed" />

Parse the XML

If you dump the contents of rssFeed, you'll see the XML for the RSS feed as a string value. We need to parse the file's content into an XML packet so we can manipulate the data.

view plain print about
1<cfset feedRequest = xmlParse(rssFeed.fileContent) />

Output data

Title

Now we can output the blog's name:

view plain print about
1<cfoutput><h2>#feedRequest.rss.channel.title.xmlText#</h2></cfoutput>

Grid

The next big step is to generate a table (grid) containing the titles and dates of the blog posts returned by the RSS feed.

view plain print about
1<table border="1">
2    <tr>
3        <th>Posts</th><th>Date</th>
4    </tr>
5    <cfoutput>

Each row of the table is created by looping over the array of item entries in the RSS feed.

view plain print about
1<cfloop index="x" from="1" to="#arraylen(feedRequest.rss.channel.item)#" step="1">
2            <tr>

We'll call a Javascript function named showDesc() to display the description of each item in the textarea. ( *** Remember that Javascript arrays start at 0 and ColdFusion arrays start at 1. )

view plain print about
1<td><a href="javascript:void(0);" onclick="showDesc(#x-1#)">#feedRequest.rss.channel.item[x].title.xmlText#</a></td>
2                <td>#feedRequest.rss.channel.item[x].pubDate.xmlText#</td>
3            </tr>
4        </cfloop>
5    </cfoutput>
6</table>

Textarea

Here's the textarea that will display the description of each entry.

view plain print about
1<textarea id="blogDesc" name="blogDesc" rows="10" cols="30"></textarea>

Button

And finally, the button that will take us to the selected item's URL.

view plain print about
1<input type="button" id="gotoURL" name="gotoURL" value="Go to Selected URL" onclick="navigateToURL()"/>

The dynamic bits

So the point of Flex is that we can display data dynamically after its been pulled from the server or we can go to the server to get more data as needed.

With the HTML version, we could click a link to make an Ajax call to the server to retrieve the selected item's description and URL. However, the Flex version doesn't do that. It stores the RSS feed internally and displays its contents as needed.

In order to keep the description and links for the blog posts on the client side (in the browser), we'll create a couple of Javascript arrays to hold each set of data. We also need to know which item has been selected, so we'll create a Javascript variable for that too.

view plain print about
1<script type="text/javascript">
2var selectedItem = 0;
3
4var itemDesc = new Array();
5var itemURL = new Array();

We need to populate the itemDesc and itemURL arrays with data from the RSS feed, so we'll use ColdFusion to generate the Javascript data. We'll also make sure to avoid any "unterminated string literal" errors by escaping any apostrophes and other characters using jsStringFormat.

view plain print about
1<cfoutput>
2<cfloop index="x" from="1" to="#arraylen(feedRequest.rss.channel.item)#" step="1">
3    itemDesc[itemDesc.length] = "#jsstringformat(trim(feedRequest.rss.channel.item[x].description.xmlText))#";
4    itemURL[itemURL.length] = "#trim(feedRequest.rss.channel.item[x].link.xmlText)#";
5</cfloop>
6</cfoutput>

And now we just need the two functions that will populate textarea with a selected item's description and send the user to the correct URL when they click the button.

view plain print about
1function showDesc(x)
2{
3    document.getElementById("blogDesc").value = itemDesc[x];
4    selectedItem = x;
5}
6
7function navigateToURL()
8{
9    window.location.href = itemURL[selectedItem];
10}
11</script>

The result

All said and done, will the code nicely formatted and whatnot, there's just over 40 lines of CFML, HTML and Javascript needed to create the functionality outlined in this Flex lesson.

You can see the final product here.

The Flex code

The basic layout and control elements can be placed using the Design mode of Flex Builder, but I'll just show you the MXML code here.

Get the feed

The following code will retrieve the RSS feed from my site. In mx:Application, the attribute creationComplete="feedRequest.send()" tells the Flash player to call the function send() on whatever element is identified as feedRequest. In this case, feedRequest is an HTTPService.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="feedRequest.send()">
3
4    <mx:HTTPService id="feedRequest" url="http://iknowkungfoo.com/blog/rss.cfm?mode=full" useProxy="false" showBusyCursor="true" />

I guess you could liken this to

view plain print about
1<body onLoad="getFeedRequest()">

on a basic HTML page.

Parse the XML

Uhm . . . yeah. Nothing to do here. Flex kinda takes care of that for you.

Output data

Title

First we output the blog's name:

view plain print about
1<mx:Panel x="10" y="10" width="475" height="400" layout="absolute" title="{feedRequest.lastResult.rss.channel.title}">

Here we've created a Panel to contain all the controls for this application. You can see that the panel's title uses a similar syntax as the HTML version. Rather than ColdFusion's pound symbols ( # ), Flex uses curly brackets to denote a dynamic value.

CFML

view plain print about
1#feedRequest.rss.channel.title.xmlText#

MXML

view plain print about
1{feedRequest.lastResult.rss.channel.title}

Grid

Now we need to populate the DataGrid with the items returned with the RSS feed. Using the dataProvider attribute, we tell the DataGrid where it's getting its data. Note that we've given it an id of dgPosts.

view plain print about
1<mx:DataGrid x="20" y="20" id="dgPosts" width="400" dataProvider="{feedRequest.lastResult.rss.channel.item}">

Here we're telling each column where to get its data from the item XML. The first column is bound to item.title, the second to item.pubDate.

view plain print about
1<mx:columns>
2        <mx:DataGridColumn headerText="Posts" dataField="title"/>
3        <mx:DataGridColumn headerText="Date" dataField="pubDate" width="150"/>
4    </mx:columns>
5</mx:DataGrid>

The DataGrid will create a row for each item in the array returned by {feedRequest.lastResult.rss.channel.item}.

Textarea

The Flex TextArea is bound to the whichever row is selected in the DataGrid.

view plain print about
1<mx:TextArea x="20" y="175" width="400" height="100" htmlText="{dgPosts.selectedItem.description}" />

When a user selects a row in the DataGrid, Flex now knows to populate the TextArea with the description associated with that item's array element.

Button

Finally, the LinkButton is a type of button that links to something.

view plain print about
1<mx:LinkButton x="20" y="280" label="Read Full Post" click="navigateToURL(new URLRequest(dgPosts.selectedItem.link));"/>

Just as the TextArea was bound to the selected row in the DataGrid "dgPosts", so is the LinkButton. When this button is clicked, it will run the Flex function navigateToURL(), open a new window and send the user to the link associated with that item's array element.

Closing the Flex app

Just to be AR:

view plain print about
1</mx:Panel>
2    
3</mx:Application>

The result

The final formatted MXML file contains 14 lines of code.

If you have Flash Player 9, you can see the final product here.

The SWF works locally and it worked when I first uploaded the file. I checked the morning after Ray posted his comment and it was working again. Does anyone have an idea why it might not load sometimes?

So what have we learned?

CFML lines of code > MXML lines of code

We can create the same functionality with CF, HTML and JS as we can with Flex.

Using our "old school" technology, a beginner has to learn three languages just to do something this basic. Using Flex, a beginner can get started with just the one.

The HTML + JS version certainly loads faster than the Flex version.

However, there are potential problems with layout (HTML, CSS) and functionality (JS, CSS) based on a user's browser or Operating System. With Flex/Flash, as long as the browser can load Flash Player 9, those issues don't exist.

If you haven't played around with Flex yet, do yourself a favor and download the 30 day trial. While it isn't going to be the solution for every problem, it's certainly a way cool and groovy solution for some.

This won't be my last Flex post, I can promise you that.