In this article we continue to look at what ColdFusion is and how you can use it for dynamic website creation. We cover all the different varieties of the loop tag and how ColdFusion makes list handling easy.
What is ColdFusion? In case you missed the last article that introduced ColdFusion, let me explain what it is. ColdFusion, which was introduced by Allaire in 1995 and is currently on version 4.0, is a programming language based on standard HTML (Hyper Text Markup Language) that is used to write dynamic webpages. It lets you create pages on the fly that differ depending on user input, database lookups, time of day or what ever other criteria you dream up. ColdFusion pages consist of standard HTML tags such as <FONT SIZE="+2"> together with CFML (ColdFusion Markup Language) tags such as <CFQUERY>, <CFIF> and <CFLOOP>.
Looping in ColdFusion Looping is a very powerful programming technique that lets you repeat a set of instructions or display output over and over until one or more conditions are met. ColdFusion implements looping with the <CFLOOP> tag. Five different types of loops are available:
Index Loops
Conditional Loops
Looping over a Query
Looping over a List
Looping over a COM Collection or Structure
The type of loop is determined by the attributes of the <CFLOOP> tag, as I will explain in detail below. By the way, all the types let you exit a loop with a <CFBREAK>
Index Loops An index loop repeats for a number of times determined by a range of numeric values. Index loops are commonly known as FOR loops, as in "loop FOR this range of values." The general syntax is:
This will result in two list boxes side by side, one with 24 items, the other with 60. If instead we had preferred one list box with all the hours and minutes of the day (that is 1440 items!) we could instead have nested the loops:
Notice how now we have enclosed the option value passed by the form submit in single quotes. This is because we want to pass a string such as '12:25' rather than just the number of hours and minutes separately. Also, as we left off the STEP parameter it defaults to a step size of one.
If you try the above code at home be prepared to wait a little while since a list box with more than a thousand items in it is not browser friendly and may either take a long time to display or crash older browsers.
Conditional Loops A conditional loop iterates over a set of instructions while a given condition is TRUE. The exact number of times it repeats may not be known when the code is written, so that is how it differs from an index loop. However, if you want to avoid your program running for ever in an infinite loop you probably will want to change the condition every time the loop iterates so that the condition does eventually evaluate as FALSE. Conditional loops are commonly known as WHILE loops, as in "loop WHILE this condition is true."
Suppose we want to display a random number of horizontal lines in a page. One way to do this is to loop until a random number is greater than a given number.
<CFSET StopIt = 0>
<CFLOOP CONDITION="StopIt LESS THAN OR EQUAL TO 5">
<CFSET StopIt = RandRange(1,10)>
<HR>
</CFLOOP>
Looping over a Query A loop over a query repeats for every record in the query record set. The CFLOOP results are similar to the <CFOUTPUT QUERYNAME=...> tag, except that you need to wrap variables with a single CFOUTPUT tag for display. During each iteration of the loop, the columns of the current row will be available for output. It just runs slower.
Then why would you use CFLOOP instead of CFOUTPUT? The advantage of looping over a query is that you can use CFML tags that are not allowed in a CFOUTPUT. For example, nested queries or email tags. Future versions of ColdFusion may eliminate this issue. The following example loops through a list of email addresses, and for each person sends all messages corresponding to that user's security level.
<CFQUERY NAME="GetEmail"
DATASOURCE="Library">
SELECT Email , SecurityLevel
FROM Customer
</CFQUERY>
<CFLOOP QUERY="GetEmail">
<CFQUERY NAME="GetText"
DATASOURCE="Library">
SELECT EmailText, EmailSubject
FROM Messages
WHERE SecurityLevel = #GetEmail.SecurityLevel#
</CFQUERY>
In this example, we are looping over customer email addresses and depending on their security level querying for different email text and subject line before emailing the message to them. If we replaced the outer CFLOOP by a CFOUTPUT, a ColdFusion error would result.
Dynamic Forms Incidentally, this little form is an example of a dynamic form — that is, an HTML form that uses elements created with database query results and CFML. Most often these elements are radio buttons, check boxes, select lists, or multiple select lists. It is powerful because you don't have to recode the form when the data changes — ColdFusion recreates the form on the fly every time you call the page. You can use dynamic forms to help ensure data integrity, to speed coding, and to create relationships between tables in your database.
Looping over a List Looping over a list runs a loop though any typically comma-delimited list of items you have. In a list loop, the INDEX attribute specifies the name of a variable to receive the next element of the list, and the LIST attribute holds a list or a variable containing a list.
Where does a comma-delimited list come from in your pages you ask? A common source is a multi-select list box or check boxes in a previous page. In our example, we generate a list of state names from a states table in our database.
<CFQUERY NAME="StateNames"
DATASOURCE="Library">
SELECT State_ID, StateName
FROM States
</CFQUERY>
When this form is submitted, it passes the selected State_ID's as a comma-delimited list of state codes.
Having created our comma-delimited list of states, the next page processes the list:
<H2>The following states were selected</H2>
<CFSET extraSQL = 'FALSE'>
<CFLOOP INDEX="ListElement"
LIST=#form.state#
DELIMITERS=",">
<CFOUTPUT>#ListElement#</CFOUTPUT><BR>
<CFSET extraSQL = extraSQL & OR State_ID =
'"&PreserveSingleQuotes(ListElement)&"'">
</CFLOOP>
<CFQUERY NAME="GetCustomers"
DATASOURCE="Library">
SELECT *
FROM Customer
WHERE #PreserveSingleQuotes(extraSQL)#
</CFQUERY>
If the states selected are MD, VA, and DC then the above code will generate the following HTML:
<H2>The following states were selected</H2>
MD<BR>
VA<BR>
DC<BR>
And the query will contain the following SQL statement:
SELECT * FROM Customer WHERE FALSE OR State_ID = 'MD' OR State_ID = 'VA' OR State_ID = 'DC'
Notice that we use the initial value of FALSE for the extraSQL variable so that the above code will still work whether the list is empty or only contains one state. Preserve single quotes is required to prevent the automatic doubling up of quote marks.
Although CFLOOP expects elements in the list to be separated by commas by default, you are free to specify your own element boundaries in the DELIMITER attribute. You can even specify several alternative delimiters.
By the way, if you are not trying to demonstrate how to use loops, there is an easier way to code for the above query on a list of states using the SQL IN clause.
SELECT * FROM Customer WHERE State_ID IN (#PreserveSingleQuotes(Form.state)#)
In our example above, the SQL statement sent to the database would be:
SELECT * FROM Customer WHERE State_ID IN ('DC','MD','VA')
ColdFusion List Functions ColdFusion has great support for list handling. Here is a listing of the functions available to you.
ListAppend
Returns list with value appended behind its last element.
ListPrepend
Returns list with value inserted at the first position, shifting all other elements one to the right.
ListInsertAt
Returns list with value inserted at the specified position.
ListSetAt
Returns list with value assigned to its element at specified position.
ListGetAt
Returns the element at a given position.
ListFirst
Returns the first element of the list.
ListLast
Returns the last element of the list
ListRest
Returns list without its first element. Returns an empty list (empty string) if list has only one element.
ListDeleteAt
Returns list with element deleted at the specified position.
ListFind
Returns the index of the first occurrence of a value within a list. Returns 0 if no value is found. The search is case-sensitive.
ListFindNoCase
Returns the index of the first occurrence of a value within a list. Returns 0 if no value was found. The search is case-insensitive.
ListContains
Returns the index of the first element of a list that contains the specified substring within elements. The search is case-sensitive. If no element is found, returns 0.
ListContainsNoCase
Returns the index of the first element of a list that contains the specified substring within elements. The search is case-insensitive. If no element is found, returns 0.
ListChangeDelims
Returns list with all delimiter characters changed to new_delimiter string.
ListToArray
Converts the specified list, delimited with the character you specify, to an array.
ArrayToList
Converts the specified one dimensional array to a list, delimited with the character you specify.
ReplaceList
Returns string with all occurrences of the elements from the specified comma-delimited list being replaced with their corresponding elements from another comma-delimited list. The search is case sensitive.
ListLen
Returns the number of elements in the list.
QuotedValueList
Returns a comma-separated list of the values of each record returned from a previously executed query. Each value in the list is enclosed in single quotes.
ValueList
Returns a comma-separated list of the values of each record returned from a previously executed query.
GetClientVariablesList
Returns a comma-delimited list of non-readonly clientvariables available to a template.
Looping over a COM Collection or Structure Although it is beyond the level of this article, I should also tell you that CFLOOP lets you loop both over a ColdFusion structure and over a COM/DCOM collection object. For the curious, a COM/DCOM collection object is a set of similar items referenced as a group rather than individually. For example, the group of open documents in an application is a type of collection. A structure is a related set of items or an associative array. In other words, an array whose index is not numeric but consists of arbitrary words.
Summary In this article we learned about all the different varieties of the <CFLOOP> tag for looping. We covered FOR loops, WHILE loops, query loops, list loops, COM /structure loops. We also explained how lists can be used in your pages.
Creating Dynamic Websites With ColdFusion— — The CF Apprentice Series Part 1: What is ColdFusion?
About Michael Smith Michael Smith is president of TeraTech (www.teratech.com/), an 11-year-old Rockville, Maryland-based consulting company that specializes in ColdFusion, database, and Visual Basic development.
Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice: