Form Validation

In this lesson of the ColdFusion tutorial, you will learn...
  1. To understand the basics of the <cfform> tag.
  2. To work with ColdFusion's auto-generated client-side form validation using <cfform>.
  3. To work with ColdFusion's auto-generated server-side form validation using <cfform>.
  4. To work with ColdFusion's auto-generated server-side form validation without <cfform>.
  5. To create input masks.
  6. To write your own server-side form validation code.

<cfform> Basics

The <cfform> tag is used to generate HTML forms. ColdFusion form controls, such as <cfinput>, <cfselect>, and <cftextarea> are used inside of <cfform> to create HTML entry fields. The table below shows <cfform>'s attributes for HTML forms.

Major <cfform> Attributes for HTML Forms
Attribute Description
name form name
action form action
method form method: "post" or "get"
format "html" for HTML forms

Code Sample: FormValidation/Demos/AddEntry-cfform.cfm

<html>
<head>
  <title>Running Log</title>
</head>
<body>

<cfform name="RunningForm" method="post" action="AddEntry-cfform.cfm" format="html">
<table>
<tr>
 <td>Date:</td>
 <td><cfinput type="text" name="date" size="20"></td>
</tr>
<tr>
 <td>Distance:</td>
 <td><cfinput type="text" name="distance" size="20"></td>
</tr>
<tr>
 <td>Time:</td>
 <td><cfinput type="text" name="time" size="20"></td>
</tr>
<tr>
 <td>Comments:</td>
 <td><cftextarea rows="3" cols="40" name="comments"></cftextarea></td>
</tr>
<tr>
 <td colspan="2" align="right">
  <cfinput type="submit" name="Add Entry" value="Add Entry">
 </td>
</tr>
</table>
</cfform>

</body>
</html>
Code Explanation

The generated HTML form code is shown below:

<form name="RunningForm" action="AddEntry-cfform.cfm" 
 method="post" onsubmit="return _CF_checkRunningForm(this)">
<table>
<tr>
 <td>Date:</td>
 <td><input name="date" id="date" type="text" size="20"/></td>
</tr>
<tr>
 <td>Distance:</td>
 <td><input name="distance" id="distance" type="text" size="20"/></td>
</tr>
<tr>
 <td>Time:</td>
 <td><input name="time" id="time" type="text" size="20"/></td>
</tr>
<tr>
 <td>Comments:</td>
 <td><textarea name="comments" rows="3" cols="40" ></textarea></td>
</tr>
<tr>
 <td colspan="2" align="right">
  <input name="Add Entry" id="Add Entry" type="submit"/>
 </td>
</tr>
</table>
</form>
     

As you can see, it is a basic HTML form with nothing too special about it. However, ColdFusion form tags can do some pretty neat things with the right attributes. In this lesson, we'll learn how to use them to validate forms.

Auto-generated Form Validation

Form Validation with <cfform>

Using the <cfform> in place of the <form> tag allows you to take advantage of ColdFusion's auto-generated validation code, which can be run client-side with JavaScript before the form actually submits or server-side after the form submits.

For input fields that you wish to validate in this way, use <cfinput> instead of <input>. To require that a field be filled in, set required="yes" in the <cfinput> tag.

In addition to checking whether or not a field is filled in, you can check that fields conform to specific types of patterns by assigning the appropriate value to the validate attribute of <cfinput> or <cftextarea>.

