Server Time:
Sunday May 11 2008 08:17 PM  
Your Time:
  
HostMySite.Com is sponsoring this tutorial, please visit their site today!
This tutorial is sponsored by HostMySite.Com - ColdFusion Hosting

Form Validation and Flow -- One Technique
by: Steve Sommers
Email this tutorial to a friend Display Printer Friendly Format
[Download in PDF Format] [Download in FlashPaper Format]

Form Validation and Flow -- One Technique

There are multiple ways and techniques to program almost any task. Because of this, there is one thing I can guarantee: If you analyze how three different applications validate form data, you will find three different ways of doing it (assuming they validate at all). Some techniques are better than others. Here I'll describe one that works for me.

A little about me first so you understand where I am coming from. I have been a professional application designer and programmer for over 20 years; the last ten years I have had a heavy focus on web based applications using various technologies. I'll be the first to admit that my views of user applications is myopic -- I tend to see everything with a "how usable is the application to the user" and "how is the user going to break the application."

Now two of my pet peeves: 1) Programs that don't gracefully display entry errors to the users and 2) Programs that don't validate EVERYTHING that the user enters. To me, customer impression wise, there is nothing worse that a generic "Invalid data, press the back button and try again." System security wise, there is nothing worse that assuming that FORM data is valid and blindly acting on it. Also, client side validation (JavaScript, etc.) is good for "customer impression" but cannot be used as a substitute for server side validation.

Anyway, now that bored stiff with my high and mighty ideals, I'll present you with a simple technique I use for validating data.

The biggest difference between this technique and most "common" tutorials that I have seen on CF is that the FORM page and the ACTION page are one and the same and this has three key benefits that can be problematical using separate FORM and ACTION pages:

First, you have full control on what information is "defaulted" to the user in form fields and you can preserve any previously keyed information in the event of any entry errors. Third, with some very minor tweaks, you can allow the passing of "default" form field values via URL parameters. Third, using the <cflocation> tag to direct the user to the next page allows for refresh to work properly without the nagging "do you want to repost" browser message and all the associated code to handle double-posts.

MySampleForm.cfm:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<cfparam name="FORM.FirstName" default="">
<cfparam name=
"FORM.LastName" default="">
<cfparam name=
"FORM.CardNumber" default="">
<cfparam name=
"FORM.ExpirationMonth" default="">
<cfparam name=
"FORM.ExpirationYear" default="">
<cfparam name=
"FORM.Action" default="">

<cfset VARIABLES.y1=DatePart(
"yyyy",Now())>
<cfset VARIABLES.y2=VARIABLES.y1+10>

<cfparam name=
"URL.Msg" default="">
<cfset VARIABLES.Msg=
"#URL.Msg#">

<cfif VARIABLES.Msg is "" and FORM.Action is "Submit">
  <!-- validate data -->
  <cfif Trim(FORM.FirstName) is
"">
    <cfset VARIABLES.Msg=VARIABLES.Msg &
"<li>You must enter your first name</li>">
  </cfif>
  <cfif Trim(FORM.LastName) is
"">
    <cfset VARIABLES.Msg=VARIABLES.Msg &
"<li>You must enter your last name</li>">
  </cfif>
  <cfif Trim(FORM.CardNumber) is
"">
   
<!--
     This is a simple "card number entered" check for the
     purpose of this example; I would do a more thorough
     check to determine number was valid!
     -->

    <cfset VARIABLES.Msg=VARIABLES.Msg &
"<li>You must enter your last name</li>">
  </cfif>
  <cfif Val(FORM.ExpirationMonth) LT 1 or Val(FORM.ExpirationMonth) GT 12>
    <cfset VARIABLES.Msg=VARIABLES.Msg &
"<li>You must select a valid expiration month</li>">
  </cfif>
  <cfif Val(FORM.ExpirationYear) LT VARIABLES.y1 or Val(FORM.ExpirationYear) GT VARIABLES.y2>
    <cfset VARIABLES.Msg=VARIABLES.Msg &
"<li>You must select a valid expiration year</li>">
  </cfif>
  <cfif VARIABLES.Msg is
"">
    <!-- validation passed, process data -->
    <!—
          ADD YOUR CODE HERE TO PROCESS THE DATA, IF ANYTHING
          FAILS THEN SET VARIABLES.Msg
     -->

  <cfif VARIABLES.Msg is "">
    <!-- process completed successfully, send client to next page -->
    <!—
           MODIFY THE FOLLOWING CFLOACTION TAG TO SEND THE
           USER TO THE NEXT PAGE IN THE PROCESS LIKE A THANK
           YOU PAGE, YOU'VE BEEN VALIDATED, ETC.
    -->
   
<cflocation url="MySampleForm.cfm?Msg=#URLEncodedFormat('Information validated & posted - Thank you!')#" addtoken="No">
  </cfif>
<cfelse>
  <!-- validation failed, make the message pretty for the user -->
  <cfset VARIABLES.Msg="<h1>ENTRY ERROR</h1>The following error(s) were detected:<ul>#VARIABLES.Msg#</ul>">
</cfif>
</cfif>

<html>
  <head>
    <title>
My Test Form and Validation</title>
  </head>

  <body>
 
<cfoutput>
  <cfif VARIABLES.Msg is not
"">
    <p>#VARIABLES.Msg#</p>
  </cfif>
  <cfform action=
"MySampleForm.cfm" method="POST" enablecab="No">
  <table cellspacing="2" cellpadding="2" border="0">
    <tr>
      <th align=
"right">First Name</th>
      <td>
<cfinput type="Text" name="FirstName" value="#FORM.FirstName#" message="You must enter your first name." required="Yes" size="30"></td>
    </tr>
    <tr>
      <th align=
"right">Last Name</th>
      <td>
<cfinput type="Text" name="LastName" value="#FORM.LastName#" message="You must enter your last name." required="Yes" size="30"></td>
    </tr>
    <tr>
      <th align=
"right">Credit Card</th>
      <td>
<cfinput type="Text" name="CardNumber" value="#FORM.CardNumber#" message="You must enter your credit card number." validate="creditcard" required="Yes" size="20"></td>
   </tr>
   <tr>
      <th>
Expiration</th>
      <td>

         <select name="ExpirationMonth">
           <cfloop index=
"i" from="1" to="12">
            
<option value="#i#"<cfif FORM.ExpirationMonth EQ i> selected</cfif>>#NumberFormat(i,"00")#</option>
           </cfloop>
        
</select>
         /
         <select name="ExpirationYear">
          
<cfloop index="i" from="#VARIABLES.y1#" to="#VARIABLES.y2#">
              <option value=
"#i#"<cfif FORM.ExpirationYear EQ i> selected</cfif>>#NumberFormat(i,"0000")#</option>
          
</cfloop>
         </select>

      </td>
    </tr>
    <tr>
      <td>
&nbsp;</td>
      <td>

        <input type="submit" name="Action" id="Submit" value="Submit">
        <input type=
"reset" value="Reset">
      </td>
   </tr>
</table>

</cfform>
</cfoutput>

</body>
</html>


To summarize the technique:

1. FORM page and ACTION page are one and the same (MySampleForm.cfm in this example)
2. Define all your form variables using the <cfparam> tag -- this example default all the values to "" but you can default any value the application requires
3. Make sure your submit button has a name and value and use this value to determine whether you are acting on POSTed data -- make sure the defaulted value for this field is "" (<cfparam name="FORM.Action" default="">)
4. If acting on the data (FORM.Action is "Submit"), validate all the data -- I use VARIABLES.Msg to hold any entry or action error for displaying to the user
5. If all the data validates, act on the data and if successful, us the <cflocation> tag to send the user to the next page in the process (this example sends us back to the same page with a message -- this is unlikely in a real application)
6. If you fall through to the actual page building code, display any errors or warnings to the user, if applicable, and default the FORM fields to their prior or defaulted values

Security wise, step #4 is the most important step -- validate everything!

There are other advantages to this single page technique, especially if you have to deal sites that have secure and unsecure portions and you are attempting to secure as few pages as possible because of CPU and bandwidth limitations.

One last note, I mentioned an parameter passing tweak to allow passing "default" values as URL parameters – here's the tweak:

<!-- original code from above -->
<cfparam name="FORM.FirstName" default="">
<cfparam name=
"FORM.LastName" default="">

<!-- the tweak -->
<cfparam name="URL.FirstName" default="">
<cfparam name=
"FORM.FirstName" default="#URL.FirstName#">
<cfparam name=
"URL.LastName" default="">
<cfparam name=
"FORM.LastName" default="#URL.LastName#">

Like I originally said, there are multiple ways program almost any task -- this is one way. Is it "the best?" -- I doubt it, but it's the best that I have found and it works for me. Hope this helps someone…


Date added: Mon. November 3, 2003
Posted by: Steve Sommers | Views: 14767 | Tested Platforms: CF4,CF5,CFMX | Difficulty: Intermediate
Categories Listed: Forms

HostMySite.Com is sponsoring this tutorial, please visit their site today!
This tutorial is sponsored by HostMySite.Com - ColdFusion Hosting

Please rate this tutorial:
5 Stars 4 Stars 3 Stars 2 Stars 1 Stars
Comments on this tutorial
Read previous comments on this particular tutorial
Good
Hello

you have mentioned all but you are not specifying that CFINPUT tag text need to be aligned right how to be mentioned

venu
Posted by: venu
Posted on: 04/24/2004 06:37 AM
I'm not sure?
I'm sorry; I'm not sure what you mean by "not specifying that CFINPUT tag text need to be aligned right how to be mentioned"?

If you are meaning that the TD tag for the CFINPUT do not include the ALIGN property, this was intentional. I prefer my headings to be as close to the input fields as possible while maintaining graphic appeal. If this is not what you meant, please ask again...
Posted by: Steve Sommers
Posted on: 05/21/2004 12:49 PM
Validate and send Where
All this I great. But where is the data going? Database, email? Can you enlighten is on this?
Posted by: Tony
Posted on: 07/21/2004 03:31 PM
Send where
The example is more on how to handle data entry and data validation. What is done with the data is completely up to you. Simply insert you code to store the data in a database or send an e-mail in the block with the following comment:

<!—
ADD YOUR CODE HERE TO PROCESS THE DATA, IF ANYTHING
FAILS THEN SET VARIABLES.Msg
-->

Posted by: Steve Sommers
Posted on: 07/21/2004 03:53 PM
Radio Button Validation
I have generated a form which works fine, but now at the point of determining, "how the user will break the form?" The majority of the areas in the form I have covered, except a set of three radio buttons. I could set a button and hope that the user looks at the buttons and sets the correct one for their circumstances, but I know Murphy will pop his head up and things will not go correctly.

What I prefer is to set no radio buttons and if the user forgets to set one pop a message up telling them to select one. Only problem I am not smart enough to determine how to code that, or adapt some coding examples I have seen to my situation.

Have any suggestions?

Chuck
Posted by: chuck
Posted on: 07/26/2004 04:25 PM
Radio Button Validation
You don't have to default the radio button but you still need to validate the value server side using something the following:

<cfparam name="FORM.MyRadioButton" default="">
...
<cfif FORM.MyRadioButton is "">
<cfabort message="ENTRY ERROR: You must select a value for MyRadioButton">
</cfif>

I would also add a JavaScript check also just to give more immediate feedback if a value is not selected.

Posted by: Steve
Posted on: 07/26/2004 08:49 PM
fantastic
I'm fairly new to all this (you've been programming almost as long as I've been alive) and I cringed when a client's host rejected PHP, but your tutorial helped me IMMENSELY and, believe me, I went through MANY before I found myself here.

Thank you for posting :)

-HB
http://www.infornographer.com
Posted by: HB
Posted on: 11/02/2006 04:39 PM
Thank you!
Thank you for the kind words. I wrote this tutorial three years ago and it seems like forever in my mind. In rereading it, I wish I had proofed the grammar better. Just to let you know, I still use this technique regularly.

If you stick with ColdFusion, I urge you and anyone else reading this to look at FuseBox. It incorporates a technique similar to this but it gives you many additional advantages, some of the biggest being maintenance and supportability.

Again, thank you and good luck.

Posted by: Steve
Posted on: 12/19/2006 12:46 PM
Super tutuorial
Great tutorial, but one this is odd to me. Perhaps it is a matter of what ColdFusion Server you are using (I am under CF 6.1) but when you specify the cfinput tag with a reuired field or another validation method it never goes to display the in-page error message - because it shows a javascript pop-up message (as defined in the cfiput) instead. I was wondering if you did this intentionally or has the implemntation of the cfform/cfinput changed since then? Thanks!
Posted by: Byron
Posted on: 08/05/2007 05:44 AM
Post a new comment on this tutorial
post a new comment on this particular tutorial
Your Name:
Your Email:
Comment Title:
Comments:
Key Phrase:
 
Skyscrapper Banner Advertisement
Daily Razor - ColdFusion Hosting

You are 1 of 761 active sessions! | Privacy | Company
Copyright © 2002 EasyCFM.Com, LLC. (Easy ColdFusion Tutorials) All Rights Reserved
All other trademarks and copyrights are the property of their respective holders.
ColdFusion Hosting ColdFusion Hosting
ADD TO:
Blink
Del.icio.us
Digg
Furl
Google
Simpy
Spurl
Y! MyWeb