Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
ColdFusion Basics Tutorial
1. COLD FUSION TUTORIAL
ColdFusion Basics
In this lesson of the ColdFusion tutorial, you will learn...
1. How ColdFusion works.
2. The basics of ColdFusion Markup Language (CFML).
3. To write a simple ColdFusion page.
4. To use ColdFusion operators.
5. To pass values from one page to another via the URL.
6. To process a form with ColdFusion.
How ColdFusion Works
ColdFusion MX 7 code is compiled into Java bytecode, making it
extremely portable, flexible and powerful. ColdFusion is made up of two
parts:
1. ColdFusion Application Server
2. ColdFusion Markup Language (CFML)
ColdFusion Application Server
When a user navigates in a browser to a page that ends with a .cfm
extension, the request is sent to a Web server, which directs the request
2. to the ColdFusion Application Server (CFAS).
As shown in the diagram above, the CFAS processes the page,
communicating with the file systems, databases, and email servers as
necessary, and then delivers a web page to the web server to return to
the browser.
ColdFusion Markup Language
The ColdFusion Markup Language (CFML) looks very similar to HTML or
XML in that it is tag-based. A ColdFusion page generally has a mix of
HTML and ColdFusion tags, and may contain other tags as well.
ColdFusion tags can be distinguished from all other tags by their first
two letters - cf (e.g, <cfloop>).
ColdFusion Variables
ColdFusion is weakly typed, meaning that you do not have to specify the
data type that a variable holds. Rather, ColdFusion determines the data
type of a variable at the time the variable is used. A common way to set
a variable is with the <cfset> tag.
3. <cfset firstname = "Paul">
<cfset age = 63>
Variable Names
In ColdFusion, variable names:
• consist of letters, digits, underscores, and dollar signs
• cannot begin with a digit
• are case-insensitive
Variable Prefixes and Scope
There are many different flavors of variables in ColdFusion:
• variables specific to a page
• variables specific to a user's session
• variables specific to an entire application
• etc.
These flavors of variables each have a different scope, which determines
where and how long a variable exists. For example, variables specific to
a user's session are of the Session scope. They exist for the duration of
the session and are accessible on every page that is a part of the
session. Variables specific to a page (i.e, Local variables) are of the
Variables scope.
A prefix is used to specify the scope of a variable. The syntax is shown
below.
Syntax
SCOPE.VariableName
The following table shows several variable scopes and their prefixes.
Prefixes are not required for variables of all scopes. Required prefixes
are in bold.
Scope Prefix Description
Defined and accessible on the current
Local VARIABLES
page only.
CGI CGI Accessible on any page. Contains
4. server environment variables.
Accessible on the current page.
URL URL Contains values passed in on the query
string.
Accessible on the current page.
Form FORM Contains values passed in through a
form.
Accessible on any page. Contains
Cookie COOKIE variables held in cookies on the client
machine.
Accessible on any page. Contains
Client CLIENT variables created using the Client
prefix.
Defined and accessible within a user-
Argument ARGUMENT
defined function or a ColdFusion
s S
Component method.
Prefix Required. Accessible on any
Session SESSION page to a single user for the duration
of a client session.
Prefix Required. Accessible on any
Applicatio APPLICATIO
page to all users until the application is
n N
restarted.
Prefix Required. Accessible on any
Server SERVER page that is delivered from specific
server.
Variables of different scopes can have the same names. For example, a
local variable could have the same name as a form variable. If such a
variable is referred to without a prefix, ColdFusion needs to know which
variable to use. ColdFusion will search through the scopes in the
following order:
1. Arguments
2. Local (Variables)
3. CGI
4. URL
5. Form
6. Cookie
7. Client
5. In general, it is a good idea to include the prefix when referring to
variables as this will help avoid confusion and could make the page
process more quickly as ColdFusion will know exactly where to look for
the variable.
Using <cfoutput>
A ColdFusion page is generally a mixture of CFML tags, HTML tags, and
plain text. ColdFusion ignores any content that is not contained within a
CFML tag. That is, content outside of CFML tags is returned as is to the
browser.
The <cfoutput> tag is used to tell ColdFusion to attempt to evaluate any
variable or expressions contained within pound signs (#). Let's take a
look at an example. You guessed it - "Hello World".
Code Sample: Basics/Demos/HelloWorld.cfm
<cfset VARIABLES.greeting="Hello">
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<cfoutput>#VARIABLES.greeting# World!</cfoutput>
</body>
</html>
Code Explanation
The code isn't very exciting. In fact, ColdFusion doesn't buy us anything
here as we could have just as easily output the code using HTML. There
is nothing dynamic about the script. Let's try something a little more
interesting.
Passing Variables on the URL
A common way to pass values from the browser to the server is by
appending them to the URL as follows:
http://webucator.com/hello.cfm?greet=Hello&person=World
6. The part of the url that follows the question mark is called the query
string. One or more name-value pairs can be passed to the server in this
way. Each name-value pair is separated by an ampersand (&). The
processing page can read these name-value pairs and use them to
determine its response.
The HTML page below shows an example of how these name-value pairs
might be passed.
Code Sample: Basics/Demos/HelloHi.html
<html>
<head>
<title>Preferred Greeting</title>
</head>
<body>
Do you prefer a formal greeting or an informal greeting?
<ul>
<li><a href="HelloHi.cfm?greet=Hello">Formal</a></li>
<li><a href="HelloHi.cfm?greet=Hi">Informal</a></li>
<li><a href="HelloHi.cfm?greet=Howdy">Friendly</a></li>
</ul>
</body>
</html>
Code Sample: Basics/Demos/HelloHi.cfm
<html>
<head>
<title><cfoutput>#URL.greet#</cfoutput> World!</title>
</head>
<body>
<cfoutput>#URL.greet# World!</cfoutput>
</body>
</html>
Code Explanation
The <cfoutput> tags tell ColdFusion to look for variables and
expressions to evaluate. Within <cfoutput> tags, any content not in
pound signs (#) is simply ignored. Another way to write this page would
be to replace the two sets of <cfoutput> tags with an open <cfoutput>
7. tag before the open <html> tag and a close </cfoutput> tag after the
close </html> tag.
Note that <cfoutput> tags, as a general rule, cannot be nested. (see
footnote)
ColdFusion Comments
ColdFusion comments are similar to HTML comments except that they
take three dashes instead of two.
<!-- This is an HTML comment -->
<!--- This is a ColdFusion comment --->
Exercise: Passing Variables via the Query String
Duration: 10 to 20 minutes.
In this exercise, you will write a script that says hello to different people
based on what is passed through the query string.
1. Open Basics/Exercises/HelloWho.html in your editor.
2. Modify HelloWho.html so that each Beatle name is a link passing
the name of that Beatle (Paul, John, George or Ringo) to
HelloWho.cfm.
3. Open Basics/Exercises/HelloWho.cfm in your editor.
4. Modify HelloWho.cfm so that it outputs a greeting based on the link
that is clicked on HelloWho.html.
5. Test your solution in a browser.
Code Sample: Basics/Exercises/HelloWho.html
<html>
<head>
<title>Greeting the Beatles</title>
</head>
<body>
Choose a Beatle to greet.
<ul>
<li><a href="HelloWho.cfm">Paul</a></li>
<li><a href="HelloWho.cfm">John</a></li>
<li><a href="HelloWho.cfm">George</a></li>
<li><a href="HelloWho.cfm">Ringo</a></li>
8. </ul>
</body>
</html>
Code Sample: Basics/Exercises/HelloWho.cfm
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
Change the links so that each Beatle gets a custom greeting (e.g, Howdy
Paul, Hi John, Bye George, Hey Ringo).
Where is the solution?
HTML Forms and ColdFusion Variables
How HTML Forms Work
A very common way to submit data to a web server is through HTML
forms. There are two methods of submitting data through a form: the
get method and the post method. The method used is determined by the
value of the method attribute of the form tag. The default method is get.
Get Method
When the get method is used, data is sent to the server in name-value
pairs as part of the query string. The get method is most commonly
used by search pages and is useful when it is important to be able to
bookmark the resulting page (i.e, the page that is returned after the
form is submitted).
Post Method
When the post method is used, data is sent to the server in name-value
pairs behind the scenes. The two major advantages of the post method
are:
9. 1. The name-value pairs are not visible in the location bar, so
sensitive data such as passwords are not displayed on the screen.
2. Files, such as images and Office documents, can be uploaded via
the form.
The major disadvantage is that the resulting page cannot be
bookmarked.
A Sample HTML Form
The following is a sample HTML form for calculating the time it takes to
run a specified distance at a specified speed.
Code Sample: Basics/Demos/Calculator.html
<html>
<head>
<title>Marathon Time Calculator</title>
</head>
<body>
<h1>Marathon Time Calculator</h1>
<form method="post" action="
ProcessCalculator.cfm">
<table>
<tr>
<td>Your Name:</td>
<td><input name="yourname" type="text"
size="30"></td>
</tr>
<tr>
<td>Your Speed:</td>
<td><input name="yourspeed" type="text"
size="4"></td>
</tr>
11. The above is a simple HTML form and contains no embedded ColdFusion
code. Its action page is ProcessCalculator.cfm, which would contain
ColdFusion code for processing the submitted form.
Exercise: Processing Form Input
Duration: 15 to 25 minutes.
Next we will create a page that processes the form data. Our form entry
page, excalculator- simpleform1.html, is already complete and is
identical to democalculator- simpleform1.html above. Filled out, it would
look like this:
1. Our form entry page, Basics/Exercises/Calculator.html, is already
complete and is identical to Basics/Demos/Calculator.html above.
Filled out, it would look like this:
2. In this exercise, we will create a page that simply outputs the form
entries as a list.
3. Open Basics/Exercises/ProcessCalculator.cfm in your editor.
4. Output the form variables as list items using <cfoutput>.
5. Save your work and test your solution in the browser by navigating
to Basics/Exercises/Calculator.html and submitting the form.
12. Code Sample: Basics/Exercises/ProcessCalculator.cfm
<html>
<head>
<title>Calculator Entries</title>
</head>
<body>
<h1>Calculator Entries</h1>
You have entered:
<ul>
<!---
Add list items that display your name,
your friend's name, your speed,
your friend's speed, and the units.
--->
</ul>
</body>
</html>
Where is the solution?
Built-in Functions
ColdFusion has many built-in functions for performing all sorts of tasks,
such as manipulating strings, formatting data, managing dates and
times, parsing XML, etc.
The syntax of a function is functionname(arguments), where arguments
is a list of zero or more values passed to the function.
Like variables, function names are case-insensitive.
It is impossible (at least for this author) to memorize all the function
names and the parameters that each function takes. So, every
ColdFusion developer should have a good function reference. Following
are few suggestions:
ColdFusion Function References
13. • Dreamweaver's built-in Macromedia CF Function Reference, which
you can get to by pressing shift+F1 or selecting Window >
Reference.
• Macromedia LiveDocs, where the functions are divided neatly into
categories. The URL is http://livedocs.macromedia.com/coldfusion/
7/htmldocs/00000354.htm
• Macromedia ColdFusion MX 7 Web Application Construction Kit by
Ben Forta and Nate Weiss has an excellent function reference in
Appendix C.
We will be looking at many functions throughout this course, but to give
you a feel for what they how they work, here are a few date and time
functions.
Date & Time Functions
Function Description
Returns the current date and time on the
Now()
server.
DateFormat("date"
Formats the date as specified by the mask.
[,"mask"])
TimeFormat("time" Formats the time as specified by the
[,"mask"]) mask.
CreateDate(year, Creates a date/time object with the time
month, day) set to 00:00:00.
Returns true if a string can be converted
IsDate(string)
to a valid date/time object.
DaysInMonth("date
Returns the number of days in a month.
")
The file below shows these functions in practice:
Code Sample: Basics/Demos/DateFunctions.cfm
<html>
<head>
<title>Date Functions</title>
</head>
<body>
<cfset RightNow = Now()>
<cfoutput>
#RightNow#<br />
14. #DateFormat(RightNow)#<br />
#DateFormat(RightNow,"mm/dd/yy")#<br />
#TimeFormat(RightNow)#<br />
#TimeFormat(RightNow,"hh:mm tt")#<br />
#IsDate(RightNow)#<br />
#IsDate("January 31, 2007")#<br />
#IsDate("foo")#<br />
#DaysInMonth(RightNow)#
</cfoutput>
</body>
</html>
Code Explanation
The output is shown below:
And here is another demo showing a friendlier page using Now() and
DateFormat():
Code Sample: Basics/Demos/HelloWorldDate.cfm
<cfset greeting="Hello">
<cfset today = Now()>
<html>
<head>
<title>Hello World!</title>
15. </head>
<body>
<cfoutput>
#greeting#, World!<br>
Today is #DateFormat(Now(),"dddd, mmmm d, yyyy")#.
</cfoutput>
</body>
</html>
Code Explanation
The output is shown below:
Pound Sign Usage
You may notice that no pound signs are used around the Now() function
in the <cfset> tag, while there are pound signs around the
DateFormat() function. The use of pound signs to indicate that a variable
or expression should be evaluated can be a bit confusing. Here are the
rules:
• Use pound signs when the expression to be evaluated is not within
a ColdFusion tag (e.g, <cfoutput>#Now()#</cfoutput>.
• Use pound signs around expressions that are within a ColdFusion
tag ONLY when the expression is also in quotes (e.g, <cfset
greeting = "Hello #person#">).
• With nested functions, use pound signs only around the outermost
function (e.g, <cfoutput>#DateFormat(Now())#</cfoutput>).
16. Examples of Proper and Improper usage of pound signs
Proper Usage
<cfset person = "Paul">
<cfset greeting = "Hello #person#">
<cfoutput>
#greeting#, today is #DateFormat(Now(),"dddd")#.
</cfoutput>
Improper Usage
<!---The improper use is italicized--->
<cfset person = "Paul">
<cfset greeting = "Hello" & #person#>
Improper Usage
<!---The improper use is italicized--->
<cfoutput>
#greeting#, today is #DateFormat(#Now()#,"dddd")#.
</cfoutput>
Arithmetic and String Operators
ColdFusion's arithmetic and string operators are, for the most part,
pretty standard.
Operator Operato
Name Example
Type r
Arithmetic + Addition <cfset c = a + b>
- Subtraction <cfset c = a - b>
* Multiplication <cfset c = a * b>
/ Division <cfset c = a / b>
MOD Modulus <cfset c = a MOD b>
Exponentiatio
^ <cfset c = a^b>
n
Concatenatio <cfset greeting = "Hello"
String &
n & " world!">
Exercise: Performing Calculations
Duration: 20 to 30 minutes.
17. In this exercise, you will modify the calculator processing page to
calculate the time it takes to finish a marathon at certain speeds.
1. Open Basics/Exercises/ProcessCalculator-2.cfm in your editor.
2. Beneath the "Calculate Speeds" heading, set a variable called
Marathon26.2. with the value of
3. Set two more variables, yourmarathontime and
friendmarathontime and assign them values as calculated from the
form input and the Marathon variable.
4. For now we will assume the units are in MPH.
5. Return text to the browser that reads:
John, at 10
mph, you would run a marathon in 2.62 hours.
At 5
mph, Marylin would run a marathon in 5.24 hours
. *Replace the highlighted words with variable values.
6. At the bottom of the page, add a paragraph that reads:
Form processed at 11:30AM on October 23, 2006.
*Replace the bold words with the current time and date from the server.
Code Sample: Basics/Exercises/ProcessCalculator-2.cfm
<html>
<head>
<title>Calculate Speeds</title>
</head>
<body>
<h1>Calculate Speeds</h1>
<!---
Set a variable called Marathon with
the value of 26.2
--->
<!---
Calculate the values for
yourmarathontime and friendmarathontime
--->
<!---
18. Return text to the browser that reads
"John, at 10 mph, you would run a marathon in 2.62 hours.
At 5 mph, Marylin would run a marathon in 5.24 hours."
--->
<!---
Add a paragraph that reads:
Form processed at 11:30AM on February 23, 2007.
--->
</body>
</html>
Return text to the browser that reads:
John, at 10 mph, you would run a marathon in 2 hours and
37 minutes.
At 5 mph, Marylin would run a marathon in 5 hours and 14
minutes.
Hint: you may find it useful to use the Int() function to reformat the
marathon times output to show a whole number (e.g, no decimal point).
You may also find it useful to use modulus (MOD).
Where is the solution?
ColdFusion Basics Conclusion
In this lesson of the ColdFusion tutorial, you have learned how to write a
simple ColdFusion page, to recognize ColdFusion functions, to work with
variables. to pass variables from one page to another via the query
string and to process form data.
Footnotes
<cfoutput> tags can only be nested if the outer <cfoutput> tag uses a
query and a group attribute. This is an advanced application of
<cfoutput> that applies to looping through complex queries.
Flow Control
In this lesson of the ColdFusion tutorial, you will learn...
19. 1. To work with <cfif><cfelseif><cfelse> blocks.
2. To work with <cfswitch><cfcase> blocks.
3. To create a self-processing form page.
4. To use loops in ColdFusion.
5. To set defaults for variables.
6. To use <cflocation> to redirect pages.
Conditional Processing
Conditional processing allows programmers to output different code
based on specific conditions. There are two conditional structures in
ColdFusion <cfif> blocks and <cfswitch> blocks.
If-Else if-Else Blocks
Simple <cfif>
The syntax for a simple <cfif> condition is shown below:
Syntax
<cfif conditions>
Hello World!
</cfif>
In the above code, Hello World will be displayed only if the conditions
are true.
<cfif><cfelse></cfif>
The syntax for a simple <cfif><cfelse> condition is shown below:
Syntax
<cfif conditions>
Hello World!
<cfelse>
Goodbye World!
</cfif>
20. <cfif><cfelseif><cfelse></cfif>
The syntax for a simple <cfif><cfelse><cfelseif> condition is shown
below:
Syntax
<cfif conditions>
Hello World!
<cfelseif conditions>
World, are you there?
<cfelse>
Goodbye World!
</cfif>
There can be an unlimited number of <cfelseif> blocks, but a
maximum of one <cfelse> block.
Switch Blocks
A <cfswitch> statement is similar to a <cfif> statement, except that
it can only check for an equality comparison of a single expression. It
cannot, for example, be used to check if one value is higher than
another.
Syntax
<cfswitch expression="#language#">
<cfcase value="German">
Hallo
</cfcase>
<cfcase value="Spanish">
Hola
</cfcase>
<cfcase value="French">
Bonjour
</cfcase>
<cfdefaultcase>
Hello
</cfdefaultcase>
</cfswitch>
21. Decision and Boolean Operators
ColdFusion use words rather than symbols for its decision and boolean
operators.
Operator
Operator Description
Type
IS
Returns True if the values are
Decision EQ
EQUAL equal.
IS NOT
NEQ Returns True if the values are not
NOT EQUAL equal.
Return True if the value on the
GREATER THAN
GT left is greater than the value on
the right.
Return True if the value on the
LESS THAN
LT right is greater than the value on
the left.
GREATER THAN
Returns True if the value on the
OR EQUAL TO
GTE left is greater than or equal to
GE the value on the right.
LESS THAN OR
Returns True if the value on the
EQUAL TO
LTE right is greater than or equal to
LE the value on the left.
Returns True if the value on the
CONTAINS left contains the value on the
right.
Returns True if the value on the
DOES NOT
CONTAIN left does not contain the value on
the right.
Reverses the value of an
Boolean NOT
argument.
AND Returns True if both arguments
are True.
OR Returns True if either argument
is True.
22. Short-circuiting
ColdFusion stops evaluating a Boolean condition as soon as it knows
the result. For example, when checking to see if "a AND b" is true,
ColdFusion will only look at b if a is true, because if a is false then the
whole expression is also false, regardless of the value of b. Likewise,
when checking to see if "a OR b" is true, ColdFusion will only look at b
if a is false, because if a is true then the whole expression is also true,
regardless of the value of b. This behavior is called short-circuiting.
Condition Examples
Following are some examples of if-else if-else and switch-case
expressions.
Code Sample: FlowControl/Demos/If.cfm
<html>
<head>
<title>If-Else If-Else</title>
</head>
<body>
<cfset Age = 21>
<cfif Age GTE 21>
You can vote and drink!
<cfelseif Age GTE 18>
You can vote, but can't drink.
<cfelse>
You cannot vote or drink.
</cfif>
</body>
</html>
Code Explanation
The file is relatively simple. You can see the different results by
changing the value of Age.
23. Code Sample: FlowControl/Demos/If2.cfm
<html>
<head>
<title>If-Else If-Else - Compound</title>
</head>
<body>
<cfset Age = 21>
<cfset Citizen = false>
<cfif Age GTE 21 AND NOT Citizen>
You can drink but you can't vote!
<cfelseif Age GTE 21>
You can vote and drink!
<cfelseif Age GTE 18 AND Citizen>
You can vote but can't drink!
<cfelse>
You cannot vote or drink.
</cfif>
</body>
</html>
Code Explanation
The example above shows the use of compound if conditions using
boolean operators.
Code Sample: FlowControl/Demos/Switch.cfm
<html>
<head>
<title>Switch-Case</title>
</head>
<body>
<cfset Quantity = 1>
<cfswitch expression="#Quantity#">
<cfcase value="1">
Quantity is 1
</cfcase>
<cfcase value="2">
Quantity is 2
</cfcase>
<cfdefaultcase>
24. Quantity is not 1 or 2
</cfdefaultcase>
</cfswitch>
</body>
</html>
Code Explanation
In many languages, a break is needed to end switch-case processing.
In ColdFusion, this is not the case. As soon as the expression is
matched, that case block code is executed, and the switch-case block
exits.
Redirection Using <cflocation>
The <cflocation> tag is used to redirect the user to a different page.
It is commonly used when a page has been moved or when a user
doesn't have permissions to view a requested page. The syntax is as
follows:
Syntax
<cflocation url="some_url">
For example:
<cflocation url="http://www.webucator.com">
Exercise: Form Validation
Duration: 20 to 30 minutes.
In this exercise, you will modify the calculator processing page so that
it validates the form input. If there are no errors, the page will be
processed. However, if errors are found, the user will be returned to
the form page.
We will also be checking the units to see if the speeds are in mph or
kph.
1. Open FlowControl/Exercises/ProcessCalculator.cfm in your editor.
25. 2. At the very top of the page, write an if condition that checks to
make sure that:
o Neither of the name form fields is empty. (see footnote)
o The speeds entered are numeric. (see footnote)
3. If there are errors, redirect the page back to Calculator.cfm.
Otherwise, continue with the page processing.
4. Define a variable Conversion with the value of .62. (see
footnote)
5. Write an if condition that checks to see if the speeds are in mph
or kph.
o If they are in kph, yourmarathontime and
friendmarathontime will have to be calculated using the
Conversion variable.
6. To test your new page, open
FlowControl/Exercises/Calculator.cfm in your browser and submit
the form.
Code Sample: FlowControl/Exercises/ProcessCalculator.cfm
<!---
Write an if condition that checks to make sure that:
A. Neither of the name form fields is empty.
B. The speeds entered are numeric.
If there are errors, redirect back to the FORM.
Otherwise, continue with the page processing.
--->
<html>
<head>
<title>Calculate Speeds</title>
</head>
<body>
<h1>Calculate Speeds</h1>
<cfset Marathon = 26.2>
<!---
Define a variable Conversion with the value of .62
Write an if condition that checks to see if the speeds
are in mph or kph. If they are in kph, yourmarathontime
and friendmarathontime will have to be calculated
using the Conversion variable.
26. --->
<cfset yourmarathontime = Marathon/FORM.yourspeed>
<cfset friendmarathontime = Marathon/FORM.friendspeed>
<cfset yourhours = Int(yourmarathontime)>
<cfset yourminutes = (yourmarathontime * 60) MOD 60>
<cfset friendhours = Int(friendmarathontime)>
<cfset friendminutes = (friendmarathontime * 60) MOD 60>
<cfoutput>
#FORM.yourname#, at #FORM.yourspeed# #FORM.units#,
you would run a marathon in #yourhours#
hours and #yourminutes# minutes.<br>
At #FORM.friendspeed# #FORM.units#, #FORM.friendname# would
run a marathon in #friendhours# hours
and #friendminutes# minutes.<br>
<p>Form processed at #TimeFormat(Now(),"h:mmtt")# on
#DateFormat(Now(),"mmmm d, yyyy")#.</p>
</cfoutput>
</body>
</html>
Add a basic error message to Calculator.cfm. To do this, you will need
to figure out a way to pass data from ProcessCalculator.cfm to
Calculator.cfm letting it know that there has been an error.
Where is the solution?
isDefined() and <cfparam>
ColdFusion errors when it is asked to try to evaluate an undefined
variable. In some cases, you will want to check to see whether a
variable is defined before trying to evaluate it. You can use the
isDefined() function to check this.
<cfif isDefined("Form.firstname")>
<cfoutput>Hello, #Form.firstname#!</cfoutput>
<cfelse>
Hello, stranger!
</cfif>
27. In other cases, you will want to set a default value for a variable in
case it is accessed before it is explicitly defined. Use <cfparam> for
this.
<cfparam name="Form.firstname" default="stranger">
<cfoutput>Hello, #Form.firstname#!</cfoutput>
In the example above, if Form.firstname is defined before the
<cfparam> tag is reached, then the <cfparam> tag would be ignored.
Otherwise, the default value of stranger would be assigned to
Form.firstname.
Exercise: Self-submitting Form
Duration: 20 to 30 minutes.
In the solution in the last exercise, when there is an error in the form,
all the form data gets lost. This is not ideal. In this exercise, you will
create a page that contains both the form and the processing code.
We use the CGI.SCRIPT_NAME variable, which holds the name of the
current file, as our form action. (see footnote) The page works as
follows:
If the form has not yet been submitted (e.g, on the first visit to the
page), the page outputs the form.
Likewise, if the form has been submitted with errors, the page re-
outputs the form, but keeps any valid values that were entered.
If the form has been submitted with no errors, we'll process the form
data and output the form showing the entered valued.
1. Open FlowControl/Exercises/CalculatorSelfProcess.cfm in your
editor.
2. Much of the code is already written. Review it to make sure you
have a good understanding of what's going on.
o Notice the hidden field named "submitted" You can use this
field to check to see if the form has been submitted.
3. In the comments of the code you will find three tasks to
complete.
28. 4. After completing the tasks, open
FlowControl/Exercises/CalculatorSelfProcess.cfm in your browser
and test your solution.
Code Sample:
FlowControl/Exercises/CalculatorSelfProcess.cfm
<html>
<head>
<title>Marathon Time Calculator</title>
</head>
<body>
<h1>Marathon Time Calculator</h1>
<!---
TASK 1: Write if condition that checks if form was
submitted and that there were no errors.
--->
<cfif WRITE_CONDITION_HERE>
<!---Set Variables--->
<cfset Marathon = 26.2>
<cfset Conversion = .62>
<!---Check units--->
<cfif FORM.units EQ "mph">
<!---Specify which option should be selected--->
<cfset mphselected=" selected">
<cfset kphselected="">
<cfset yourmarathontime = Marathon/FORM.yourspeed>
<cfset friendmarathontime = Marathon/FORM.friendspeed>
<cfelse>
<!---Specify which option should be selected--->
<cfset mphselected="">
<cfset kphselected=" selected">
<cfset yourmarathontime =
Marathon/Conversion/FORM.yourspeed>
<cfset friendmarathontime =
Marathon/Conversion/FORM.friendspeed>
</cfif>
<cfset yourhours = Int(yourmarathontime)>
<cfset yourminutes = (yourmarathontime * 60) MOD 60>
<cfset friendhours = Int(friendmarathontime)>
<cfset friendminutes = (friendmarathontime * 60) MOD 60>
<cfoutput> #FORM.yourname#, at #FORM.yourspeed#
29. #FORM.units#, you would run a marathon in #yourhours# hours
and #yourminutes# minutes.<br>
At #FORM.friendspeed# #FORM.units#, #FORM.friendname# would
run a marathon in #friendhours# hours and #friendminutes#
minutes.<br>
<!---
TASK 2: Write a nested if condition that determines
who will win and by how many minutes. The output to the
browser should read:
"You would beat Marylin by 10.3 minutes." OR
"Marylin would beat you by 10.3 minutes." OR
"Marylin and you would finish at the same time."
--->
<p>Form processed at #TimeFormat(Now(),"h:mmtt")# on
#DateFormat(Now(),"mmmm d, yyyy")#.</p>
</cfoutput>
<cfelseif isDefined("FORM.submitted")>
<!---Checks if form was submitted with errors.--->
<p class="errors">All fields are required.</p>
<p class="errors">Speeds must be numeric.</p>
</cfif>
<!---
TASK 3: Use <cfparam> to create default values
for the Form variables of empty strings.
Replace all instances of "FOO" in the form below
with appropriate values.
You will also need to create default values for
mphselected and kphselected.
--->
<cfoutput>
<form method="post" action="#CGI.SCRIPT_NAME#">
<input type="hidden" name="submitted" value="true">
<table>
<tr>
<td>Your Name:</td>
<td><input name="yourname" value="FOO"
type="text" size="30" maxlength="50"></td>
</tr>
<tr>
<td>Your Speed:</td>
<td> <input name="yourspeed" value="FOO"
type="text" size="4" maxlength="5"> </td>
30. </tr>
<tr valign="top">
<td>Friend's Name:</td>
<td><input name="friendname" value="FOO"
type="text" size="30" maxlength="50"> </td>
</tr>
<tr>
<td>Friend's Speed:</td>
<td> <input name="friendspeed" value="FOO"
type="text" size="4" maxlength="5"> </td>
</tr>
<tr>
<td>Units</td>
<td> <select name="units">
<option value="mph"#mphselected#>MPH</option>
<option value="kph"#kphselected#>KPH</option>
</select> </td>
</tr>
<tr>
<td colspan="2" align="right"> <input type="submit"
value="Calculate"> </td>
</tr>
</table>
</form>
</cfoutput>
</body>
</html>
In your solution, the user probably gets no feedback if he submits the
form with errors. Add an <cfelseif> block to the outer <cfif> block
that checks to see if the form was submitted with errors and gives the
user feedback if it was.
Where is the solution?
Loops
As the name implies, loops are used to loop (or iterate) over code
blocks. The following section shows the syntax for some of the
different types of loops. All of these loops can be found in
FlowControl/Demos/Loops.cfm.
31. Index Loops
An index loop is like a for loop in other languages. It steps through a
process based on some type of count.
<cfloop index="count" from="1" to="5" step="2">
<cfoutput>#count#</cfoutput>
</cfloop>
This loop will output 1 3 5.
Conditional Loops
A conditional loop is like a while loop in other languages. It continues
to iterate through a process as long as the specified condition is true.
<cfset count=1>
<cfloop condition="count LTE 5">
<cfoutput>#count#</cfoutput>
<cfset count = count + 2>
</cfloop>
This loop will output 1 3 5.
List Loops
Lists are simply strings delimited by a specified character or set of
characters. By default, the delimiter is a comma. ColdFusion has
many functions for working with lists.
<cfloop> can be used to iterate through a list, performing some
function with each list item.
<cfset numlist="1,2,3,4,5">
<cfloop index="num" list="#numlist#">
<cfoutput>#num#</cfoutput>
</cfloop>
<cfset beatles="paul john ringo george">
<ul>
<cfloop index="beatle" list="#beatles#" delimiters=" ">
<li><cfoutput>#beatle#</cfoutput></li>
32. </cfloop>
</ul>
The first loop will output 1 2 3 4 5. The second loop will output an
unordered list of the Beatles' names.
Other Types of Loops
<cfloop> can also be used to loop through other types of data,
including queries and structures. Some of these advanced uses of
<cfloop> will be covered later in the course.
<cfbreak>
The <cfbreak> tag is used to break out of loops before they have
finished processing. The syntax is shown below:
<cfloop index="count" from="1" to="5" step="1">
<cfoutput>#count#</cfoutput>
<cfif count GTE 3>
<cfbreak>
</cfif>
</cfloop>
<cfsavecontent>
ColdFusion's <cfsavecontent> tag provides another mechanism for
storing data in a variable. The syntax is as follows:
Syntax
<cfsavecontent variable="var_name">
Variable value
</cfsavecontent>
The great thing about <cfsavecontent> is that it can contain other
ColdFusion code such as conditionals and loops. This makes it easy to
save the results of complicated code as a string of text without
appending to a variable with <cfset>.
The following example illustrates the value of <cfsavecontent>.
34. As you can see from the bolded sections, setting and changing values
with <cfset> can become ugly and <cfsavecontent> provides a much
more elegant solution.
Flow Control Conclusion
In this lesson of the ColdFusion tutorial, you have learned to work
with if-else if-else and switch conditionals, to recognize and use
ColdFusion loops and to redirect pages with <cflocation>.
Footnotes
Simply check to see if the values are equal to an empty string.
You cna use the IsNumeric() function.
There are .62 miles in a kilometer.
According to the HTML specification, the action attribute is required;
however, in practice, if you leave it out the page will submit to itself.
Lists and Arrays
In this lesson of the ColdFusion tutorial, you will learn...
1. To work with lists.
2. To work with one- and two-dimensional arrays.
Up to this point, we have dealt only with variables that store single
values. Lists and arrays are used to store multiple values in a single
variable.
Lists
Lists are really nothing more than strings delimited by a specified
character or set of characters. By default, the delimiter is a comma. A
list can be created using <cfset>.
<cfset numlist="1,2,3,4,5">
The delimiter can be changed to any character or group of characters
<cfset beatles="Paul John George Ringo">
35. To following code shows how to loop through these lists.
Code Sample: ListsAndArrays/Demos/ListLoops.cfm
<html>
<head>
<title>List Loops</title>
</head>
<body>
<h1>List Loops</h1>
<h2>List Loop 1</h2>
<cfset numlist="1,2,3,4,5">
<cfloop index="num" list="#numlist#">
<cfoutput>#num#</cfoutput>
</cfloop>
<h2>List Loop 2</h2>
<cfset beatles="paul john ringo george">
<ul>
<cfloop index="beatle" list="#beatles#" delimiters=" ">
<li><cfoutput>#beatle#</cfoutput></li>
</cfloop>
</ul>
</body>
</html>
List Functions
ColdFusion provides many built-in functions for working with lists. The
table below shows some of the most common list functions.
Function Description
Determines the number of elements
ListLen()
in a list.
Returns the index of the first list
ListFind() element in which a specified value
occurs. Case-sensitive.
ListFindNoCase() Determines the index of the first list
element in which a specified value
36. occurs. Case-insensitive.
Returns the index of the first list
ListContains() element that contains a specified
substring. Case-sensitive.
Returns the index of the first list
ListContainsNoCase() element that contains a specified
substring. Case-insensitive.
Counts instances of a specified
ListValueCount() value in a list. The search is case-
sensitive.
Counts instances of a specified
ListValueCountNoCase(
value in a list. The search is case-
)
insensitive.
Returns a copy of the list without
ListDeleteAt()
the specified element.
Gets a list element at a specified
ListGetAt()
position.
Replaces the contents of a list
ListSetAt()
element.
Sorts list elements according to a
ListSort()
sort type and sort order.
ListAppend() Appends a list or element to a list.
Inserts an element at the beginning
ListPrepend()
of a list.
ListInsertAt() Inserts an element in a list.
ListFirst() Gets the first element of a list.
ListRest() Gets a list, without its first element.
ListLast() Gets the last element of a list.
Converts a one-dimensional array to
ArrayToList()
a list.
Converts a list to a one-dimensional
ListToArray()
array.
Replaces occurrences of the
elements from a delimited list in a
ReplaceList() string with corresponding elements
from another delimited list. The
search is case-sensitive.
ListChangeDelims() Changes a list delimiter.
37. Inserts a string at the beginning and
ListQualify()
end of list elements.
Exercise: Formatting the Running Log
Duration: 15 to 25 minutes.
In this exercise, you will change the running log so that it displays the
entries in an HTML table.
1. Open ListsAndArrays/Exercises/RunningLog.cfm in your editor.
2. Before the loop that is used to display the entries, begin an
HTML table and add a header row that contains the following
table headers: Date, Distance, Time, and Comments.
3. Write code that will create a table row. Use <cfloop> to output
the table data cells.
4. Close the HTML table.
Write code so that the resulting table's table rows have alternate
colors as in the following diagram.
Note that, if you use hexadecimal color values, you may need to
escape the pound sign in locations in which ColdFusion will interpret it
as the beginning of an expression to be evaluated. The escape
38. character is another pound sign. For example, the following code
properly sets a variable called bgcolor.
<cfset bgcolor="##ff0000">
Where is the solution?
One-dimensional Arrays
One-Dimensional arrays are similar to lists or tables with a single
column. An array can contain zero or more elements. In ColdFusion,
unlike in many programming languages, the first element of an array
has an index of 1. An array with no elements has a zero length.
Creating Arrays
Arrays are created with the built-in ArrayNew() function, which takes
one argument - the number of dimensions in the array. The following
line of code creates a onedimensional array and then adds four
elements to the array.
<cfset beatles = ArrayNew(1)>
<cfset beatles[1] = "John">
<cfset beatles[2] = "Paul">
<cfset beatles[3] = "George">
<cfset beatles[4] = "Ringo">
The first line above is actually optional as the second line will create
the array if one does not already exist. However, it is a better coding
practice to explicitly set the array.
Reading from Arrays
Reading from arrays is just a matter of pointing to a specific index of
an array.
<cfoutput>#beatles[3]#</cfoutput>
<!---outputs George to the browser--->
39. Looping through Arrays
The following code sample shows how to create the array, output a
single element in the array, and then loop through the entire array
outputting each element to the browser.
Code Sample: ListsAndArrays/Demos/Arrays.cfm
<head>
<title>Array Demo</title>
</head>
<body>
<cfset beatles = ArrayNew(1)>
<cfset ArrayAppend(beatles,"John")>
<cfset ArrayAppend(beatles,"Paul")>
<cfset ArrayAppend(beatles,"George")>
<cfset ArrayAppend(beatles,"Ringo")>
<!---outputs George to the browser--->
<cfoutput>#beatles[3]#</cfoutput>
<ul>
<cfloop from="1" to="#ArrayLen(beatles)#" index="i">
<li><cfoutput>#beatles[i]#</cfoutput></li>
</cfloop>
</ul>
</body>
</html>
Code Explanation
Note that the code uses the ArrayLen() function to determine the
length of the array, which is the same as the highest index. The next
sections discusses other array functions.
Array Functions
As with lists, ColdFusion provides many built-in functions for working
with arrays. The table below shows some of the most common array
functions.
40. Function Description
ArrayNew() Creates a new array.
Determines the number of elements in an
ArrayLen()
array.
Returns true if value is an array; false
IsArray()
otherwise.
ArrayIsEmpty(
Returns true if array has zero elements.
)
Sorts array elements according to a sort type
ArraySort()
and sort order.
ArrayAppend() Appends an element to an array.
ArrayPrepend(
Prepends an element to an array.
)
Inserts a value into an array. Array elements
ArrayInsertAt( whose indexes are greater than the new
) position are incremented by one. The array
length increases by one.
ArrayDeleteAt
Deletes an element from an array.
()
ArrayClear() Deletes all elements from an array.
Returns the smallest numeric value in an
ArrayMin()
array.
Returns the greatest numeric value in an
ArrayMax()
array.
Calculates the average of the values in an
ArrayAvg()
array.
ArraySum() Calculates the sum of the values in an array.
ArrayResize() Gets the first element of a list.
ArrayToList() Converts a one-dimensional array to a list.
ListToArray() Converts a one-dimensional array to a list.
ArrayToList() Converts a list to a one-dimensional array.
Two-dimensional Arrays
ColdFusion supports two-dimensional arrays, which are similar to
tables or grids. You can think of the outer array as containing the
rows and the inner arrays as containing the data cells in those rows.
For example, a two-dimensional array called rockbands could contain
41. the names of the bands and some of the songs that they sing. Below
is a grid that represents such a two-dimensional array.
Rockband Song1 Song2 Song3
Beatles Love Me Do Hey Jude Helter Skelter
Rolling Waiting on a Yesterday's
Angie
Stones Friend Papers
Life in the Fast Hotel
Eagles Best of My Love
Lane California
The following code sample shows how this two-dimensional array is
created. Note that the header row is not included.
Code Sample: ListsAndArrays/Demos/Arrays-2Dim-
create.cfm
<html>
<head>
<title>Rockbands</title>
</head>
<body>
<h1>Rockbands</h1>
<cfset rockbands=ArrayNew(2)>
<cfset rockbands[1][1]="Beatles">
<cfset rockbands[1][2]="Love Me Do">
<cfset rockbands[1][3]="Hey Jude">
<cfset rockbands[1][4]="Helter Skelter">
<cfset rockbands[2][1]="Rolling Stones">
<cfset rockbands[2][2]="Waiting on a Friend">
<cfset rockbands[2][3]="Angie">
<cfset rockbands[2][4]="Yesterday’s Papers">
<cfset rockbands[3][1]="Eagles">
<cfset rockbands[3][2]="Life in the Fast Lane">
<cfset rockbands[3][3]="Hotel California">
<cfset rockbands[3][4]="Best of My Love">
</body>
</html>
42. Reading from Two-dimensional Arrays
To read an element from a two-dimensional array, you must first
identify the index of the "row" and then identify the index of the
"column." For example, the song "Angie" is in row 2, column 3, so it is
identified as rockbands[2][3].
Looping through Two-dimensional Arrays
To loop through a two-dimensional array, you need to nest one loop
inside of another. The following code will create an HTML table from
our two-dimensional array.
Code Sample: ListsAndArrays/Demos/Arrays-2Dim-read.cfm
---- Code Omitted ----
<table border="1">
<cfloop from="1" to="#ArrayLen(rockbands)#" index="i">
<tr>
<cfoutput>
<cfloop from="1" to="#ArrayLen(rockbands[i])#" index="j">
<td>#rockbands[i][j]#</td>
</cfloop>
</cfoutput>
</tr>
</cfloop>
</table>
</body>
</html>
Lists and Arrays Conclusion
Lists and arrays can be very helpful for working with data sets. In
most cases, arrays are much more efficient than lists as a list is not
actually built-in data type and has to be created and parsed by
ColdFusion at the time it is required. So, unless data is already in a
list format (e.g, form data from a multiple select field), it is generally
better practice to use arrays.
43. 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. (see
footnote)
<cfform> Basics (see footnote)
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.
Attribute Description
name form name
action form action
form method: "post" or
method
"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>
45. 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
46. appropriate value to the validate attribute of <cfinput> or
<cftextarea>.
Suffix Description
Numeric. The following special characters are
numeric
allowed and kept: $ ¤ ¥ £ +.
Integer. The following special characters are
integer
allowed but stripped: $ ¤ ¥ £ +.
Float. The following special characters are
float
allowed but stripped: $ ¤ ¥ £ +.
Value must be within range specified by the
value attribute in the format "min=minvalue
range
max=maxvalue". No custom error message is
allowed.
Date/time that ColdFusion can understand.
date ColdFusion converts the value into ODBC date
format (without the time).
Date/time that ColdFusion can understand.
time ColdFusion converts the value into ODBC time
format (without the date).
U.S. date. Allowed formats: m/d/y, m-d-y , or
usdate
m.d.y
European date. Allowed formats: d/m/y, d-m-y,
eurodate
or d.m.y
Number between 13-16 digits that conforms to
creditcard the mod10 algorithm. Spaces and dashes are
stripped.
Nine-digit Social Security number separated by
SSN
dashes or spaces.
U.S. telephone number with or without area
telephone
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
47. number.
Unique identifier that follows the Microsoft/DCE
format, xxxxxxxx-xxxx-xxxx-xxxx-
GUID
xxxxxxxxxxxx, where x is a hexadecimal
number.
Value must contain at least one non-whitespace
noblanks character. Field must also be specified as
required using required.
Value cannot contain more characters than
maxlength specified by the maxlength attribute. No custom
error message is allowed.
Value must match regular expression defined in
regex
the pattern attributed.
SubmitOnc Used in submit buttons to prevent a user from
e 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>
48. <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.)
49. 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>
50. <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.
51. 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.
Old
Suffix Description
Suffix
Field must be filled out or
selected. If this is not set, then
_cfformrequired _required the field will not be required,
even if other validation rules are
set.
Numeric. The following special
_cfformnumeric n/a characters are allowed: $ ¤ ¥
£ + and kept.
Integer. The following special
_cfforminteger _integer characters are allowed: $ ¤ ¥
£ + but stripped.
_cfformfloat _float Float. The following special
52. characters are allowed: $ ¤ ¥
£ + but stripped.
Value must be within range
specified by the value attribute
_cfformrange _range in the format "min=minvalue
max=maxvalue". No custom
error message is allowed.
Date/time that ColdFusion can
understand. ColdFusion converts
_cfformdate _date
the value into ODBC date format
(without the time).
Date/time that ColdFusion can
understand. ColdFusion converts
_cfformtime _time
the value into ODBC time format
(without the date).
U.S. date. Allowed formats:
_cfformusdate n/a
m/d/y, m-d-y , or m.d.y
_eurodat European date. Allowed formats:
_cfformeurodate
e d/m/y, d-m-y, or d.m.y
Number between 13-16 digits
_cfformcreditcar that conforms to the mod10
n/a
d algorithm. Spaces and dashes
are stripped.
Nine-digit Social Security
_cfformSSN n/a number separated by dashes or
spaces.
U.S. telephone number with or
_cfformtelephon
n/a without area codes and
e
extensions.
_cfformzipcode n/a 5 or 9 digit U.S. ZIP code.
_cfformemail n/a Valid email address.
_cfformURL n/a Valid URL.
Boolean. (Yes, No, True, False,
_cfformboolean n/a
1, 0)
_cfformUUID n/a Universally unique identifier
(UUID) that follows the
ColdFusion format, xxxxxxxx-
xxxx-xxxx-xxxxxxxxxxxxxxxx,
53. where x is a hexadecimal
number.
Unique identifier that follows the
Microsoft/DCE format,
_cfformGUID n/a xxxxxxxx-xxxx-xxxx-xxxx-
xxxxxxxxxxxx, where x is a
hexadecimal number.
Value must contain at least one
non-whitespace character. Field
_cfformnoblanks n/a
must also be specified as
required using _cfformrequired.
Value cannot contain more
_cfformmaxlengt characters than specified by the
n/a
h value attribute. No custom error
message is allowed.
Value must match regular
_cfformregex n/a
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
54. 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
55. 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.
56. 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:
Character Description
A A-Z (case-insensitive)
A-Z (case-insensitive) or
X
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="course_id"
mask="AAA99X"><br/>
<cfinput type="submit" name="Submit" value="Submit">
</cfform>
</body>
</html>
57. 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," ")>
59. </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).
60. 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.
61. 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.
(see footnote) In addition, the type can be any of the following:
Suffix Description
Same as
any
IsSimpleValue().
array Same as IsArray().
binary Same as IsBinary().
query Same as IsQuery().
struct Same as IsStruct().
Exercise: Custom Form Validation
Duration: 20 to 30 minutes.
1. Open FormValidation/Exercises/AddEntry.cfm in your editor.
2. Add the following validation.
o Time format should be "##:##".
o Comments should be required and not longer than 50
characters.
3. Open AddEntry.cfm in your browser to test your new page.
1. The date entered should be in the past. You can use the
DateCompare() function to compare it to the current time. If the
date has not yet occurred, return an error.
2. Using your other knowledge of ColdFusion, let the user know
how fast she was running.
Where is the solution?
62. 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.
Footnotes
This lesson does not address writing custom client-side validation as
that requires knowledge of JavaScript.
This lesson only covers using <cfform> with HTML forms. Starting
with ColdFusion MX 7, ColdFusion can auto-generate Flash and
XML/XSLT-generated forms.
With the exception of SubmitOnce.
Database Access and Authentication
In this lesson of the ColdFusion tutorial, you will learn...
1. To create a login form and authenticate users.
2. To use <cfquery> to send queries to a database and store result
sets.
3. To use <cfoutput> to output query results.
A Database-less Login Form
Below is a simple login form that hardcodes the username and
password.
Code Sample: DatabaseBasics/Demos/Login-noDB.cfm
<cfif isDefined("FORM.submitted")>
<cfif FORM.email EQ "itsme@webucator.com" AND password EQ
"password">
<cflocation url="index.cfm" addtoken="no">
</cfif>
</cfif>
64. As you can see, this page submits to itself. If the user has not yet
submitted the form, the form is displayed. If the user submits the
form with the correct email and password, the page is redirected to
the home page.
<cfquery>
ColdFusion has a special data type called query. Recordsets returned
from a database are of this data type and are called "queries".
The <cfquery> tag is used to send queries to a database and to store
the results returned in a query variable.
Attribute Description
name Name of query.
datasource Name of data source.
Only possible value is "query". Used with query
dbtype
of queries.
Overrides username set up in ColdFusion
username
Administrator.
Overrides password set up in ColdFusion
password
Administrator.
Maximum number of rows to return in record
maxrows
set.
blockfactor Maximum rows to get at a time from server.
Number of seconds that each action of a query
timeout is permitted to execute before returning an
error.
Date value specifying when to drop query from
cachedafter
cache.
cachedwithi
Timespan for which to hold query in cache.
n
debug Turns debugging display on or off.
The query object created by this tag has the following properties.
Property Description
Current record of the query being
currentRow
processed.
columnList Comma-delimited list of column names.
65. recordCount Number of records returned by query.
executionTime Time it took to execute query.
You can find out how long a query takes to process by reading the
cfquery.executionTime variable.
This following example is very similar to the previous one, except that
the valid username and password are not hardcoded in the script but
instead are searched for in a database.
Code Sample: DatabaseBasics/Demos/Login.cfm
<cfif isDefined("FORM.submitted")>
<cfquery name="logincheck" datasource="runners">
SELECT FirstName, LastName, Email FROM Users
WHERE email='#FORM.email#'
AND password='#FORM.password#'
</cfquery>
<cfif logincheck.RecordCount>
<cflocation url="index.cfm" addtoken="no">
</cfif>
</cfif>
---- Code Omitted ----
Exercise: Creating a Registration Page
Duration: 20 to 30 minutes.
In this exercise, you will create a self-submitting registration page
that displays a registration form the first time a user visits the page
and processes the form when the user submits it.
1. Open DatabaseBasics/Exercises/Register.cfm in your editor.
Much of the file is already complete.
2. In the main <cfelse> block follow the directions in the
comments. You will write code that:
o Validates the passwords.
o Inserts the new record into the database (the fields in the
database have the same names as those in the form:
firstname, lastname, email, password).
67. <input type="text" name="lastname" size="10">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Register">
</td>
</tr>
</table>
</form>
<cfelse>
<!---
Write an if statement that checks to make
sure the passwords are the same.
--->
<cfif WRITE_CONDITION_HERE>
<!---
Write a query that inserts the new record
into the Users table. The fields in the
database have the same names as those in
the form: firstname, lastname, email, password
--->
<cfquery datasource="Runners">
</cfquery>
You have registered successfully.
<p><a href="index.cfm">Home Page</a></p>
<cfelse>
<p class="errors"><b>Your passwords
do not match. Please <a href=
"Register.cfm">try again</a>.</p>
</cfif>
</cfif>
</body>
</html>
Write code on the registration page that first checks to see if that
email is already in the Users table. If it is, let the user know she is
already registered and do not insert a new record.
68. Where is the solution?
Outputting Database Data
We have used <cfquery> to check for the existence of a record and to
insert a new record. It is also often used to select a group of records,
known as a recordset, and output them to the web page. The most
common way to output the data is to use the <cfoutput> tag with its
query attribute set to the relevant query name. The following example
illustrates this.
Code Sample: DatabaseBasics/Demos/cfoutput.cfm
<cfquery name="getUsers"
datasource="#APPLICATION.datasource#">
SELECT firstname, lastname, email
FROM Users
</cfquery>
<html>
<head>
<title>Using cfoutput</title>
</head>
<body>
<ul>
<cfoutput query="getUsers">
<li>#firstname# #lastname# (#email#)</li>
</cfoutput>
</ul>
</body>
</html>
Code Explanation
69. The output of this page is shown below:
Exercise: Using <cfoutput> to Display Query Results
Duration: 10 to 20 minutes.
In this exercise, you will modify the demo we have just seen so that
the records are output as a table rather than as a list.
1. Open DatabaseBasics/Exercises/cfoutput.cfm in your editor.
70. 2. Fix the code so that each record is displayed as a row as shown
in the screenshot below:
Where is the solution?
Database Access and Authentication Conclusion
In this lesson of the ColdFusion tutorial, you have learned how to
connect to a database to insert and select records and to use this
ability to create registration and login forms. Unfortunately, as it is
written currently, only the pages themselves are protected. To protect
the whole site in this manner, we would have to force the user to log
in to every page. That might frustrate our visitors a bit. You will need
to learn about session management to allow the user to stay logged
in.
Reusing Code and Writing Functions
In this lesson of the ColdFusion tutorial, you will learn...
71. 1. To include files with <cfinclude>.
2. To to use Application.cfm and OnRequestEnd.cfm.
3. To to write user-defined functions.
Writing reusable code results in time and money savings, more
consistent and bug free code, and the ability to hide complex code
from less seasoned developers. We'll cover several basic code reuse
techniques in this lesson.
Including Files
Including files in ColdFusion is made simple with the <cfinclude> tag,
which takes a single attribute: template. The template attribute points
to the file to include. ColdFusion first looks for the included file
relative to the current directory. If it cannot find it, it then looks in
directories mapped in ColdFusion Administrator.
Syntax
<cfinclude template="path_to_file">
Note that a ColdFusion tag cannot be opened in a calling file and then
closed in an included file or vice versa. The ColdFusion code in the
included file must be syntactically valid on its own.
A Note on Security
If included files are under the web root, they can be accessed just as
any other file can. If they have an extension such as .inc then the
browser may display them as plain text. With other extensions, the
browser may attempt to download the file. If the included file is a
ColdFusion file and a user navigates to it, the server will try to
process the file and may return errors. As a precaution, you may want
to place your included files in a directory above or outside of the web
root. This will prevent users from accessing the files directly.
Code Sample: ReusingCode/Demos/index.cfm
<html>
<head>
<title>Runners Home™</title>
72. <link href="Styles/Main.css" rel="stylesheet">
</head>
<body>
<cfinclude template="Includes/NavBar.cfm">
<div id="greeting">
<cfoutput>The time is #TimeFormat(Now(),"h:mm tt")# on
#DateFormat(Now(), "mmmm d, yyyy")#.</cfoutput>
</div>
<table align="center" cellpadding="10" cellspacing="0"
width="100%" height="100%" id="hometable">
---- Code Omitted ----
</table>
<cfinclude template="Includes/Footer.cfm">
</body>
</html>
Code Explanation
The above code is relatively straightforward. It contains to included
files: Includes/NavBar.cfm and Includes/Footer.cfm.
Application.cfm and OnRequestEnd.cfm (see
footnote)
Whenever a ColdFusion page is called, the ColdFusion Application
Server checks the current directory for a file called Application.cfm. If
Application.cfm is not found in the current directory, ColdFusion looks
for the file in the parent directory and continues to look up the tree
until it gets to the root directory of the file system. As soon as the file
is found, ColdFusion stops looking up the tree and prepends the found
Application.cfm to the called page.
Application.cfm is often used for the following tasks:
73. • Control state management variables and set the application
name with <cfapplication>.
• Set default global variables such as data source names and file
paths.
• Set custom error handling using <cferror>.
Application.cfm should not used for including code to be output to the
browser, such as a common header.
When and only when an Application.cfm file is found, ColdFusion will
also look for a file called OnRequestEnd.cfm in the same directory. If
it finds OnRequestEnd.cfm it will append it to the called file.
OnRequestEnd.cfm is sometimes used for outputting debugging
information or logging information about the page.
User-defined Functions
User-defined functions are used to make common tasks easier and to
make code more modular and easier to read.
Defining and Calling Functions
Functions are defined with the <cffunction> tag as follows. Like built-
in functions, user-defined functions can receive arguments.
Arguments are defined using the <cfargument> tag. If no default is
defined with the default attribute, then the argument is required.
Syntax
<cffunction name="function_name" returntype="type">
<cfargument name="arg" type="type" default="default">
</cffunction>
Here is an example user-defined function for adding numbers.
Code Sample: ReusingCode/Demos/UDF.cfm
<html>
<head>
<title>User-defined Function</title>
</head>
74. <body>
<cfset total = addNums(1)>
<cfoutput>#total#</cfoutput>
</body>
</html>
<cffunction name="addNums" returntype="numeric">
<cfargument name="num1" type="numeric">
<cfargument name="num2" type="numeric" default="0">
<cfargument name="num3" type="numeric" default="0">
<cfset sum=num1 + num2 + num3>
<cfreturn sum>
</cffunction>
Code Explanation
Notice that user functions are called in the same way as built-in
functions.
Exercise: Creating a File2Table Function
Duration: 20 to 30 minutes.
In this exercise, you will modify RunningLog.cfm to include a function
that creates a table from a tab-delimited text file.
1. Open ReusingCode/Exercises/RunningLog.cfm in your editor.
2. Create a function called File2Table that takes two arguments:
the path to the file and an array of the table headers.
3. Modify the page so that the function contains all the processing
code that loads the file and creates and returns an HTML table.
4. If the file cannot be opened, the function should return "File not
found".
5. the function and send the result to the browser.
Add formatting functionality to the function. For example, make the
border size and the background color of the table controlled by the
function call.
75. The function currently has the headers hardcoded in. This is not great
for reuse. Change this so the function excepts a Headers array and
loops through the array to output the headers.
Where is the solution?
Exercise: Creating a Function Library
Duration: 5 to 10 minutes.
In this exercise, you will move the function you created in the last
exercise into a function library and then include that library in
RunningLog2.cfm with <cfinclude>.
1. Open ReusingCode/Exercises/RunningLog.cfm in your editor and
save it as RunningLog2.cfm.
2. Cut the File2Table function and paste it in a new file. Save the
new files as Functions.cfm.
3. Add code to RunningLog2.cfm so that it includes the new
function library.
Where is the solution?
Reusing Code and Writing Functions Conclusion
Using includes and functions are two common ways of writing
reusable code. Very often developers will save common functions in
an include file (e.g, functions.inc), so they don't have to copy and
paste functions into scripts to make use of them.
Session & Application Management
In this lesson of the ColdFusion tutorial, you will learn...
1. To understand the difference between ColdFusion session
management and J2EE session management.
2. To use the <cfapplication> tag is used to set defaults for session
state management.
3. To use Application variables.
4. To use session variables to remember that the users are logged
in as they go from page to page.