Accessibility

ColdFusion Article

 

Creating a Flex 2 interface for the BlogCFC application


Raymond Camden

Raymond Camden

www.coldfusionjedi.com

Created:
18 September 2006
User Level:
Intermediate

Note: This article was created based on Flex 2. Minor changes in the description and code may be necessary before it can be applied to Flex 3.

A few months back I decided to work on an Adobe Flex 2 interface for my blog software, BlogCFC. Not that I thought it made sense to have an entirely Flash front end for a blog, but I thought it would be a good exercise to help me learn Flex 2. I had a lot of help along the way, and ran into issues on both the front and back ends, but I'm hoping to share some of this with other developers out there so they can learn from my experiences.

After checking out the Flex implementation of BlogCFC, you can read more about the demo in my blog entry. There you'll find feedback that various readers sent me about my design.

Through the blog post, you can see the feedback that various readers sent me about my design. Let's get started talking about the project.

Requirements

It's not a requirement to download and install Flex 2 but you may want to install Flex 2 SDK (it's free) and Flex Builder 2 to try out some of the code in this tutorial.

Flex 2 SDK (free)

Flex Builder 2 (SDK included)

Flash Player 9

ColdFusion MX 7.0.2

Building the Flex 2 front end

I started off by figuring out what would actually exist on the front end. BlogCFC by default displays a set of entries and pods, with most of the pods acting as ways to filter content—by day, search, category, and so forth. Obviously, I didn't want to make an exact copy of the HTML version because that would have been a waste of time. So the first change I made was to show the entries and entry content all on one page. This lets a reader browse the titles of entries (along with other bits of information, like a date and category) and then click to load a particular entry. Right away, this improves the experience a bit because the user doesn't need to constantly reload the entire page in order to browse the blog.

Visual controls

One of the things I found difficult as a new Flex user was figuring out which control to use where. To be clear, I'm not complaining. Flex offers developers a lot of choices in its available rebuilt controls. I suggest taking a look at the Flex 2 Component Explorer.

Become familiar with what Flex offers. Obviously, Flex has "typical" HTML form controls—such as text fields and drop-down menus—but you also get some cool controls like calendars, sliders, and grids. The grid is what I selected to display my entries (see Figure 1).

Using a rebuilt Flex grid to display blog entries in the application

Figure 1. Using a rebuilt Flex grid to display blog entries in the application

In some regards, this works much like an HTML table—except that you can scroll and sort, which is a very handy feature for the user. How difficult is the code behind all this? Consider the following:

<mx:DataGrid height="100%" width="100%" id="entryGrid" dataProvider="{this.entries}"
click="throwSelect()" change="throwSelect()">
   <mx:columns>
      <mx:DataGridColumn headerText="Posted" dataField="posted" labelFunction="gridFormatDate" width="200" />
      <mx:DataGridColumn headerText="Title" dataField="title" />
 <mx:DataGridColumn headerText="Categories" dataField="categorynames" width="200" />
  </mx:columns>
</mx:DataGrid>

If you don't know MXML, I'm willing to bet you can read this and understand the basics of what is going on here. It's basically a table (<mx:DataGrid>) with three columns (<mx:DataGridColumn>). Each column has a label and a particular data field (in other words, what field to use in the data behind the scenes).

Layout controls

I've only mentioned visual controls so far; Flex 2 also comes with some handy layout controls. (Again, the Flex 2 Component Explorer is your friend.) I wanted to let people read not only the blog entries but also the comments to a blog entry. Because a user may not be interested in the comments, I used the built-in TabNavigator control in Flex 2 to created a tabbed interface (see Figure 2). This control lets me show the entry by default, but lets the user choose to see comments, or actually even add a comment.

Using the TabNavigator control in Flex 2 to create a tabbed interface

Figure 2. Using the TabNavigator control in Flex 2 to create a tabbed interface

The code behind this functionality is rather trivial. I wrapped the entire block in the <mx:TabNavigator> tags. Each child then automatically becomes a tab. So, for example, the first child (the entry) is created as follows:

<mx:Canvas id="bodyPanel" label="Entry" >

Canvas is the type of child container I used, but it doesn't really matter what I pick. Flex is smart enough to use just the kids as tabs. In other words, as I add more and more components into the navigator control, they simply add themselves as new tabs. Flex has other navigator controls as well, and the exact same behavior works for them too. As a developer, I love this kind of behavior.

Pods

Moving on, I decided on three main pods: Categories, Search, and Calendar. This would provide three main ways to filter blog entries, and it seemed to be most appropriate for the demo I was building.

The first two pods are rather simple. They demonstrate how Flex recreates basic HTML form fields. The last pod displays a calendar, one of the built-in controls you can use with Flex—and now also in ColdFusion MX 7, which uses Flex to display calendar widgets.

How did I decide on the controls? In some cases it was obvious. A calendar should use a calendar control—or, to use the right Flex 2 component name, the DateChooser component. Here is the code:

<mx:DateChooser id="calMain" width="100%" click="checkMonth(); if(calMain.selectedDate)
throwSelectDate(calMain.selectedDate);" />

The DateChooser control was the only piece that really challenged me. For some reason, Flex 2 lets you disable only days in the control; you can't provide a list of enabled days. My back-end code was returning days that had blog entries, so I had to do a bit of magic to "flip" the dates. Essentially, I simply took the set of days that contained entries and found the other days of the month. For example, if there were only three days to the month and day 2 had an entry, I would return 1 and 3. When I get to the description of the back end, I'll demonstrate that some more.

