Thursday, April 10, 2008

When Your Flex App Needs to Hide

Shockingly, your Flex (or Flash) application will not take center stage for all clients and all situations. Frequently the application simply provides a useful interface for some utility, but is not or does not contain, the featured content itself. In this situation you'll only want/need to have the application loaded or visible when the user requires interaction with the provided functionality. Often there will be a central location (page) where the application is available. The underlying reasons for this, especially for assets embedded in a web site, is the fact that the application has a footprint that pushes out the surrounding content, or prevents interaction with content that may be visible 'beneath' the application when the wmode is set.

On a recent client e-commerce implementation the requirement was for their shopping cart to be ubiquitous, but not overbearing. In this case the normal HTML content of the site was what the client wanted featured, not the cart that would only be used occasionally by some visitors. In other situations, the approach is to either have a fully integrated shopping experience where products are displayed and managed within the application, or to have a single cart/check out page for the application that is displayed when the user wants to view the current contents and to place their order. In this case the 'products' were not visual and didn't lend themselves to an all-in application approach, also the client wanted ready access to their cart without having to redirect to a dedicated page. So the approach taken was to 'hide' the cart.

In this situation, we chose to leverage the browser to achieve our ends. This involved the use of layering and absolute positioning via interaction with the ExternalInterface class and css and JavaScript in the browser. The basic idea here is to push the application 'off' the page and only make it visible when it is needed. This also allows the entire web page to be interactive when the application is hidden, while at the same time having the application standing by when it is needed.

The fully realized application lives Here. And a toned down version with source code can be found Here.

One further feature of this application was the use of the iframe to provide regular form processing for cart items that require further user input. The client wanted to be able to add and customize these forms through the CMS which precluded making them pre-compiled within the application and budget prevented dynamically building them. The compromise was to intercept the form post on the back end, and feed the results back into the application.

Demo application source.

Sunday, March 16, 2008

Using Flex to “Black Box” HTML Forms

I've you've ever wanted to refresh a tired web interface by replacing your traditional HTML forms with a more user friendly interface, you may have encountered some of the thoughts which are addressed here. I'll describe a method to utilize the power of Flex components in conjunction with some simple ColdFusion tags to make this process as simple as possible. You'll end up with (hopefully) a better user inteface; and be able to centralize multiple forms into a refreshless (page that is) interface.


The Black Box Approach

One of the first things that you'll encounter is a list of questions:

  • What does this form capture?

  • What validation is being used on the data input (e.g. o.length>6?b7(o):false;)?

  • What is returned to the user when the form is posted? What if there is an error?

  • What server side technology is used to process the form data (php, asp, jsp, cf, perl, vb.net, c#, tcl, cgi)?

  • What business logic is used on the data to generate the response the user gets from their submission?

  • What databases etc… are effected by this form post?

As the above questions show, you can quickly come to realize that you don't necesarily want to have to reproduce what the form does, and in many cases you don't actually know the answers to some of these questions. Wouldn't it be easier to treat the form as a Black Box, and send it one it's merry way? Yep, and here's how.


The Example

In the example shown HERE, I wanted to make my case as simply as possible. To this end I chose a web based form that provided some simple feedback for valid posts, and an easy way to determine if it wasn't; it's also a very tolerant form in that it didn't impose things like captcha if you put in bad form data as a form of punishment (well, ok security). With this in mind, I decided to use the Weather Channel’s ® form at the top of their home page where you enter your city (I'm using the zipcode option for, again, simplicity)


The Code

The simplicity of this example is that fact that I'm using Flash Remoting via the RemoteObject mxml tag.



<mx:RemoteObject id="blackBoxRO" destination="ColdFusion" source="BlackBox.components.blackbox" showBusyCursor="true" >
<mx:method name="getTemp" result="handeResult(event)" fault="doh(event)" />
</mx:RemoteObject>

If you don't happen to have ColdFusion on your own server, but have say a rich uncle who does, you can use the same CFC (ColdFusion component for the uninformed) to provide a Web Service that will accomplish the same task. Just update the path information and the local variable serverURL (can be passed as flashVar) to your ColdFusion web root.



<mx:WebService id="blackBoxWS" wsdl="{serverURL}/blackbox/components/blackbox.cfc?wsdl" >
<mx:operation name="getTemp" result="handeResult(event)" fault="doh(event)" showBusyCursor="true" />
</mx:RemoteObject>

The magic all happens inside the ColdFusion function with the call that populates the "real" form with the data you send from Flex and posts your submission. All you have to do now is look at the response and what it means for success or failure, which you then return to Flex to do with as you please.



<cfcomponent>
<cffunction name="getTemp" access="remote" returntype="string" output="yes">
<cfargument name="zipcode" type="string" required="yes">
<cfset var returnValue = "">
<cftry>
<!--- use CF http request to post form data --->
<cfhttp url="http://www.weather.com/search/enhanced" method="post" delimiter="," resolveurl="no" >
<cfhttpparam type="formfield" name="where" value="#ARGUMENTS.zipcode#">


The key thing to look for in using this technique is to make sure that you capture all the form inputs and spell them exactly as they appear in the "real" form (this includes hidden fields! so don't over look these). You can usually easily determine what fields are present by viewing the source of the web page with the form, or using a tool like FireBug to peruse the html.


Get the source.