By: Doug Hyde

Rapidly deploy form submission, By Doug Hyde (dhyde1@magma.ca)

Have you ever wanted to have a quick way to process just about any form in coldfusion? Whether it is by direct submission of a form by submit or through AJAX, you can apply some simple standards to your database and to your form elements, then this tutorial makes it easy for you to develop and deploy forms in your application rapidly.

Note, some developers will frown on it because it does not draw on stored procedures where speed can be gained in your application, but sometimes you just want to get it working without writing a lot of code. As my role is commonly to build prototypes, I have found coding forms to be a tedious and repetitive task, and I often leave the task to a more hard core development team. For me, the approach set out below cuts the effort to deploy a simple application in half. And because you aren't writing a separate set of code to process every form, it keeps your code efficient. It also allows you to do server side verification of data before submitting it to the database.

Note to use this template, you must adopt or create the following standards; all fields in the database that need to be qualified or verified are made distinct in this regard by the first three characters of the column name - eg for text values, the name is txtColumnName; for numeric or integer values, numValue or intValue define them as such. You can develop your own standard to help improve security. In addition, table names must begin with a three letter extension, such as tbl or other extension as defined by you in the configuration at the top.

On the form, each of your form elements on the submitting form must be made up of three elements separated by a '$' sign (1) the table name where the form element will be stored, without the extension (you can use whatever you wish, though for this tutorial, "table" is used), (2) the full column name in the database, (3) the primary key if it is an update, or the values "0" or "new" if you need insert. For example, a form element named ‘user$txtCompanyName_1$102' will update the table, and a form element named 'user$txtCompanyName_1$new' will insert a new record. By using a “$” in the name of the form element, coldfusion can parse the name as a list, allowing you to get information about which table, which column in the table, and the unique identifier. For example,

<cfset targettable = listfirst(‘user$txtCompanyName_1$102’,’$’)>
<cfset column = listgetat(‘user$txtCompanyName_1$102’,2,’$’)>
<cfset uniqueID = listlast(‘user$txtCompanyName_1$102’,’$’)>

Once you determine that the target table is “user” you can append your unique table extension to the front of this new variable as follows:

<cfset tableextension = ‘tbl’>
<cfset table = tableextension&targettable>

To make the process_form.cfm work, one form element must be inserted for the primary key of each table that will be updated. The element must identify the primary key in the format as 'company$primarykeyname$ID'. Finally, in some cases, you may need to process form elements uniquely, using a separate template or code. If this is the case, the form element (input or textarea) values must include "out$" as the beginning of every name, for example "out$newselect" – these form values are not processed by listing 2 below.

To show you how this will work, let’s develop a simple form using the standards above, just to show you how simple it can be. We will call the form “simple_form.cfm” and the template that processes it “process_form.cfm”.

Listing 1: Creating a simple form

For our simple form, create an new template and save it as “simple_form.cfm”. The form will be used to allow the user to update their contact information; we will assume the user has already logged in, and has an active session stored as a “session” variable. We are going to assume, for the purposes of the tutorial, that the database includes information about the user is stored in a table named tbluser. Note the declaration the names of the form fields

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--- First, we query the database for the user information --->
<CFQUERY NAME="getUserInfo" DATASOURCE="#datasource#">
    SELECT a.txtFIrstName, a.txtLastName, a.txtPhoneNumber
    FROM tbluser a
    WHERE a.intUser = #session.intUser#
</CFQUERY>

<!---now we create the form--->
<head>
    <title>
Update User Information</title>
    <meta http-equiv=
"Content-Type" content="text/html; charset=iso-8859-1">
    <cfset title= "User Information">
    <cfparam name=
"Process" default="">
    <cfparam name=
"close" default="no">

    <!---once we have submitted the form, it is processed here --->
    <cfif process is "update">
        <cfinclude template=
"process_form.cfm">
    </cfif>
</head>
<body>
<!---note, we will use cfform to allow client side validation--->
<cfform name="addedit" method="post" action=”simple_form.cfm”>
    <!---declare the unique identifier for the record, if not a new record; for new records, this entry is not needed, and all form elements should be named with “new” at the end. --->
    <input type="hidden" name="user$intUser$ID" VALUE="1">

    <table cellspacing="0" cellpadding="0" border="0" width="640">
        <tr>
            <td colspan=
"2"><h2>User Contact Information</h2></td>
        </tr>    
        <tr>
            <td>
First Name:</td>
            <td>
<cfinput type="text" name="user$txtfirstname$#getuserinfo.intuser#" value="#getuserinfo.txtfirstname#" size="25" required="yes"></td>
        </tr>
        <tr>
            <td>
Last Name:</td>
            <td>
<cfinput type="text" name="user$txtlastname$#getuserinfo.intuser#" value="#getuserinfo.txtlastname#" size="25" required="yes"></td>
        </tr>
        <tr>
            <td>
Phone Number:</td>
            <td>
<cfinput type="text" name="user$txtphonenumber$#getuserinfo.intuser#" value="#getuserinfo.txtworkpostalcode#" size="25" validate="telephone"></td>
        </tr>
    </table>

