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.
An index loop repeats for a number of times determined by a range of numeric values.
The CFLOOP index loop uses the following parameters:
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 5.
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 1.
Tip: Index loops are commonly known as a FOR loop, as in æloop FOR this range of values.Æ
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:
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 5.
Tip: Conditional loops are commonly known as WHILE loops, as in æloop while this condition is true.Æ
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:
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>
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.
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 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."
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>
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 7.