Following is a description of one way to tidily implement a TerraForm form in your code. You may prefer a different style, but this is a good starting point.
Create a folder for all the files related to your form. In this folder, create a controller file. This file would be
cfincluded into the template where you want your form to appear. The controller file controls what happens and contains very little code.
Looking at the code below, you can see that the form file is included. It is important to realise that the form markup is used to both generate the empty form and handle validation. So the form markup must be included in the page that handles the submitted form. If the form fails to validate or hasn't been submitted yet, then the form is displayed. If it validates successfully then the form is hidden, the action template is included, and the user is redirected to a "thank you" page.
<cfinclude template="frm_MyForm.cfm"> <cfif Form.MyForm EQ "Valid"> <cfinclude template="act_MyForm.cfm"> <cflocation URL="MyThanksPage.cfm"> </cfif>
Create your form as
<table> <cf_terraform name="MyForm"> <messagesblock> <tr> <td colspan="2"> <messages> </td> </tr> </messagesblock> <tr> <td labelfor="Palindrome"> Your palindrome: </td> <td labelfor="Palindrome"> <cf_terrafield name="Palindrome" caption="your palindrome" datatype="string" required="yes" /> </td> </tr> <tr> <td colspan="2" align="right"> <cf_terrafield name="Submit" format="submit" caption="Push me!" /> </td> </tr> </cf_terraform> </table>
Create your action template as
act_MyForm.cfm. This template will process the valid form. Typically, you might be updating or inserting data into a database table. Here, we are inserting a new row into a SQL Server table:
<cfquery name="AddPalindrome"> SET NOCOUNT ON INSERT INTO Palindromes ( Palindrome ) VALUES ( '#Form.Palindrome#' ) SELECT NewPalindromeID = @@IDENTITY SET NOCOUNT OFF </cfquery> <cfset Client.ID = AddPalindrome.NewPalindromeID>
Create your thanks page as
MyThanksPage.cfm. Once your form has been processed, the visitor will be relocated to this page. They can hit refresh as much as they like here, without the form being resubmitted. If you pass an attribute to this page, you can requery the database to display information specific to the visitor, for example: a reference number or an order summary. If you are displaying confidential information here rather than simply a reference number, it could be possible for a visitor to scan through all the orders by tampering with the attribute in the (this bug is not uncommon on e-commerce Web sites). One solution could be to pass the attribute as a session or client variable as above. Another might be to pass a key along with the ID that must match a value in the record to unlock it.
<p>Thanks for your submission. Your tracking code is <cfoutput>#Client.ID#</cfoutput>.</p>
Adding custom validation
TerraForm provides a range of powerful validation techniques, including automatic datatype validation, ranges, regular expression matching, length ranges, and so forth. However, sometimes form data needs to be validated in a different way. Perhaps you need to compare the contents of two fields, or connect to a database or web service. In these situations, you can supplement TerraForm's validation with custom validation of your own. Any errors generated by your validation will be presented in exactly the same way as other validation, providing a consistent interface.
Create a validation template
<cfif NOT ListFindNoCase(ErrorFieldList, "Palindrome")> <cfset PalindromeForward = REReplace(Form.Palindrome, "[^[:alnum:]]+", "", "ALL")> <cfset PalindromeBackward = Reverse(PalindromeForward)> <cfif PalindromeForward NEQ PalindromeBackward> <cfset ErrorFieldList = ListAppend(ErrorFieldList, "Palindrome")> <cfset ErrorMessageList = ListAppend(ErrorMessageList, "That doesn't seem to be a palindrome. Your palindrome must read the same forwards and backwards! <a target=""_blank"" href=""HTTP://WWW.palindromes.org/"">Help!</a>", RS)> </cfif> </cfif>
This template contains custom validation to test whether a string is a palindrome. It works as follows. First it checks to see if the "Palindrome" field has already generated an error by looking in
ErrorFieldList (the comma-delimited list of invalid fields). If it has (for example if it has been left blank), there's no need to proceed any further. If not, it performs a computation to decide if the string is a palindrome. If not, it adds the field name to
ErrorFieldList, and adds an error message to
-delimited list of error messages -
Chr(30) is predefined for you).
Finally, we need to tell TerraForm to use the custom validation template. In
frm_MyForm.cfm, change the opening TerraForm tag to read:
<cf_terraform name="MyForm" CustomValidationPath="val_MyForm.cfm" >