</cfform>
</body>
</html>

Listing 2: Template to process all forms.

Now that we have the form built, let’s build the template to process the form, in fact to process any form with elements named using our conventions. Note, this template can be used to update very complex form, for example, where you create an array of form elements, or where you include form elements related to a number of tables, not just one (tbluser) as set out in our example above. It is built on the notion that form elements are sent as a comma-delimited list of values. In some cases, where you need for whatever reason to process form elements outside of the listing below, naming the form element with “out” it is not processed.

<!---configuration to allow your standards to be applied, and to allow submission to multiple datasources registered in coldfusion administrator--->
<cfparam name="tblextension" default="tbl">
<cfparam name=
"datatarget" default="#datasource#">
<cfparam name=
"FieldNames" default="">
<!---we need to create placeholders for all the tables and records in the list of form fields--->
<cfset tablelist = "">
<cfset recordlist =
"">

<cfoutput>
    <!---begin processing the fields here; we are going to loop through all form elements that have been submitted--->
    <cfloop list="#FieldNames#" index="a">

        <!---first, we need to get a list of all table names (note for the simple_form.cfm, there is only one, but there could be many)--->
        <cfset candidate = listfirst(a,'$')>
        <cfif candidate
neq 'out'>
            <cfif listfindnocase(tablelist,candidate)
is 0>
                <cfset tablelist = listappend(tablelist,candidate)>
            </cfif>

            <!---get names and values of primary keys--->
            <cfset intvalue = listgetat(a,3,'$')>
            <cfif intvalue
is 'ID'>
                <cfset
'#candidate#_ID' = listgetat(a,2,'$')>
            </cfif>
        </cfif>
    </cfloop>

    <!---now loop back through all form elements to determine whether they are valid, but do so by table--->
    <cfloop list="#tablelist#" index="a">

        <!---get all unique records for each table--->
        <cfloop list="#FieldNames#" index="element">
            <!---process elements from one table--->
            <cfif listfirst(element,'$') is a>
                <!---get unique key values--->
                <cfset intvalue = listgetat(element,3,'$')>
                <cfif intvalue
is not 'ID'>
                    <cfif listfindnocase(recordlist,intvalue)
is 0>
                        <cfset recordlist = listappend(recordlist,intvalue)>
                    </cfif>
                </cfif>
            </cfif>
        </cfloop>

        <!---now loop through the records--->
        <cfloop list="#recordlist#" index="r">
            <cfset fieldsfound =
"">
            <!---loop through fields--->
                <cfloop list="#FieldNames#" index="element">
                    <cfif element
does not contain "out">
                        <cfset tblname = listfirst(element,
'$')>
                        <cfset intvalue = listgetat(element,3,
'$')>

                        <cfif tblname is a and intvalue is r>
                            <cfset fieldname = listgetat(element,2,
'$')>
                            <CFIF IsDefined(
"#element#")>
                                <!---make sure the value passed is acceptable for the field type--->
                                <CFSWITCH EXPRESSION="#Left(fieldname,3)#">
                                    <CFCASE VALUE=
"dat">
                                        <!---Make sure value is a date--->
                                        <CFIF IsDate(Evaluate(element))>
                                            <CFSET fieldsfound = ListAppend(fieldsfound,element)>
                                        </CFIF>
                                    </CFCASE>
                                    <CFCASE VALUE=
"sin">
                                        <!---Make sure value is a number--->
                                        <CFIF IsNumeric(Evaluate(element))>
                                            <CFSET fieldsfound = ListAppend(fieldsfound,element)>
                                        </CFIF>
                                    </CFCASE>
                                    <CFCASE VALUE=
"txt">
                                        <CFIF Evaluate(element)
IS NOT "">
                                            <CFSET fieldsfound = ListAppend(fieldsfound,element)>
                                        </CFIF>
                                    </CFCASE>
                                    <CFCASE VALUE=
"mem">
                                        <CFIF Evaluate(element)
IS NOT "">
                                            <CFSET fieldsfound = ListAppend(fieldsfound,element)>
                                        </CFIF>
                                    </CFCASE>
                                    <CFDEFAULTCASE>
                                        <CFIF Evaluate(element)
IS NOT "">
                                            <CFSET fieldsfound = ListAppend(fieldsfound,element)>
                                        </CFIF>
                                    </CFDEFAULTCASE>
                            </CFSWITCH>
                        </CFIF>
                    </cfif>
                </cfif>
            </cfloop>

            <cfset session.fieldsfound = fieldsfound>

    &nb

About This Tutorial
Author: Doug Hyde
Skill Level: Intermediate 
 
 
 
Platforms Tested: CF5,CFMX,BlueDragon
Total Views: 80,661
Submission Date: March 22, 2007
Last Update Date: June 05, 2009
All Tutorials By This Autor: 2
Discuss This Tutorial
Advertisement

Sponsored By...
Mobile App Development (IOS, Android, Cordova, Phonegap, Objective-C, Java) - Austin, Texas Mobile Apps - Touch512, LLC.