Archive for January, 2008

Giants 37, Patriots 35

Let me first start this by saying, if these two teams had met 10 times this year, I believe that the Giants would only win 2 out of those 10 games.  Right now, however, they are playing their finest football of the season.  This isn’t a pick that’s analyzing matchups (the Patriots are arguably better than the Giants at every offensive position).  This pick does not use any true logical deduction.  No no, this pick is purely a hunch.  I have a feeling this will be an all time classic Super Bowl.  Much like Super Bowl XXV, with a slight twist - Lawrence Tynes making the game winner as time expires.

Here is a step by step all-in-one guide to installing and configuring Eclipse on Windows to work with ColdFusion 8:

Eclipse Setup

  1. Download Eclipse - Choose the latest version of Eclipse Classic (currently 3.3.1.1 as of 1/28/2008).
  2. Unzip the zip file into a directory of your choosing. Typically, I like to unzip this into C:\apps\. Whatever directory you choose, when you unzip this file the root for the install will be the “eclipse” directory. So, in my case, this would be C:\apps\eclipse.
  3. Open up C:\apps\eclipse\eclipse.exe. This is the executable file for the Eclipse IDE (it is a good idea to create a shortcut to this file on your desktop or toolbar).
  4. When you launch Eclipse, it will ask you what your Workspace will be. This is of more use for Java development than ColdFusion. I typically accept the default here, check the “Use this as the default and do not ask again” checkbox, and click Ok.
  5. You can close the welcome page by clicking on the X next to Welcome. This will show you the default perspective of Java. The next steps entail configuring the CFEclipse plugin for Eclipse to work on your ColdFusion applications.

Configuring CFEclipse

  1. Go to http://www.cfeclipse.org and click on the Download link.
  2. Following these directions, you should be able to easily configure the CFEclipse plugin.
  3. To use the CFEclipse perspective, inside of Eclipse, go to Window -> Open Perspective -> Other. Choose CFEclipse and click OK.
  4. To create a new CFEclipse Project (similar to a Dreamweaver site):
    • Go to File -> New -> Project.
    • In the Select a Wizard dialogue box, expand CFEclipse, click on CFML Project and click next
    • Name the Project (similar to a Dreamweaver site name), and browse to the local/network directory where the project is contained (i.e., C:\ColdFusion8\wwwroot\myapp\).

ColdFusion 8 Extensions

  1. Go to the ColdFusion downloads section of the Adobe website.
  2. Download both the ColdFusion 8 Extensions for Eclipse and the ColdFusion 8 Help Files for Eclipse.  Follow the simple instructions on the page for installing the ColdFusion 8 Help Files.
  3. To install the ColdFusion 8 Extensions for Eclipse:
    1. Go to Help -> Software Updates -> Find and Install
    2. Search for New Features to Install and click Next
    3. Click on new archived site, and find the file that you just downloaded (it’s named: cf8_extensions_for_eclipse.zip).  Click OK.
    4. Make sure that cf8_extensions_for_eclipse.zip is the only one that is checked, and click Finish.
    5. For Select Features to Install, check the box next to cf8_extensions_for_eclipse.zip and click Next.
    6. Accept the License agreement, click Next, then click Finish.  When prompted, click Install All.
    7. Once it is finished installing, you will be prompted to restart Eclipse.  Click Yes.  Eclipse will reboot, and you will be all set.

Congratulations to the New York FOOTBALL Giants !!! NFC Champions !!!

Patriots 45, Chargers 24

This would probably be as monumental of a championship game upset as we would ever see.  That is not going to happen.  New England will win by plenty and move on to destiny…

Giants 17, Packers 15

Again, this just has all the makings of a classic.  The Giants have found their stride and continue to play the role of Cinderella.  The Packers resilience this season has been extremely surprising.  This will go down to the wire, and right now, the Giants are wearing the lucky shoes.

Last Week: 3-1 vs spread, 3-1 outright.

Automatic server side validation in ColdFusion can be an extremely useful feature, particularly when you need to perform a set of rather common validation tasks.

Consider this cfform, with the server side validation code:

1
2
3
4
5
6
7
8
9
10
11
12
<cfform action="myform_action.cfm">
   Name: <cfinput type="text" name="fullName" required="yes"
                  message="Your name is required" validateat="onserver" />
   <br />
   Email: <cfinput type="text" name="emailAddress" required="yes" validate="email"
                  message="You must enter a valid email address" validateat="onserver" />
   <br />
   Confirm Email: <cfinput type="text" name="confirmEmailAddress" required="yes" validate="email"
                  message="You must enter a valid confirmation email address" validateat="onserver" />
   <br />
   <cfinput type="submit" name="save" value="Submit" />
</cfform>

Very simple, very neat. However the problem is with the output:

Default cfform error

This post deals with customizing the output, so that it shows up on the same page as the form, in a typical validation fashion.

We are going to tackle this by utilizing the onError() method of the Application.cfc. First, let’s start out with an extremely basic Application.cfc, to understand what happens when we implement the onError() method.