<cfinput> and <cftextarea> Validate Values
Suffix Description
numeric Numeric. The following special characters are allowed and kept: $ ¤ ¥ £ +.
integer Integer. The following special characters are allowed but stripped: $ ¤ ¥ £ +.
float Float. The following special characters are allowed but stripped: $ ¤ ¥ £ +.
range Value must be within range specified by the value attribute in the format "min=minvalue max=maxvalue". No custom error message is allowed.
date Date/time that ColdFusion can understand. ColdFusion converts the value into ODBC date format (without the time).
time Date/time that ColdFusion can understand. ColdFusion converts the value into ODBC time format (without the date).
usdate U.S. date. Allowed formats: m/d/y, m-d-y , or m.d.y
eurodate European date. Allowed formats: d/m/y, d-m-y, or d.m.y
creditcard Number between 13-16 digits that conforms to the mod10 algorithm. Spaces and dashes are stripped.
SSN Nine-digit Social Security number separated by dashes or spaces.
telephone U.S. telephone number with or without area codes and extensions.
zipcode 5 or 9 digit U.S. ZIP code.
email Valid email address.
URL Valid URL.
boolean Boolean. (Yes, No, True, False, 1, 0)
UUID Universally unique identifier (UUID) that follows the ColdFusion format, xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx, where x is a hexadecimal number.
GUID Unique identifier that follows the Microsoft/DCE format, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is a hexadecimal number.
noblanks Value must contain at least one non-whitespace character. Field must also be specified as required using required.
maxlength Value cannot contain more characters than specified by the maxlength attribute. No custom error message is allowed.
regex Value must match regular expression defined in the pattern attributed.
SubmitOnce Used in submit buttons to prevent a user from submitting a form multiple times by mistake.

The validateat Attribute

The validateat attribute specifies where the form validation should take place. Options are onsubmit (default), onblur, and onserver. The first two options use client-side form validation. The last one uses server-side validation.

Below is an example of how to use <cfform> to validate the running log entry form using client-side form validation.

Code Sample: FormValidation/Demos/AddEntry-onsubmit.cfm

---- Code Omitted ----
<cfform name="RunningForm" method="post" action="#CGI.SCRIPT_NAME#" format="html"> <table> <tr> <td>Date:</td> <td><cfinput type="text" name="date" size="20" required="yes" validate="date" validateat="onsubmit" message="You must enter a valid date."></td> </tr> <tr> <td>Distance:</td> <td><cfinput type="text" name="distance" size="20" required="yes" validate="float" validateat="onsubmit" message="You must enter a valid number for the distance."></td> </tr> <tr> <td>Time:</td> <td><cfinput type="text" name="time" size="20" required="yes" validate="regex" pattern="^\d{1,3}:\d{0,2}$" validateat="onsubmit" message="You must enter a valid time in the format mm:ss."></td> </tr> <tr> <td>Comments:</td> <td><cftextarea rows="3" cols="40" name="comments" required="yes" validate="maxlength" maxlength="50" validateat="onsubmit" message="The comment must be between 1 and 50 characters."></cftextarea></td> </tr> <tr> <td colspan="2" align="right"> <cfinput type="submit" name="AddEntry" value="Add Entry"> </td> </tr> </table> </cfform> </body> </html>
Code Explanation

