home Links Articles Books Past Meetings Photos SiteMap
The MDCFUG is sponsored by TeraTech. Visit us at www.TeraTech.com

Please send
comments/questions to

michael@
teratech.com

 

CPCUG Monitor

Creating dynamic websites with ColdFusion

Part 4: Loops and Lists

by Michael Smith

TeraTech http://www.teratech.com/

What is ColdFusion

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.

 

In case you missed the last article that introduced ColdFusion, let me explain what it is. ColdFusion 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>.  ColdFusion was introduced by Allaire in 1996 and is currently on version 4.0

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.

 

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:

 

<CFLOOP INDEX="parameter_name"

FROM="beginning_value"

TO="ending_value"

STEP="increment">

 

   HTML or CFML code to repeat

 

</CFLOOP>

For example if we want  HTML list boxes of hours and minutes that go from 0 to 23 and 0 to 59 respectively we could use two CFLOOP tags as follows:

 

<SELECT NAME="Hour">

<CFLOOP INDEX="hour" FROM="0" TO="23">

   <CFOUTPUT>

    <OPTION VALUE="#hour#">#hour#

  </CFOUTPUT>

</CFLOOP>

</SELECT>

:

<SELECT NAME="Minute">

<CFLOOP INDEX="minute"FROM ="0" TO="59">

   <CFOUTPUT>

    <OPTION VALUE="#minute#">#minute#

  </CFOUTPUT>

</CFLOOP>

</SELECT>

 

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:

 

<SELECT NAME="HourAndMinutes">

<CFLOOP INDEX="hour" FROM="0" TO="23">

  <CFLOOP INDEX="minute" FROM="0" TO="59">

    <CFOUTPUT>

    <OPTION VALUE="'#hour#:#minute#'">#hour#:#minute#

    </CFOUTPUT>

  </CFLOOP>

</CFLOOP>

</SELECT>

 

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 as to be honest 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 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>

 

Can exit a loop with <CFBREAK>

 

Looping over a Query

A loop over a query repeats for every record in the query record set.  The CFLOOP results are just like a CFOUTPUT. 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. 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>

 

   <CFMAIL QUERY="GetText"

      TO="#GetEmail.Email#"

      FROM="info@mycompany.com"

      SUBJECT="#GetText.EmailSubject#"

      SERVER="smtp.mycompany.com">#GetText.EmailText#

   </CFMAIL>

</CFLOOP>

 

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.

Looping over a List

Text Box: Dynamic forms
By the way the little form to the left 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 either 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 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 from a states table in our database.

<CFQUERY NAME="StateNames"

DATASOURCE="Library">

SELECT State_ID, StateName

FROM States

</CFQUERY>

 

<FORM ACTION="example.cfm" METHOD="Post">

<SELECT NAME="state" MULTIPLE>

<CFOUTPUT QUERY="StateNames">

   <OPTION VALUE="’#State_ID#’">#StateName#

</CFOUTPUT>

</SELECT>

<INPUT TYPE="submit" VALUE="Submit">

</FORM>

 

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>

 

Text Box: ColdFusion List functions
ColdFusion has great support for list handling. Here is a list (no pun intended) 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 zero (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 client variables available to a template.


<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 then 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’)

 

 


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.  Or 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.

To Learn More

You can download a free 30 day-evaluation version of ColdFusion from Allaire or request a free eval CD-ROM from

the Allaire website http://www.allaire.com/ 

 

Allaire Corporation

1 Alewife Center

Cambridge, MA 02140

 

Tel: 617.761.2000 voice

Fax: 617.761.2001 fax

Toll Free: 888.939.2545

Email: sales@allaire.com

Web: www.allaire.com

 

ColdFusion Resources

Allaire also maintains an extensive knowledge base and tech support forums on their website.

CPCUG and TeraTech ColdFusion Conference http://www.teratech.com/cfconf/

TeraTech maintains a ColdFusion code cuttings called ColdCuts at http://www.teratech.com/ColdCuts/. This page also has links to about a dozen ColdFusion white papers in the CF Info Center.

The Maryland ColdFusion User Group meets the second Tuesday of each month at Backstreets Cafe, 12352 Wilkins Avenue, Rockville. See http://www.cfug-md.org/ for details and directions.

The DC ColdFusion User Group meets the first Wednesday each month at Figleaf , 16th and P St NW, Washington DC. See the DCCFUG page on http://www.figleaf.com/ for details and directions.

Bio

Michael Smith is president of TeraTech, a ten year old Rockville Maryland based consulting company that specializes in ColdFusion, Database and Visual Basic development. You can reach Michael at michael@teratech.com or 301-424-3903.


Home | Links | Articles | Past Meetings | Meeting Photos | Site Map
About MDCFUG | Join | Mailing List |Forums | Directions |Suggestions | Quotes | Newbie Tips
TOP

Copyright © 1997-2017, Maryland Cold Fusion User Group. All rights reserved.
< >