New Simple Application


A brand new Simple application for ColdFusion is now available from steveeray.com. The Simple For Sale System is an online classified ads system that allows people to post items for sale, for free, wanted items, or any category desired.

Posted June 04, 2005

Submitting Flash Forms in CFMX 7


I started experimenting with the new Flash forms feature in Cold Fusion 7. My first attempt was to convert an HTML form on our Intranet that searches the phone directory by either name, phone number, or department. I decided to have each of these queries as a separate tabbed panel on the form. I first put one submit button for the whole form, but found that I could not determine which tab the user was on when they clicked it, because all fields on the form are sent. I then put a separate submit button on each tab, with a unique name, so I could query it's existence to determine where they clicked from. A screen shot of the form:
flash_form.gif
Once submitted, the database queried, and the results displayed, I wanted to re-display the form so they could do another search. Here I wanted to have the tab they submitted from be the selected tab on the form, with the previous search values still on the form. This was easily done by setting the selectedIndex attribute of the cfformgroup equal to the appropriate tab, which I could determine from the value of the submit field.

I was happy with this until a few test users asked why hitting the Enter key after typing in something did not work like the HTML form. This was true, the submit button must be clicked with the mouse to submit the form. I searched the MM forum and found a solution (submitted by Bartjan Meier) to capture the Enter key when pressed and submit the form programmatically with ActionScript code:

<cfinput type="text" name="lastname" label="Last"
 onKeyDown="if(Key.isDown(Key.ENTER)) {submitForm()}">

This did successfully work, but requires you to put the code for every text field on the form that the user may hit Enter on. Since I had few fields, I added this to the cfinput fields and it worked, partially. The form would be submitted, but because the submit button was not clicked, it does not get passed in the form collection. All the input fields were, but not the submit fields. As the value of the submit field was what I was using to determine which tab the user clicked on, I did not know which query to perform, let alone which tab to bring to the front when re-displayed.

I e-mailed a few gurus to see if there was a better solution. Unfortunately, the MM engineer responded: "There really is no good way to do this, however, it is a good enhancement request though." Great.

Since the input fields were being sent, I ended up creating a hidden field and programmatically setting its value to the appropriate tab when the form was submitted. Thus the onKeyDown code now became:

onKeyDown="if(Key.isDown(Key.ENTER)) {myform.thetab=0; submitForm()}"

with the value set to the appropriate tab, and the new hidden field at the end of the form:

<cfinput type="hidden" name="thetab" value="0">

This hidden field also had to be set if the user did click the submit button, so that code became:

<cfinput type="submit" width="100" name="searchname"
 value="Search" onclick="myform.thetab=0">

This is finally in a state where I'm happy with it, but this kind of behaviour with the Flash forms will give me another factor to consider on whether to use a Flash or HTML form in the future.

View Live Example
Download Source

Joys of a Typeless Language


Cold Fusion is a typeless language, meaning a variable can contain any kind of value (numeric, string, boolean, etc.). This recently caused me much confusion until someone on the Macromedia CF Forum pointed this out to me.

I had an application where I wanted to display a price value. If the price value had no cents, but the user typed in an ending ".00", I wanted to remove this, and just display the whole dollar amount (e.g. $25 instead of $25.00). So being the smart programmer, I just looked for a ".00" as the last three characters and dropped them if it existed. I tested it, and if worked just as desired.

The first day in production, someone calls and says they keep entering $6,000 but it shows up on the web as "$6,". What!! I test this myself, and yep, the last three zeros are getting dropped. I scour the code, write a little test, and CF keeps thinking ".00" is equal to "000". Of course any human can see these strings are not equal.

They may look like unequal strings to me, but to CF they're the same. Why? Well, CF looks at the first ".00" and decides that this can be interpreted as a numeric ZERO, so that's how it treats it, as numeric. Then the "000" can be interpreted as a numeric ZERO too, so ZERO equals ZERO and those last three zeros are going to be dropped from the value and "$6," is going to be displayed.

The solution is to use the compare() function, which does a string comparison.


Incorrect:
<cfif right(trim(itm_cost),3) eq ".00">
  <cfset form.itm_cost=left(trim(form.itm_cost), 
      len(trim(form.itm_cost)) - 3)>
</cfif>

Correct:
<cfif NOT Compare(right(trim(itm_cost),3),".00")>
  <cfset form.itm_cost=left(trim(form.itm_cost), 
      len(trim(form.itm_cost)) - 3)>
</cfif>

I know in the future I'll come across this again and can only hope I remember the "typeless" nature of Cold Fusion.