CFLOOP

Looping is a very powerful programming technique that lets you repeat a set of instructions or display output over and over depending on a particular set of conditions. CFLOOP allows for four different types of loops:

The type of loop is determined by the attributes of the CFLOOP tag.

Index Loops

An index loop repeats for a number of times determined by a range of numeric values.

The CFLOOP index loop uses the following parameters:

CFLOOP (Index loop)
Attribute

Description

INDEX

Required. Defines the parameter that is the index value. The index value will be set to the FROM value and then incremented by 1 (or the STEP value) until it equals the TO value.

FROM

Required. The beginning value of the index.

TO

Required. The ending value of the index.

STEP

Optional. Default is 1. Sets the value by which the loop INDEX value is incremented each time the loop is processed.

Example 1

The INDEX variable will be incremented on each iteration of the loop. The following example loops five times, displaying the index value of the loop each time:

<CFLOOP INDEX="LoopCount" FROM="1" TO="5">
   The loop index is  <CFOUTPUT>#LoopCount#</CFOUTPUT>.<BR>
</CFLOOP>

The result of this loop in a browser would look something like this:

The loop index is 1.

The loop index is 2.

The loop index is 3.

The loop index is 4.

The loop index is 5.

Example 2

The STEP value has a default value of 1. But you can set the step value to change the way the INDEX value is incremented. The following example is like example one but it counts backwards from 5:

<CFLOOP INDEX="LoopCount" FROM="5" TO="1" STEP="-1">
   The loop index is <CFOUTPUT>#LoopCount#</CFOUTPUT>.<BR>
</CFLOOP>

The result of this loop in a browser would look something like this:

The loop index is 5.

The loop index is 4.

The loop index is 3.

The loop index is 2.

The loop index is 1.

Tip: Index loops are commonly known as a FOR loop, as in æloop FOR this range of values.Æ

Conditional Loops

A conditional loop iterates over a set of instructions while a given condition is true. To use this type of loop correctly the instructions must change the condition every time the loop iterates until the condition evaluates as FALSE.

The CFLOOP conditional loop uses the following parameters:

CFLOOP tag (conditional loop)
Attribute

Description

CONDITION

Required. Sets the condition that controls the loop. The loop will repeat as long as the condition evaluates as TRUE. When the condition is FALSE the loop will stop.

Example

The following example increments the parameter "CountVar" from 1 to 5. The results look exactly like the Index loop shown above.

<!--- Set the variable CountVar at 1  --->
<CFSET #CountVar#  =  0>
<!--- Loop until CountVar is 5 --->
<CFLOOP CONDITION="CountVar LESS THAN OR EQUAL TO 5">
<CFSET #CountVar# = #CountVar# + 1>
   The loop index is <CFOUTPUT>#CountVar#</CFOUTPUT>.<BR>
</CFLOOP>

The result of this loop in a browser would look something like:

The loop index is 1.

The loop index is 2.

The loop index is 3.

The loop index is 4.

The loop index is 5.

Tip: Conditional loops are commonly known as WHILE loops, as in æloop while this condition is true.Æ

Looping over a Query

A loop over a query repeats for every record in the query result 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. The advantage of using CFLOOP instead of a CFOUTPUT is that you can use any CFML tag within a CFLOOP. CFOUTPUT is restricted to a limited number of tags to increase its performance.

The CFLOOP query loop uses the following parameters:

CFLOOP tag (conditional loop)
Attribute

Description

QUERY

Required. Specifies the query which will control the loop.

STARTROW

Optional. Specifies the first row of the query that will be included in the loop.

ENDROW

Optional. Specifies the last row of the query that will be included in the loop.

Example 1

The following example shows a CFLOOP tag that works just like a CFOUTPUT:

<CFQUERY NAME="MessageRecords" DATASOURCE="CF 2.0 Examples">
   SELECT * FROM Messages
</CFQUERY>
<CFLOOP QUERY="MessageRecords">
   <CFOUTPUT>#Message_ID#</CFOUTPUT><BR>
</CFLOOP>

Example 2

CFLOOP also provides iteration over a recordset with dynamic starting and stopping points. Thus, you can begin at the tenth row in a query and end at the twentieth. Using this mechanism provides a simple means to get the next n set of records from a query. The following example loops from the tenth through the twentieth record returned by "MyQuery:"

<CFSET Start = 10>
<CFSET End = 20>
<CFLOOP QUERY="MyQuery" STARTROW="#Start#" ENDROW="#End#">
   <CFOUTPUT>#MyQuery.MyColName#</CFOUTPUT><BR>
</CFLOOP>

The loop is done when there are no more records or when the current record is greater than the value of the ENDROW attribute.

Example 3

The advantage of looping over a query is that you can use CFML tags that are not allowed in a CFOUTPUT. The following example will combine the templates returned by a query of a list of template names into a single document using the CFINCLUDE tag.

<CFQUERY NAME="GetTemplate" DATASOURCE="Library"

   MAXROWS="5">
   SELECT TemplateName FROM Templates
</CFQUERY>
<CFLOOP QUERY="TemplateName">
   <CFINCLUDE TEMPLATE="#TemplateName#">
</CFLOOP>

Looping over a List

Looping over a list offers the option of walking through elements contained within a variable or value returned from an expression. 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. This loop will display the names of each of the Beatles:

<CFLOOP INDEX="ListElement" LIST="John,Paul,George,Ringo">
   <CFOUTPUT>#ListElement#</CFOUTPUT><BR>
</CFLOOP>

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. Here's the same loop as before, only this time CFLOOP will treat commas, colons, or slashes as list element delimiters:

<CFLOOP INDEX="ListElement" LIST="John/Paul,George::Ringo" DELIMITERS=",:/">
   <CFOUTPUT>#ListElement#</CFOUTPUT><BR>
</CFLOOP>

Delimiters need not be specified in any particular order. Note that consecutive delimiters are treated as a single delimiter; thus, the two colons in the previous example are treated as a single delimiter between "George" and "Ringo."

Nesting Loops

The tags contained within the boundaries of a CFLOOP can also be other CFLOOPs. In this case, the inner loop will execute from start to finish as many times as the outer loop executes. Loops can be nested as deeply as you like. Here the inner loop will execute on each iteration of the outer loop for a grand total of 15 times:

<CFLOOP INDEX="OuterLoopCount" FROM="1" TO="3">
   <CFOUTPUT>Outer loop #OuterLoopCount#</CFOUTPUT><BR>
   <CFLOOP INDEX="InnerLoopCount" FROM="1" TO="5">
      <CFOUTPUT>Inner loop #InnerLoopCount#</CFOUTPUT><BR>
   </CFLOOP>
</CFLOOP>

Breaking Out of a Loop

When Cold Fusion encounters the CFBREAK tag in a loop it terminates the execution of the loop and proceeds to process the template starting with the line immediately following the end of the loop. This is generally less elegant than constructing the loop with an appropriate conditional, but there are times when breaking out of a loop can simplify a tag structure that's complicated or deeply nested. The following example isn't a terribly good use of CFBREAK, but it shows the tag in action:

<CFLOOP INDEX="LoopCount" FROM="1" TO="100">
   The value is <CFOUTPUT>#LoopCount#</CFOUTPUT>.<BR>
   <CFIF LoopCount IS 7>
      <CFBREAK>
   </CFIF>
</CFLOOP>

The results in the browsers would look something like:

The value is 1.

The value is 2.

The value is 3.

The value is 4.

The value is 5.

The value is 6.

The value is 7.