Scroll Through Tabs in Flex with Mouse Wheel

I blogged the other day about an Office 2007 feature for the tabs that are apart of the ribbon in that you can use your scroll wheel to change the selected tab. I thought this was actually pretty cool.

I decided to implement it in Flex because I figure it would be extremely easy... and it was! Took about 15 minutes total. However, it seems it is having issue when playing without a breakpoint in the code. Just playing through normally, when I scroll up or down, it actually seems to skip a tab when going through them. Yet, if I put a breakpoint at the beginning of the event handler and play through it that way, it goes to the next tab as it should.

Here is a demo of what I have done. Source is included...

http://www.kylehayes.info/tabby/TabThumbWheel.html

Transfer and Flex: Part 1

I started a project a couple of months ago that has and is going to continually have a very complex and growing architecture. The technology stack in place is Flex 3, Cairngorm 2.2, ColdFusion 8, ColdSpring, Transfer, and SQL Server 2005. This is my first Flex application that will be using Transfer to handle the database abstraction layer. Normally, I would use Brian Rinadi's Illudium PU-36 CFCGenerator to handle the initial generation of all my CFCs and from there would either modify the XSLT files or simply append to the generated CFCs as I saw fit.

The problem with this type of approach lies namely in the early stages of application design and development (especially since I traditionally don't go through a line of specs working on a solo project) when the database is going through many changes. Each time you make a change to the database, you either have to regenerate your files which will overwrite any changes you made, or you have to manually hand-code the database changes. On top of this, it doesn't take care of any of your table relationships as per a 3rd normal form database structure. You then have to design your own home-brew setup of such a system if you require it, or simply provide functions that return the structs/VOs to Flex as you need them by manually building up the hierarchical tree of the model.

For this project, I knew from the beginning that the database schema was going to be pretty complex and that it was also going to be going through changes as I developed and tried things out. I knew that I wanted to get Transfer to work with Flex. I had tried this once in the past and failed because I was designing Flex applications differently at that time. I now know better to design with a service layer in mind.

Although, it is not that easy either. There are actually quite a few steps involved when using Transfer to interact with your database and to return the right kind of objects back to Flex. Also, let me state, that I am talking about this in terms of using the AMF protocol with RemoteObjects between ColdFusion and Flex so that datatypes are appropriately and quickly translated.

This post will first introduce the Transfer ORM framework and why it is not a basic task to integrate it into your ColdFusion / Flex application. In the next part of this article, I will discuss the technical details of getting this all to work.

Transfer ORM framework

Visit project website

ORM, or Object-Relational Mapping, in simplistic terms is abstracting a representation of your data inside a database as objects in your application. An ORM framework does all of this abstraction semi-automatically by means of introspection to your database and generating the necessary files, or by a configuration file that describes the datatypes and the relationships of the tables to each other. Transfer falls into the latter category.

While some say that a fault of Transfer (esp when compared to a competing framework, Reactor) is that you have to write the table structure and it's relationships manually in an XML file. Whereas Reactor is a framework that reads the database metadata. At first, I thought this same thing and after working with Transfer later, have found it much better to be in control and to define the relationships myself. With this method I really feel like I have a much better understanding of what Transfer is creating when it generates it's objects. Plus when debugging your code it is easier to see what columns/fields are causing issues in your relationships.

The benefits of using Transfer over generating the CFCs yourself using tools like Brian Rinaldi's Illudium PU-36 CFCGenerator is that once you have defined your XML file, the actual creation of the CFCs is completely automatic. To give you an example, let's say you have a table in your database called Employee that has the following fields: employeeId, firstName, lastName, email. Once you have instantiated the TransferFactory, you simply call the object the you would any other VO, only you haven't previously written it:

<cfset firstName = variables.Transfer.get('employee', 1).getFirstName() />

Transfer.get() retrieves a specific Transfer object (which is defined in your Transfer XML) with a Primary Key ID of "1". Then it simply calls the generated "getFirstName()" method on that object and returns it to you. That's it! It is really simple.

This is hardly even skimming the surface of what Transfer does for you. Let's say that an employee can have multiple phone numbers on file that you store in a separate table called EmployeePhone. This is of course a One-to-Many relationship. Once you have simply defined this relationship in your Transfer XML you would then access the phone numbers this way:

<cfset emp = variables.Transfer.get('employee', 1) />
<cfset empPhoneArray = emp.getPhoneArray() />

From there you can simply loop through that array which in turn provides different EmployeePhone Transfer objects. You can configure in your XML whether that relationship will return an array or query. Notice that I mentioned it would return an array of Transfer Objects. This is where it gets tricky. The default return type of any relational object is typed as a Transfer Object. This is instantiated from the generic Transfer Object interface in the framework and is what all the relational object inherit from. However, you can change this by applying a decorator to any of your objects which will change the type of the object to the decorator path. The decorator will also allow you to add methods as well as change existing ones that the Transfer Object defines.

As you can see, Transfer can be very very powerful in your applications. It doesn't require very much setup time and configuration. As with most advanced concepts like this, it takes practice to really understand the underlying methodologies and to use them wisely in your application. Also, do not think that Transfer is simply a glorified code generator. Mark Mandel has spent a lot of time utilizing ColdFusion's unique strengths to truly make this a fast and effecient framework to keep your application at top speed.

That's it for now. Next time I will actually get more technical about the configuration file and start discussing how to prepare your CFC middle-tier for Flex consumption.

Related reading:

Online Pizza Ordering the Way it Should Be

Dominos.com now the stick to which all future online pizza ordering systems (and other ordering systems) will be measured. The wife and I received a coupon for Domino's Pizza today in the mail, and while I normally don't go for eating out on a Monday night, she has been busy as of late and I had just gotten home after sitting for quite some time in traffic. I was just going to call in the order but then I decided to order online.

First of all, I immediately realized when I approached their page that they have the "You got 30 minutes" marketing campaign right now. Also, I must say that they have the nicest online pizza ordering site in the industry (though I can only compare it to Papa John's and Pizza Hut). There Web 2.0 look and feel as well as Flash-y elements created great appeal and very nice appearance. But that wasn't the half of it...

Along with their launch of this new campaign came the launch of the "Pizza Tracker". This thing is awesome! A real-time application written in Flash provide a slick interface and virtual viewport of your pizza each step of the way. A large progress bar shows you the status from Order Placed, Prep, Bake, Box, to Delivery all as it happens. In some of the steps, it even tells you who completed that part of the process. It includes a glowing red filler for each of the progress as the bar fills up. This application is a great example of what non-technical companies can do to utilize today's instant gratification technologies like Flash and Data Services.

Here are some screenshots of the process as it was happening:

Domino's Pizza Tracker
Uploaded with plasq's Skitch!

Domino's Pizza Tracker
Uploaded with plasq's Skitch!

Why Flex and AIR?

My first 30onair video:

10% off Flex Builder 3

Yep, that's right. Thanks to the handy-dandy site RetailMeNot.com I found a coupon code for 10% off any Adobe product sold in the online store. If your math is right, you will see that this makes the PRO upgrade at about $270 instead of $300. While you are at it, you might as well purchase the Creative Suite Web Premium bundle for $50 off.

Oh yeah, and the code you use is: DESIGNQ108

Remotely Connect Your Flex/AIR App Without Services-Config

Many developers have the question of how to define the infamous connections to the various AMF gateways to which they need to communicate through to their server-side code. The process, while usually handled through the famed services-config.xml file, can actually be handled directly in your ActionScript very easily.

The examples below are showing connecting to a AMFPHP endpoint as opposed to a ColdFusion one, only because that is what I have been learning and working on recently. For ColdFusion, simply replace the latter part of the string with /flex2gateway/

First, define a new string in your model that references the URI to which you are going to connect with your RemoteObjects:

var endpointUri:String = "http://mysite.com:8000/amfphp/gateway.php";

Then, simply define a new ChannelSet, and Channel to add to the ChannelSet that references your URI:

var cs:ChannelSet = new ChannelSet();      
var customChannel:Channel = new AMFChannel("my-amfphp", endpointUri);
cs.addChannel(customChannel);

Finally, define your RemoteObject to access this ChannelSet that you just created and set the destination to the name you gave your AMFChannel:

<mx:RemoteObject id="employeeService" channelSet="{cs}" destination="my-amfphp" source="com.yourcompany.app.employee.EmployeeService"
      showBusyCursor="true" />

It is as simple as that! Be sure to take out the services-config declaration in your compiler arguments to test this out appropriately.

AIR Does NOT Require Certificate for Full API

After Ted posted his AIR entry on his blog and talked about the various great things about the runtime, he also mentioned that it is important to purchase a signed certificate from companies such as Thawte in order to get the "greatly expanded APIs", I immediately pinged Ryan to confirm this since Ted was not immediately available.

Shocked, Ryan went to check and reported back that it was not the case. Since then, I noticed that the misinformation has been removed from Ted's blog.

The actual question I posed to Ryan was if he thought the $300 certificate cost from Thawte would discourage the development of open source and free applications. He didn't think so due to the ability to self-sign your own applications, however, at the cost of them being labeled as "UNVERIFIED" when the user installs them. Is there a way around this? Such as a certificate for open source applications to encourage this ever-increasingly popular movement?

Adobe Flex 3 and AIR SDK Are Here!

W00T!!!!!!!

I am so happy that the final releases of the long awaited Adobe Flex 3 (and builder) and AIR SDK are here. And they have a couple of other cool bits and pieces about them to go with this major update to the famed leading RIA platform.

First of all, as you can see at the store, the upgrade price is only $99! Also, if you have a keen eye, you will notice that it is no longer a separate license for PC and Mac...they come together now!

This is huge news and is truly making Flex be even more affordable and better than ever. One thing to note, is that the $99 upgrade is for Flex Builder 3.0 standard. Chock up an additional $200 and you've got the Pro version which includes advanced charting components and testing tools.

Keep in mind that the Flex framework is still free and open source. The prices above are for the Flex Builder 3.0 IDE products.

Be sure to thank the Flex team for all their hard work!

Yahoo! Flex Skin Buggy

Lately I have been using the Yahoo! Flex skin in a few of my interfaces as it greatly improves the overall standard look of the Flex widgets. It's very easy to implement (thanks to Adobe for creating a simple workflow for this). Recently, however, I have noticed a couple of bugs in the skin that are worth bringing up and should definitely be fixed. Suffice it to say that I am not sure if they are Adobe's fault or Yahoo!'s fault.

As you can see there is an issue on the bottom where a partial row of the datagrid is showing and the other part of it is hidden. It's the hidden part that is causing the skin to appear invisible. Note that, as soon as I scroll the datagrid it goes away. However, if I move my mouse over that row it comes back. Same goes for the [+] button. You can see that it's bounds are causing an anomaly on the control bar.

Like I said, I am not sure if this is an Adobe issue or a Yahoo! issue, but it is annoying enough that I might be swapping the skin out. I don't want to, but I may have to.

Copying Text To the User's Clipboard in Flex

Sometimes there is a requirement or a desired usability enhancement for text to be placed on the user's clipboard. This is a great little feature in an your application if you are able to provide it and have a good reason to. In Flex, it couldn't be any easier. The setClipboard() function lives inside the System package. Simply call it like so:

...
import flash.system.System;
import mx.controls.Alert;

public function copyText(txt:String):void
{
System.setClipboard(txt);
Alert.show("'" + txt + "' has been copied to your clipboard");
}
...

Simple as that.

Lean Out Your ActionScript Imports

I have been working on a new Flex application at work lately which I am pretty excited about. Not only has it received a lot of positive attention, but I also get to learn how to build a Flex application that is to be using a PHP middle-tier. Luckily for me, I do have experience with PHP, plus there seems to be some great resources on the topic.

Anyway, the application is being programmed with the help of the Cairngorm micro-architecture and as such, there is a lot of copying and pasting of files as I create new commands, events, and delegates. One thing that has bugged me in the past about doing this, is figuring out which import statements belong in the newly created class and which don't. Many a times, I just didn't even bother. That has now changed, now that I discovered an easy, automagic way of doing so.

Knowing that Eclipse always has some gems hidden in the right-click context menus, I perused them to see if there was anything about import statements. Lo and behold, if you right-click on any of the lines that contain import statements, and go to the submenu "Source", there is an option called "Organize Imports" (Or my preference: [Mac] Command + Shift + O, [PC] Ctrl + Shift + O). Not only does it actually organize your import statements by package alphabetically (starting with the root package), but it also eliminates any import statements that you do not need in that class. Pretty neat!

Some features I would like to see added to this:

  1. Add statements that are required
  2. Combine multiple import statements from the target package using wildcard (*) (Perhaps it could be defined in preferences, how many should be considered before it combines)

More Entries