One of the most common tasks for online interactive web development is form validation. There are an almost unlimited number of ways to approach this problem. In general there are 4 general ways to handle the problem.

  1. CFFORM - Lets ColdFusion generate the javascript necessary to validate your data.
  2. Custom JavaScript - You create your own functions to validate your data.
  3. Built-In CF Server-side - Uses hidden form fields like "name_required" or "enroll_date" etc.
  4. Custom Server side - Write your own custom validation
This set of tags fits into the last category. These tags provide a solution if you have the following requirements:
  1. Javascript can't be used (or it's not preferred).
  2. You need to provide both standardized and custom validation in the same solution.
  3. Data that is entered on the form page must persist after the page has been submitted.
This solution uses session variables (in the demo, a structure is used) to save all data before validation, so all entries are re-populated if the user enters invalid data.

The validation tags consist of the following:
  1. error_codes.cfm - custom tag used for adding and displaying error messages.
  2. udf_validate_form.cfm - contains all of the functions required for validation. The system takes advantage of the large library of User-Defined Functions available on cflib.org. UDF's are supported only on CF5 and above, so this solution will NOT work on anything below CF5. The benefit of this is that anytime you need a new type of validation, you will probably be able to find it on cflib.org.
  3. validate_form.cfm - custom tag that is called with the value to validate, along with the validation rules.
The other pages used in this demo are index.cfm (the page with the form on it) and validate_me.cfm (the action page for index.cfm).

The general flow of the validation process is this:

  1. Declare CFPARAM variables for all FORM variables in the SESSION scope. This will create empty string values for all FORM variables until after the form has been submitted. Once the FORM has been submitted, each value will be replaced with the value from the FORM.
  2. Call <cf_error_codes> before the form. On the first pass, this tag will display nothing. If any errors are found after the form has been submitted, they will be printed.
  3. Display the FORM.
  4. On the action page, set all the SESSION variables with the data from the FORM.
  5. Call <cf_validate_form> for each value you need to validate.
  6. If errors are found, the page will redirect to the form page. If not, the process can continue.

<!--- start index.cfm --->

<cflock timeout="5" throwontimeout="yes" type="EXCLUSIVE" scope="SESSION">
   
<!-- option to delete the structure that holds registration information -->
    <cfif structkeyexists(URL,
"reset")>
        <cfset structdelete(session,
"str_registration")>
    </cfif>
   
<!--- create default structure so it will be always be defined --->
    <cfparam name=
"session.str_registration" default="">
    <cfif not isstruct(session.str_registration)>
        <cfscript> 
           
/* if the structure isn't populated, create default blank values */
           
session.str_registration = structnew();
            session.str_registration.first_nm = "";
            session.str_registration.last_nm = "";
            session.str_registration.email = "";
            session.str_registration.zip = "";
            session.str_registration.number = ""
        </cfscript>
    </cfif>
   
<!--- copy the session variable to the request scope so we don't have to lock the values displayed in the form --->
    <cfset request.str_registration = session.str_registration>
</cflock>


<!--- On the first pass, this tag will display nothing. If any errors are found 
        after the form has been submitted, they will be printed here. --->

<cf_error_codes>
<form action="validate_me.cfm" method="POST" name="validate">
  <cfoutput>
  <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" summary="This table contains a form for collecting registration information including first name, last name, email address, and zip code."
    <TR>
        <TD width=
"175"><label for="registration_first_nm">First Name</label></TD>
        <TD valign=
"top">
            <span style="color:red;">*</span>
            <input type="Text" name="registration_first_nm" value="#request.str_registration.first_nm#" size="30" id="registration_first_nm">
        </TD>
    </TR>
    <TR>
        <TD width=
"175"><label for="registration_last_nm">Last Name</label></TD>
        <TD valign=
"top">
            <span style="color:red;">*</span>
            <input id="registration_last_nm" type="Text" name="registration_last_nm" value="#request.str_registration.last_nm#" size="30">
        </TD>
    </TR>
    <TR>
        <TD width=
"175"><label for="registration_email">Email</label></TD>
        <TD valign=
"top">
            <span style="color:red;">*</span>
            <input id="registration_email" type="Text" name="registration_email" value="#request.str_registration.email#" size="30">
        </TD>
    </TR>
    <TR>
        <TD width=
"175"><label for="registration_zip">US Zip Code</label></TD>
        <TD valign=
"top">
            <span style="color:red;">*</span>
            <input id="registration_zip" type="Text" name="registration_zip" value="#request.str_registration.zip#" size="30">
        </TD>
    </TR>
    <TR>
        <TD width=
"175"><label for="registration_number">Enter a number between 5 and 10</label></TD>
        <TD valign=
"top">
            <span style="color:red;">*</span>
            <input id="registration_number" type="Text" name="registration_number" value="#request.str_registration.number#"     size="5">
        </TD>
    </TR> 
</table>

<br><input type="submit" id="submit" value="Validate Information">
</cfoutput>
</form>

</body>
</html>

<!--- end index.cfm --->


<!--- begin validate_me.cfm --->

<cfif structkeyexists(FORM,"fieldnames")>
    <cflock timeout=
"5" throwontimeout="No" type="EXCLUSIVE" scope="SESSION">
        <!--- assign the FORM values to the session structure. this will allow the form.cfm page to maintain the variables that were previously entered. --->
        <cfscript> 
            session.str_registration.first_nm = FORM.registration_first_nm;
            session.str_registration.last_nm = FORM.registration_last_nm;
            session.str_registration.email = FORM.registration_email;
            session.str_registration.zip = FORM.registration_zip;
            session.str_registration.number = FORM.registration_number;
            
            /* copy the structure to request scope */
            request.str_registration = session.str_registration; 
        </cfscript>
    </cflock>


    <!--- reset the error codes array to we start from a clean slate every time we validate ---> 
    <cf_error_codes method="delete">

    <!--- validate the all fields --->
    <cf_validate_form var="#request.str_registration.first_nm#" 
            validate=