The form checks for the following:

  1. The date is filled in and is a valid date.
  2. The distance is filled in and is a valid float.
  3. The time is filled in and corresponds to a specified regular expression. (Note this is a time in minutes and seconds (mm:ss), not a time of day, so we don't check to see if it is a valid time.)
  4. The comments field is filled in.

If the form is submitted with errors, the following alert will pop up:

Below is an example of how to use <cfform> to validate the running log entry form using server-side form validation. The only change is the value of the validateat attribute.

Code Sample: FormValidation/Demos/AddEntry-onserver.cfm

---- Code Omitted ----
<cfform name="RunningForm" method="post" action="#CGI.SCRIPT_NAME#" format="html"> <table> <tr> <td>Date:</td> <td><cfinput type="text" name="date" size="20" required="yes" validate="date" validateat="onserver" message="You must enter a valid date."></td> </tr> <tr> <td>Distance:</td> <td><cfinput type="text" name="distance" size="20" required="yes" validate="float" validateat="onserver" message="You must enter a valid number for the distance."></td> </tr> <tr> <td>Time:</td> <td><cfinput type="text" name="time" size="20" required="yes" validate="regex" pattern="^\d{1,3}:\d{0,2}$" validateat="onserver" message="You must enter a valid time in the format mm:ss."></td> </tr> <tr> <td>Comments:</td> <td><cftextarea rows="3" cols="40" name="comments" required="yes" validate="maxlength" maxlength="50" validateat="onserver" message="The comment must be between 1 and 50 characters."></cftextarea></td> </tr> <tr> <td colspan="2" align="right"> <cfinput type="submit" name="AddEntry" value="Add Entry"> </td> </tr> </table> </cfform> </body> </html>
Code Explanation

The form makes the same checks as we saw with the client-side validation, but is validated server-side.

If the form is submitted with errors, the page will display as follows:

Although it is possible to customize this error template, you do not have as much control over the look and feel of the page as you would if you wrote the form validation code yourself.

Behind the Curtain of Server-Side Validation

What's happening behind the curtain here? The <cfform> tag and its friends (<cfinput>, <cfselect>, etc.) are performing a little magic by auto-generating standard HTML form controls. For each piece of validation, hidden fields are added that ColdFusion later uses to know what type of validation to perform. The developer is also able to add these hidden fields directly, which is useful when not using <cfform>. In older versions of ColdFusion (MX 6 and earlier), this was the only way to get ColdFusion to auto-generate server-side validation. This is discussed in the next section.

Server-Side Validation without <cfform>

Through the use of hidden <input> fields in a form, you can get ColdFusion to do some basic server-side form validation for you. The name of the hidden fields must be the same name as the field to be validated followed by an underscore (_) followed by a suffix, which indicates the type of validation. Starting with ColdFusion MX 7, suffixes begin with "cfform"; however, for the validation types that were supported in older versions, the old suffix will still work.

ColdFusion returns the value of the hidden field as the error message.

The table below describes the hidden fields suffixes.

Hidden Field Form Validation Suffixes
Suffix Old Suffix Description
_cfformrequired _required Field must be filled out or selected. If this is not set, then the field will not be required, even if other validation rules are set.
_cfformnumeric n/a Numeric. The following special characters are allowed: $ ¤ ¥ £ + and kept.
_cfforminteger _integer Integer. The following special characters are allowed: $ ¤ ¥ £ + but stripped.
_cfformfloat _float Float. The following special characters are allowed: $ ¤ ¥ £ + but stripped.
_cfformrange _range Value must be within range specified by the value attribute in the format "min=minvalue max=maxvalue". No custom error message is allowed.
_cfformdate _date Date/time that ColdFusion can understand. ColdFusion converts the value into ODBC date format (without the time).
_cfformtime _time Date/time that ColdFusion can understand. ColdFusion converts the value into ODBC time format (without the date).
_cfformusdate n/a U.S. date. Allowed formats: m/d/y, m-d-y , or m.d.y
_cfformeurodate _eurodate European date. Allowed formats: d/m/y, d-m-y, or d.m.y
_cfformcreditcard n/a Number between 13-16 digits that conforms to the mod10 algorithm. Spaces and dashes are stripped.
_cfformSSN n/a Nine-digit Social Security number separated by dashes or spaces.
_cfformtelephone n/a U.S. telephone number with or without area codes and extensions.
_cfformzipcode n/a 5 or 9 digit U.S. ZIP code.
_cfformemail n/a Valid email address.
_cfformURL n/a Valid URL.
_cfformboolean n/a Boolean. (Yes, No, True, False, 1, 0)
_cfformUUID n/a Universally unique identifier (UUID) that follows the ColdFusion format, xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx, where x is a hexadecimal number.
_cfformGUID n/a Unique identifier that follows the Microsoft/DCE format, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is a hexadecimal number.
_cfformnoblanks n/a Value must contain at least one non-whitespace character. Field must also be specified as required using _cfformrequired.
_cfformmaxlength n/a Value cannot contain more characters than specified by the value attribute. No custom error message is allowed.
_cfformregex n/a Value must match regular expression.
Syntax
<input type="text" name="age">
<input type="hidden" name="age_cfforminteger" value="Age must be a
valid integer.">

Below is an example of how to use hidden fields to validate the running log entry form.

Code Sample: FormValidation/Demos/AddEntry-hidden.cfm

---- Code Omitted ----
<form method="post" action="#CGI.SCRIPT_NAME#"> </cfoutput> <input type="hidden" name="submitted" value="true"> <table> <tr> <td>Date:</td> <td><input type="text" name="date" size="20"></td> <input type="hidden" name="date_cfformrequired" value="You must enter a date."> <input type="hidden" name="date_cfformdate" value="The date you entered is not a valid date."> </tr> <tr> <td>Distance:</td> <td><input type="text" name="distance" size="20"></td> <input type="hidden" name="distance_cfformrequired" value="You must enter a distance."> <input type="hidden" name="distance_cfformfloat" value="The distance you entered is not a valid number."> </tr> <tr> <td>Time:</td> <td><input type="text" name="time" size="20"></td> <input type="hidden" name="time_cfformrequired" value="You must enter a time."> <input type="hidden" name="time_cfformregex" value="^\d{1,3}:\d{0,2}$"> </tr> <tr> <td>Comments:</td> <td><input type="text" name="comments" size="50"></td> <input type="hidden" name="comments_cfformrequired" value="You must enter a comment."> <input type="hidden" name="comments_cfformmaxlength" value="50"> </tr> <tr> <td colspan="2" align="right"> <input type="submit" name="Add Entry"> </td> </tr> </table> </form> </body> </html>
Code Explanation

The form makes the same checks as before, but using this method, it is possible to have different error messages based on the type of error.

If the form is submitted without filling any of the fields in, a page that looks like the screenshot below will appear:

If the form is completely filled in, but the fields are invalid, the resulting page will look like this:

Although it is possible to customize this error template, you do not have as much control over the look and feel of the page as you would if you wrote the form validation code yourself.

Masking Input Values

The <cfinput> tag has a mask attribute that controls the format the user enters into a text field. The syntax is as follows:

Syntax
<cfinput type="text" name="phone" mask="(999) 999-9999">

The table below shows the mask characters for HTML fields:

Text Input Mask Characters
Character Description
A A-Z (case-insensitive)
X A-Z (case-insensitive) or 0-9
9 0-9
? Any character
Other Characters Inserts literal character

The code sample below shows some samples of masking:

Code Sample: FormValidation/Demos/Masks.cfm

<html>
<head>
  <title>Masks</title>
</head>
<body>

<cfform method="post" action="#CGI.SCRIPT_NAME#" format="html">
 Phone: <cfinput type="text" name="phone" mask="(999) 999-9999"><br/>
 SSN: <cfinput type="text" name="ssn" mask="999-99-9999"><br/>
 Course ID: <cfinput type="text" name="ssn" mask="AAA99X"><br/>
 <cfinput type="submit" name="Submit" value="Submit">
</cfform>

</body>
</html>
Code Explanation

Open the page in your browser and enter fields. You will notice that the format of your entry is controlled and that some characters are automatically inserted.

Custom Server-Side Form Validation

Writing your own custom server-side form validation gives you a lot more flexibility and control. Take a look at the following code.

Code Sample: FormValidation/Demos/AddEntry-custom.cfm

<cfparam name="FORM.date" default="">
<cfparam name="FORM.distance" default="">
<cfparam name="FORM.time" default="">
<cfparam name="FORM.comments" default="">

<html>
<head>
  <title>Running Log</title>
  <style>
   .errors {color:red; font-weight:bold}
 .cool {color:black}
  </style>
</head>
<body>
<cfparam name="errors" default="">
<cfif isDefined("FORM.submitted")>
 <cfif NOT isDate(FORM.date)>
  <cfset errors = errors & "<li>The date is invalid.</li>">
  <cfset dateclass="errors">
 </cfif>
 
 <cfif NOT ListLen(FORM.distance," ") EQ 2>
  <cfset errors = errors & "<li>The distance must be in the format <i>num units</i>.</li>">
  <cfset distanceclass="errors">
 <cfelse>
  <cfset intDistance = ListGetAt(FORM.distance,1," ")>
  <cfset units = ListGetAt(FORM.distance,2," ")>
  <cfif NOT isNumeric(intDistance)>
   <cfset errors = errors & "<li>The distance must be in the format <i>num units</i>.</li>">
   <cfset distanceclass="errors">
  </cfif>
 </cfif>
 
 <cfif Len(errors) EQ 0>
  <cfset RunningLogPath = ExpandPath("Logs/RunningLog.txt")>
  <cfset Tab = chr(9)>
  <cfset outputstring = "#FORM.date##Tab##FORM.distance##Tab##FORM.time##Tab##FORM.comments#">
  
  <cffile action="append" file="#RunningLogPath#" output="#outputstring#" addnewline="yes">
  <h1 align="center">Entry added</h1>
  <a href="RunningLog.cfm">Running Log</a>
  
  <!---Clean up variables--->
  <cfset FORM.date="">
  <cfset FORM.distance="">
  <cfset FORM.time="">
  <cfset FORM.comments="">
 </cfif>
</cfif>

<h1 align="center">Add Entry</h1>
<cfoutput>
<form method="post" action="#CGI.SCRIPT_NAME#">
<input type="hidden" name="submitted" value="true">
<table>
<cfparam name="dateclass" default="cool">
<cfparam name="distanceclass" default="cool">
<cfparam name="timeclass" default="cool">
<cfparam name="commentsclass" default="cool">
<cfif Len(errors) GT 0><!---checking for errors--->
 <tr><td colspan="2" style="margin-left:20px">
  <h3>Errors</h3>
  <ul class="errors">
   #errors#
  </ul>
 </td></tr>
</cfif>
<tr>
 <td>Date:</td>
 <td><input type="text" name="date" size="20" value="#FORM.date#" class="#dateclass#"></td>
</tr>
<tr>
 <td>Distance:</td>
 <td><input type="text" name="distance" size="20" value="#FORM.distance#" class="#distanceclass#"></td>
</tr>
<tr>
 <td>Time:</td>
 <td><input type="text" name="time" size="20" value="#FORM.time#" class="#timeclass#"></td>
</tr>
<tr>
 <td>Comments:</td>
 <td><input type="text" name="comments" size="50" value="#FORM.comments#" class="#commentsclass#"></td>
</tr>
---- Code Omitted ----
Code Explanation

This form only validates the first two fields.

  • The date must be a valid date.
  • The distance must be in the format "num units" (e.g, 9 miles).

If the form is submitted without filling any of the fields in, a page that looks like the screenshot below will appear:

The validation is handled as follows:

  1. An errors variable is created using <cfparam> containing an empty string.
  2. When the form is submitted, the fields needing validation are checked one by one. If an error is found, text is appended to the errors variable in the form of an HTML list item and a variable holding the class for that field is set to "errors". That variable is used inside the <input> fields to determine how the field should be displayed.
  3. After each field has been checked, the length of the string held in errors is checked. If it is a zero-length string, that means there are no errors and the entry is added to the log.
  4. Within the HTML form itself, the length of errors is checked again. If it is not a zero-length string, then the error message is output.

IsValid()

The IsValid() function is useful for checking whether a variable or value is of a certain data type or meets pattern, size or length constraints. There are three possible signatures for IsValid().

IsValid(type, value)
isValid("range", value, min, max) 
isValid("regex", value, pattern)

Possible types are the same as those shown in the "<cfinput> and <cftextarea> Validate Values" table at the beginning of this lesson. In addition, the type can be any of the following:

Additional Types for IsValid()
Suffix Description
any Same as IsSimpleValue().
array Same as IsArray().
binary Same as IsBinary().
query Same as IsQuery().
struct Same as IsStruct().

Form Validation Conclusion

Although ColdFusion's auto-generated form validation makes it quick and easy to validate forms, it makes it very difficult to provide a customized user interface for handling errors.

To continue to learn ColdFusion go to the top of this page and click on the next lesson in this ColdFusion Tutorial's Table of Contents.

Use of this website implies agreement to the following:

Copyright Information

All pages and graphics on this Web site are the property of Webucator, Inc. unless otherwise specified.

None of the content on this website may be redistributed or reproduced in any way, shape, or form without written permission from Webucator, Inc.

No Printing or saving of web pages

This content may not be printed or saved. It is for online use only.


Linking to this website

You may link to any of the pages on this website; however, you may not include the content in a frame or iframe without written permission from Webucator, Inc.


Warranties

This website is provided without warranty of any kind. There are no guarantees that use of the site will not be subject to interruptions. All direct or indirect risk related to use of the site is borne entirely by the user. All code and explanations provided on this site are provided without warranties to correctness, performance, fitness, merchantability, and/or any other warranty (whether expressed or implied).

For individual private use only

You agree not to use this online manual to deliver or receive training. If you are delivering or attending a class that is making use of this online manual, you are in violation of our terms of service. Please report any abuse to courseware@webucator.com. If you would like to deliver or receive training using this manual, please fill out the form at http://www.webucator.com/Contact.cfm.