For the Categories pod, I decided to use a simple list control. This gave me a nice area to place my categories and, even better, enable automatic scrolling when there is a long list of categories. Compare the HTML version of the list to the Flex 2 version (see Figure 3).

HTML version of a list of categories  Flex 2 version of a list of categories

Figure 3. HTML version (left) and Flex 2 version (right) of a list of categories

I know I've left a lot out—there's a lot of ActionScript going on here—but, in general, this describes my experiences working with Flex 2 at the front end. Now let's turn things around a bit and talk about how I changed the back end of the application.

Building the ColdFusion back end

The main issue I ran into when coding the back end in Flex 2 had nothing to do with Flex, but simply with the way I had designed my blog. The blog applicaiton uses a core CFC that handles almost all of the database logic. The CFC is built, however, in such a way that you have to make an instance of it in order to use it. When creating the CFC, you pass in a configuration parameter. This sets up various settings inside the CFC and that version is returned. The CFC simply doesn't work in the "remote" manner that Flex 2 needs. By this I mean that if you run any of the methods as a web service or through Flash Remoting, the CFC won't have the correct setting. This would have been a big problem if I wanted Flex to talk to my blog's ColdFusion component.

Luckily there was a workaround, which I will talk about because it's useful for more than just correcting poor design decisions. (Hey, it was my first component-based application!) I built what I call a "proxy CFC," which simply acts as a conduit to pass information back and forth between the Flex 2 front end and my main blog component.

As an example, let's consider the most common action, the getEntries() function. Here is the code from the proxy:

<cffunction name="getEntries" access="remote" output="false"
returnType="query">
  <cfargument name="filters" type="struct" required="false">
  <cfset var data = "">
  <cfset var params = structNew()>
  <cfset var newdata = "">
  <cfset params.maxEntries = 50>
  <cfset params.mode = "full">
  <cfif structKeyExists(arguments, "filters")>
      <cfset structAppend(params, arguments.filters)>
  </cfif>
  <cfset data = getBlog().getEntries(params)>

  <!--- fix bodies --->

  <cfloop query="data">
       <cfset querySetCell(data, "body", getBlog().render(body),
  currentRow)>
  </cfloop>
  <cfreturn data>
</cffunction>

Without getting into too much detail, the basic point of this method is to accept various filters, apply those filters to the main collection of entries, and return the text. After checking for the filters, these are then passed on to the blog engine in this line:

<cfset data = getBlog().getEntries(params)>

What does the getBlog() function do? It is pretty trivial as well:

<cffunction name="getBlog" access="private" output="false">
  <cfreturn application.blog>
</cffunction>

I know, I know—it's bad to address any outside scope in a CFC directly. Good ColdFusion developers know this. However, as with most rules, there are some exceptions. In this case, the CFC simply uses the Application-scoped blog component that already exists. This ensures that when the Flex 2 front end talks to the back end, the component will not need to be recreated on each call. Obviously there are other ways of coding this functionality, but this worked well for me.

Another thing the proxy CFC gives me is a bit more control over how my blog resources are used. Note that the getEntries() call has a hard-coded maxEntries value. The blog application uses this value to specify how many entries it should return at maximum. Because I hard-coded this value, the front end can't overrule it. In other words, the proxy allows me to provide access to the components but with some rules in place.

You can imagine a proxy that allows only a certain number of remote connections per hour, or logs the connections for billing purposes later.

Lessons learned

I learned quite a bit from building this application. In general MXML is simple—almost as simple as learning HTML. You have controls for layout and controls for various user interface pieces. The most difficult part of the process was simply learning to speak the MXML and ActionScript lingo. Once I got into it, however, the process moved quickly.

To be fair, I had worked with Flex 1 and 1.5 on previous occasions, so I wasn't a complete beginner. However, I do think that any ColdFusion developer should take the time to add Flex 2 to their arsenal of languages.

Last but not least, let me leave you with some snapshots of the original BlogCFC user interface (see Figure 4) and the revised Flex 2 front end (see Figure 5). I think it's pretty snazzy—although bear in mind that I'm no designer.

Original blog application

Figure 4. Original blog application

Revised blog application built with Flex 2

Figure 5. Revised blog application built with Flex 2

Don't forget that you can always right-click the Flex 2 application and select View Source from the pop-up menu. This lets you browse the MXML and other files related to the project that I linked to in the introduction to this article. (The ability to view source is one of the cooler features of Flex Builder 2—an automatic way to add code sharing to your application.)

Where to go from here

About the author

Raymond Camden is the owner of Camden Media, Inc, a web development and training company. A long time ColdFusion user, Raymond has worked on numerous ColdFusion books including the ColdFusion Web Application Construction Kit and has contributed to the Fusion Authority Quarterly Update and the ColdFusion Developers Journal. He also presents at numerous conferences and contributes to online webzines. He founded many community web sites including CFLib.org, ColdFusionPortal.org, ColdFusionCookbook.org and is the author of open source applications, including the popular BlogCFC blogging application.

Raymond can be reached at his blog or via email at ray@camdenfamily.com. He is the happily married proud father of three kids and is somewhat of a Star Wars nut.