"required"
            message=
"Please enter your First Name.">
    <cf_validate_form var=
"#request.str_registration.last_nm#" 
            validate=
"required"
            message=
"Please enter your Last Name."
    <cf_validate_form var=
"#request.str_registration.email#" 
            validate=
"required,email"
            message=
"Please enter a valid Email Address.">
    <cf_validate_form var=
"#request.str_registration.zip#" 
            validate=
"required,uszip"
            message=
"Please enter a valid US Zip Code.">
    <cf_validate_form var=
"#request.str_registration.number#" 
            validate=
"required,range(5-10)"
            message=
"Please enter a number between 5 and 10.">
    <!--- You can also add your own special validation that might not be useful to include in the validate_form custom tag ---> 
    <cfif request.str_registration.first_nm contains "pablo">
        <cf_error_codes method=
"add" message="You are a CF_WIZARD. Use another name to continue."
    </cfif>


    <!--- check if any errors - if any errors were found, re-direct back to the form.cfm page --->
    <cf_error_codes method="check" page="index.cfm?action=validateform">
<cfelse>

    <!--- if this page was accessed without the FORM being submitted --->
    <cflocation url="index.cfm">
</cfif>

<!--- All validation was passed, run database or other necessary code here. For now, just display a message --->
<html>
  <head>
    <title>
NM Consulting: Advanced Server-side FORM validation</title>
    <meta http-equiv=
"Content-Type" content="text/html; charset=iso-8859-1">
  </head>

  <body>
    <h3>
Congratulations</h3>
    All data has passed validation tests.
    <br>
    <br>

    Want to <a href="index.cfm?reset=true" title="try again">try again</a>?

</body>
</html>

<!--- end validate_me.cfm --->


<!--- begin validate_form.cfm --->
<!--- 
    attributes
    var
        -value to be validated
            validate
        -comma delimited list of validation rules. valid rules are:
            [range(x-y),required,numeric,int,SSN,phone,uszip,cazip,ukzip,date,email,money]
        - to add additional rules, add the funtion to udf_validate_form.cfm, and add a cfcase block for the new rule below
    message
        -message to add to session.error_codes if the validation doesn't pass


    Author: Nathan Miller (nathan@nmconsulting.us)
    Version: 1, March 6, 2003 
--->


<cfparam name="attributes.var" default = "">
<cfparam name=
"attributes.validate" default = "">
<cfparam name=
"attributes.message" default = "An error has occurred.">

<cfif attributes.var IS
"" AND attributes.validate IS "">
    <CFEXIT METHOD=
"ExitTag"
</cfif>

<cfset attributes.var = trim(attributes.var)>

<!--- include user defined functions --->
<cfinclude template="udf_validate_form.cfm">

<cfloop list="#attributes.validate#" index="validate_reason">
<cfif validate_reason contains "range(">
    <cfscript>

        begin = 7;
        dash = find("-",validate_reason,1);
        min_num = mid(validate_reason,begin,dash-begin);
        begin_last = len(min_num) + begin + 1;
        end_last = begin_last - len(validate_reason);
        max_num = mid( validate_reason, begin_last, abs(end_last) );
    </cfscript> 

    <cfif min_num GT max_num OR NOT IsNumeric(min_num) OR NOT IsNumeric(max_num)>
        <cfoutput>

        <p>The validation format of <strong>#validate_reason#</strong> is incorrect. 
            The first index #min_num# must be less than the last index #max_num#
            and both values must be numbers.
        </p> 
        </cfoutput> 
    </cfif>


    <!--- validate value vs. rules --->
    <cfif attributes.var LT min_num OR attributes.var GT max_num>
        <cf_error_codes method=
"add" message="#attributes.message#">
        <CFEXIT METHOD=
"ExitTag"
    </cfif>
</cfif>



<cfswitch expression="#validate_reason#">
    <cfcase value=
"required">
       
<!--- must have a length --->
        <cfif len(attributes.var) LT 1>
            <cf_error_codes method=
"add" message="#attributes.message#">
            <CFEXIT METHOD=
"ExitTag"
        </cfif> 
    </cfcase>
    <cfcase value=
"numeric">
        <cfif NOT Isnumeric(attributes.var)>
            <cf_error_codes method=
"add" message="#attributes.message#"
            <CFEXIT METHOD=
"ExitTag"
        </cfif>
    </cfcase> 
    <cfcase value=
"int">
        <cfif NOT (isInt(attributes.var))>
            <cf_error_codes method=
"add" message="#attributes.message#"
            <CFEXIT METHOD="ExitTag"> 
        </cfif> 
    </cfcase>
    <cfcase value=
"ssn">
        <cfif NOT (IsSSN(attributes.var))>
            <cf_error_codes method=
"add" message="#attributes.message#"
      &

About This Tutorial
Author: Nathan Miller
Skill Level: Advanced 
 
 
 
Platforms Tested: CF5,CFMX
Total Views: 56,268
Submission Date: December 15, 2003
Last Update Date: June 05, 2009
All Tutorials By This Autor: 11
Discuss This Tutorial
  • hello nice tutorial ,but one thing ,I have a url variable #url.propertyID# in index.cfm and it send me this error ,Element PROPERTYID is undefined in URL. I tried to resolve this problem by defining the url.propertyID in cfparam But the problem exist Please help me

  • sdfsdfsd

Advertisement

Sponsored By...
Powered By...