Consider this first rendition of the Application.cfc:

1
2
3
4
5
6
7
8
9
10
<cfcomponent name="Application">
   <cfset this.name="form_validation_app" />
 
   <cffunction name="onError" returntype="void">
      <cfargument name="exception" required="true" />
      <cfargument name="eventName" type="String" required="true" />
 
      <cfdump var="#exception#">
   </cffunction>
</cfcomponent>

When an automatic validation error is triggered, it is now caught by the onError() method (in fact, all application errors are now captured here). Let’s analyze the output.

Below is the dump of the exception object (internally, it’s actually not a struct), triggered by failing form validation:

Form validation error dump

Let’s analyze each key of this structure:

Detail
This is the exact output we saw on the default validation error page (the ugly grey error). Completely useless to us.
Message
This is the message that we see on the ugly grey error page. We could use this to determine if there is a validation error, however, if future versions of ColdFusion modify this message, our code would need to be updated.
StackTrace
Extremely long, ugly, gives you an idea about how CF is built on top of Java. But, actually, fairly useful. The first entry in the trace is coldfusion.filter.FormValidationException, which is the exception object thrown by ColdFusion when a form validation error occurs. It is highly unlikely that the name of this would ever be modified, so we could test to see if exception.stackTrace contains “coldfusion.filter.FormValidationException”, and trap a validation error using this.
Tag Context
Not applicable here
Type
Type of Application is extremely common, therefore, useless here.
errors
This is a key that is particular to this type of error. It is a bunch of <li> tags, or list items, which could be used in a list to display the error. This will be very useful to us, however, it would have been much more useful had CF provided us with an array of structures, with 1 key representing the name of the field in error, and the other key representing the message (this way our display of messages would be unlimited). However, this will suffice, so we will use it.

Now let’s modify the Application.cfc.

  1. We will trap validation errors, while throwing all other errors up to the next level of error handling (either a site-wide error handler or the ugly grey message).
  2. If we catch a validation error, we need to capture the exception.errors field, and forward the user to the page they came from (we can use cgi.HTTP_REFERER). Since we need to use cflocation to forward the user, we must put exception.errors into a persistent scope - we’ll use the session scope for this and delete the key immediately after we display the errors.
  3. We will also create a method to display these validation errors, right in the Application.cfc (you could certainly put it elsewhere; this is simply for ease of implementation.)
  4. Finally, we need to be able to pre-populate the form, using the submitted data (depending on business rules, the actual population can vary, i.e., we likely won’t populate password fields). To do this, we will simply create another temp session variable, and a function in the application.cfc to access this (and destroy it).

The new Application.cfc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<cfcomponent name="Application">
   <cfset this.name="form_validation_app" />
   <cfset this.sessionManagement = "true" />
 
   <cffunction name="onRequestStart" returntype="boolean">
      <cfargument name="targetPage" type="String" required="true" />
      <!--- Capture this instance of the Application.cfc into the request
      so that other pages can call custom functions on the Application.cfc --->
      <cfset request.app = this />	    
      <cfreturn true />
   </cffunction>
 
   <cffunction name="onSessionStart" returntype="void">
      <cfset session.validationError = "" />
      <cfset session.stFormData = structNew() />
   </cffunction>
 
   <cffunction name="onError" returntype="void">
      <cfargument name="exception" required="true" />
      <cfargument name="eventName" type="String" required="true" />
 
      <cfif isDefined('exception.StackTrace') AND isDefined('exception.errors')
      AND exception.StackTrace contains 'coldfusion.filter.FormValidationException'>
         <cfset session.validationError = exception.errors />
         <cfset session.stFormData = duplicate( form ) />
         <cflocation url="#cgi.HTTP_REFERER#" addtoken="false" />
      <cfelse>
         <cfthrow object="#exception#" />
      </cfif>
   </cffunction>
 
   <cffunction name="displayValidationError" access="public" returntype="void"
               output="true">
      <cfif len( session.validationError )>
         <ul class="validationError">#session.validationError#</ul>
         <cfset session.validationError = "" />
      </cfif>
   </cffunction>
 
   <cffunction name="getStFormData" access="public" returntype="struct">
      <cfset var stRet = duplicate( session.stFormData ) />
      <cfset session.stFormData = structNew() />
 
      <cfreturn stRet />
   </cffunction>
</cfcomponent>

And we now add 2 lines of code to our form page, above the cfform:

<cfset variables.stFormData = request.app.getStFormData() />
<cfoutput>#request.app.displayValidationError()#</cfoutput>

We can now reference variables.stFormData, to prepopulate each of the form fields that need to be prepopulated.

Now, our output upon an error is as follows:

Customized Error Message

We could further extend this now, to even perform custom validation in our action page, by simply using cfthrow (for example, when the email address and confirmation email do not match), and catching this cfthrow inside of our cferror. Of course, I leave that for you to do :)