Using Server-Side Validation


As mentioned earlier, server-side validation involves adding code to your application that performs form field validation after the form is submitted. In ColdFusion this usually is achieved with a series of <cfif> statements that check each field's value and data types. If any validation steps fail, processing can be terminated with the <cfabort> function, or the user can be redirected to another page (maybe the form itself) using <cflocation>.

Using Manual Server-Side Validation

The code shown in Listing 13.1 is a simple login prompt used to gain access to an intranet site. The file (which you should save as login1.cfm in a new directory named 13) prompts for a user ID and password. HTML's only validation rule, maxlength, is used in both form fields to restrict the number of characters that can be entered. The form itself is shown in Figure 13.1.

Listing 13.1. login1.cfmSimple Login Screen
 <!--- Name:        login1.cfm Author:      Ben Forta (ben@forta.com) Description: Basic server-side validation Created:     12/21/04 ---> <html> <head>   <title>Orange Whip Studios - Intranet</title> </head> <body> <!--- Page header ---> <cfinclude template="header.cfm"> <!--- Login form ---> <form action="process1.cfm" method="post"> <table align="center" bgcolor="orange">   <tr>     <td align="right">       ID:     </td>     <td>       <input type="text"              name="LoginID"              maxlength="5">     </td>   </tr>   <tr>     <td align="right">       Password:     </td>     <td>       <input type="password"              name="LoginPassword"              maxlength="20">     </td>   </tr>   <tr>     <td colspan="2" align="center">       <input type="submit" value="Login">     </td>  </tr> </table> </form> </body> </html> 

Figure 13.1. HTML forms support basic field types, such as text and password boxes.


This particular form gets submitted to a template named process1.cfm (specified in the action attribute). That template is responsible for validating the user input and processing the login only if all the validation rules passed. The validation rules necessary here are:

  • Login ID is required.

  • Login ID must be numeric.

  • Login password is required.

To perform this validation, three <cfif> statements are used, as shown in Listing 13.2.

Listing 13.2. process1.cfmBasic Server-Side Login Validation Code
 <!--- Name:        process1.cfm Author:      Ben Forta (ben@forta.com) Description: Basic server-side validation Created:     12/21/04 ---> <html> <head>   <title>Orange Whip Studios - Intranet</title> </head> <body> <!--- Page header ---> <cfinclude template="header.cfm"> <!--- Make sure LoginID is not empty ---> <cfif Len(Trim(LoginID)) IS 0>  <h1>ERROR! ID can't be left blank!</h1>  <cfabort> </cfif> <!--- Make sure LoginID is a number ---> <cfif IsNumeric(LoginID) IS "No">  <h1>ERROR! Invalid ID specified!</h1>  <cfabort> </cfif> <!--- Make sure LoginPassword is not empty ---> <cfif Len(Trim(LoginPassword)) IS 0>  <h1>ERROR! Password can't be left blank!</h1>  <cfabort> </cfif> <p align="center"> <h1>Intranet</h1> </p> Intranet would go here. </body> </html> 

The first <cfif> checks the length of LoginID after trimming it with the trim() function. The trim() function is necessary to trap space characters that are technically valid characters in a text field but are not valid here. If the Len() function returns 0, an error message is displayed, and the <cfabort> statement halts further processing.

TIP

Checking the length of the trimmed string (to determine whether it's empty) is functionally the same as doing a comparison against an empty string, like this:

 <cfif Trim(LoginID) IS ""> 

The reason I used Len() to get the string length (instead of comparing it to "") is that numeric comparisons are generally processed more quickly than string comparisons. For even greater performance, I could have eliminated the comparison value and used the following:

 <cfif not Len(Trim(LoginID))> 


The second <cfif> statement checks the data type. The IsNumeric() function returns trUE if the passed value was numeric (contained only digits, for example) or FALSE if not. Once again, if the <cfif> check fails, an error is displayed and <cfabort> halts further processing, as shown in Figure 13.2. The third <cfif> checks that a password was specified (and that that the field was not left blank).

Figure 13.2. <cfif> statements can be used to perform validation checks and then display error messages if the checks fail.


This form of validation is the most powerful and flexible of all the validation options available to you. There's no limit to the number of <cfif> statements you can use, and there's no limit to the number of functions or tags you can use within them. You can even perform database operations (perhaps to check that a password matches) and use the results in comparisons.

See Appendix C, "ColdFusion Function Reference," for a complete list of functions that can be used for form field validation. Most of the decision functions begin with is (for example, IsDefined() and IsDate()).


TIP

<cfif> statements can be combined using AND and OR operators if necessary. For example, the first two <cfif> statements shown in Listing 13.2 could be combined to read

 <cfif (Len(Trim(LoginID)) IS 0) OR (NOT IsNumeric(LoginID))> 


Of course, there is a downside to all of this. Managing and maintaining all of those <cfif> statements can get tedious and complex, especially since most of your forms will likely contain more than just two controls, as ours did here.

Using <cfparam> Server-Side Validation

One solution to the proliferation of <cfif> statements in Listing 13.2 is to use the <cfparam> tag (first introduced in Chapter 9, "CFML Basics"). The <cfparam> tag has two distinct functions:

  • Providing default values for variables.

  • Performing field value validation.

The difference is whether or not a default is provided. Look at this example:

 <cfparam name="LoginID"> 

No default value is provided, and so LoginID is required, and if not present an error will be thrown.

By contrast, this next example has a default value:

 <cfparam name="color" default="red"> 

In this example color isn't required, and if not present, the default value of red will be used.

<cfparam> also supports one additional attribute, a type, as seen in this example:

 <cfparam name="LoginID" type="integer"> 

In this example LoginID is required (because no default is specified). In addition, it must be an integer (a number), and if it's something other than an integer an error will be thrown. ColdFusion supports a complete range of validation types, as listed in Table 13.2.

Table 13.2. Supported Validation Types

TYPE

DESCRIPTION

any

Allows any value

array

A ColdFusion array

binary

A binary value

boolean

true (yes, true, or any non-zero number) or false (no, false, or 0)

creditcard

A 13- or 16-digit credit card number that matches the MOD10 algorithm

date

A date and time value (same as time)

email

A well-formatted e-mail address

eurodate

A date value in dd/mm/yy format

float

A numeric value (same as numeric)

guid

A UUID in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

integer

An integer value

numeric

A numeric value (same as float)

query

A ColdFusion query

range

A range of numbers (range must be specified)

regex

A regular expression pattern (same as regular_expression)

regular_expression

A regular expression pattern (same as regex)

social_security_number

A US format social security number (same as ssn)

ssn

A U.S. format Social Security number (same as social_security_number)

string

A string of one or more characters

struct

A ColdFusion structure

telephone

A US format phone number

time

A date and time value (same as date)

url

A file, ftp, http, https, mailto, or news url

usdate

A date value in mm/dd/yy format

uuid

A ColdFusion UUID in the form xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxx

variablename

A string that meets ColdFusion variable naming rules

xml

An XML object or string

zipcode

A U.S. 5- or 5+4-digit ZIP code


Listing 13.3 is an updated version of Listing 13.2, this time replacing the <cfif> statements with <cfparam> tags.

Listing 13.3. process2.cfm<cfparam> Server-Side Validation
 <!--- Name:        process2.cfm Author:      Ben Forta (ben@forta.com) Description: <cfparam> server-side validation Created:     12/21/04 ---> <!--- Form field validation ---> <cfparam name="FORM.LoginID" type="integer"> <cfparam name="FORM.LoginPassword"> <html> <head>   <title>Orange Whip Studios - Intranet</title> </head> <body> <!--- Page header ---> <cfinclude template="header.cfm"> <p align="center"> <h1>Intranet</h1> </p> Intranet would go here. </body> </html> 

The code in Listing 13.3 is much cleaner and simpler than the code in Listing 13.2., yet it accomplishes the same thing. To test this code, modify login1.cfm and change the <form> tag so that action="process2.cfm". TRy submitting the form with errors and you'll see a screen like the one shown in Figure 13.3

Figure 13.3. When using embedded form field validation, ColdFusion automatically displays an error message listing which checks failed.


As you can see, there's a trade-off here. <cfparam> makes validation much simpler, but you lose control over formatting and presentation. <cfif> statements are a lot more work, but you retain total control over ColdFusion processing.

The screen shown in Figure 13.3 is the default ColdFusion error screen. This screen can be changed using the <cferror> tag, which will be introduced in Chapter 19, "Introducing the Web Application Framework."


There is, however, a downside with both forms of server-side validation. If you were to add or rename a field, for example, you'd have to remember to update the destination page (the page to which the fields get submitted, as specified in the <form> action attribute), as well as the form itself. As your forms grow in complexity, so does the likelihood of your forms and their validation rules getting out of sync.

Using Automatic Server-Side Validation

Server-side validation is the safest and most secure form of form field validation, but it can also become a maintenance nightmare. ColdFusion to the rescue!

ColdFusion enables developers to embed basic form validation instructions within an HTML form. These instructions are embedded as hidden form fields. They get sent to the user's browser along with the rest of the form fields, but they aren't displayed to the user. When the user submits the form back to the Web server, however, those hidden fields are submitted tooand ColdFusion can then use them to perform automatic field validation.

These hidden form fields serve as validation rules, and ColdFusion can generate them for you automatically. It does this via some new tags, <cfform> and <cfinput>. But first, an explanation.

As you have already seen, <form>, <input> and related tags are used by browsers to display HTML forms. ColdFusion doesn't process <form> or <input> tags when it sees them in your code (as it did in Listing 13.1). It simply passes them down to the browser. ColdFusion only processes CFML tags (or expressions without blocks to be processed), not HTML tags.

<cfform> is ColdFusion's version of <form>, and <cfinput> is ColdFusion's version of <input>. The tags can be used interchangeably, and this code:

 <form action="process.cfm" method="post">  <input type="text" name="search">  <input type="submit"> </form> 

is functionally identical to:

 <cfform action="process.cfm" method="post">  <cfinput type="text" name="search">  <cfinput type="submit" name="submit"> </cfform> 

When ColdFusion processes the <cfform> tag it simply generates the HTML <form> tag, and when it processes <cfinput> it generates <input>. So why bother doing this? Because these tags essentially intercept the form generation, allowing ColdFusion to insert other code as needed. For example, validation code. For example, look at the following code snippet:

 <cfinput type="password"          name="LoginPassword"          maxlength="20"          required="yes"          message="Password is required!"          validateAt="onServer"> 

This tag accepts a password, just like the <input> seen in Listing 13.1. But unlike the tag in that listing, here a <cfinput> tag is used. And once <input> has been replaced with <cfinput>, additional attributes (that are instructions to ColdFusion) may be introduced. required="yes" tells ColdFusion that the password field is required, message contains the error message to be displayed if validation fails, and validateAt="onServer" instructs ColdFusion to validate the page on the server after form submission. When ColdFusion processes this tag it generates a <input> tag (because Web browsers would have no idea what <cfinput> was anyway), along with other code that it writes for you, hidden form fields that contain validation rules that ColdFusion can process upon form submission.

CAUTION

<cfinput> must be used within <cfform> tags, you can't use <cfinput> with <form>. Doing so will throw an error.


Listing 13.4 contains an updated login screen, this time containing <cfform> and <cfinput> tags providing validation rules.

Listing 13.4. login2.cfmEmbedded Server-Side Validation Rules
 <!--- Name:        login2.cfm Author:      Ben Forta (ben@forta.com) Description: Form field validation demo Created:     12/21/04 ---> <html> <head>   <title>Orange Whip Studios - Intranet</title> </head> <body> <!--- Page header ---> <cfinclude template="header.cfm"> <!--- Login form ---> <cfform action="process2.cfm"> <table align="center" bgcolor="orange">   <tr>     <td align="right">       ID:     </td>     <td>       <cfinput type="text"                name="LoginID"                maxlength="5"                required="yes"                message="A valid numeric ID is required!"                validate="integer"                validateAt="onServer">     </td>   </tr>   <tr>     <td align="right">       Password:     </td>     <td>       <cfinput type="password"                name="LoginPassword"                maxlength="20"                required="yes"                message="Password is required!"                validateAt="onServer">     </td>   </tr>   <tr>     <td colspan="2" align="center">       <cfinput type="submit"                name="submit"                value="Login">     </td>  </tr> </table> </cfform> </body> </html> 

NOTE

When using <cfinput> every form field must have a name, even type="button".


If you were to run this code, it would look exactly as it did before (Figure 13.1). That's because ColdFusion generated the same HTML form code as we did before. So where is the difference? Do a View Source, and you'll see that the form generated by ColdFusion looks like this:

 <form name="CFForm_1" action="process2.cfm"       method="post"       onsubmit="return _CF_checkCFForm_1(this)"> <table align="center" bgcolor="orange">   <tr>     <td align="right">       ID:     </td>     <td>       <input name="LoginID"               type="text" maxlength="5"  />     </td>   </tr>   <tr>     <td align="right">       Password:     </td>     <td>       <input name="LoginPassword"               type="password" maxlength="20"  />     </td>   </tr>   <tr>     <td colspan="2" align="center">       <input name="submit"               type="submit" value="Login" />     </td>  </tr> </table> <input type='hidden' name='LoginID_CFFORMINTEGER'        value='A valid numeric ID is required!'> <input type='hidden' name='LoginID_CFFORMREQUIRED'        value='A valid numeric ID is required!'> <input type='hidden' name='LoginPassword_CFFORMREQUIRED'        value='Password is required!'> </form> 

There is no <cfform> in this code, no <cfinput>, and no closing </cfform>. ColdFusion generated the standard HTML form tags, and also made some other changes:

  • Listing 13.4 had no method specified, but <cfform> knew to automatically set method="post".

  • <cfform>, <cfinput>, and </cfform> were replaced with <form>, <input>, and </form> respectively.

  • Three hidden fields were added to the form, these contain the validation rules that ColdFusion will use when processing the form submission.

  • Other changes were made too, but those relate to client-side validation which we'll get to shortly.

Run login2.cfm and submit the form with missing or invalid values. You'll see an error screen like the one shown in Figure 13.4.

Figure 13.4. Validation errors caught by embedded server-side validation throw a more friendly error message screen.


NOTE

The screen shown in Figure 13.4 is the default validation error screen. This screen too can be changed using the <cferror> tag.


As you can see, the ColdFusion validation rules are simple and effective. And because the validation rules are embedded into the form itself, your forms and their rules are less likely to get out of sync.

NOTE

The validation rules seen here were generated by ColdFusion automatically. If needed, you can embed the hidden validation rules yourself, although you'll seldom have to. In previous versions of ColdFusion this was necessary, as no automatic generation existed.


Of course, when validation errors occur the user will still have to go back to the form to make any corrections. The benefits of embedded validation rules are really only for developers. Embedded validation does nothing to improve the user experiencefor that you need client-side validation.



Macromedia Coldfusion MX 7 Web Application Construction Kit
Macromedia Coldfusion MX 7 Web Application Construction Kit
ISBN: 321223675
EAN: N/A
Year: 2006
Pages: 282

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net