cfloop

Different items are required based on loop type. Items listed
as required may not be depending on your loop type.
Loop forms:
[query] [condition] [index + from + to ] [index + list]
[collection + item ]

  <cfloop>

 for (i = 1; i <= 10; i++) { }

Attribute Reference

index string

Index value. CFML sets it to from value and
increments or decrements by step value, until it equals to
value.

from numeric

Beginning value of index.

to numeric

Ending value of index.

step numeric

Step by which to increment or decrement the index value.

condition string

Condition that controls the loop.

query query

Query that controls the loop.

group string

CF 10+ and Lucee 4.5+. Query column to use to group sets of records. Eliminates adjacent duplicate rows when data is sorted. Use if you retrieved a recordset ordered on one or more query columns.

groupcasesensitive boolean
Default: No

Lucee 4.5+. Boolean indicating whether to group with regard to case or not. The default value is NO; case is considered while grouping. If the query attribute specifies a query object that was generated by a case-insensitive SQL query, set the groupCaseSensitive attribute to NO to keep the recordset intact.

startrow numeric

First row of query that is included in the loop.

endrow numeric

Last row of query that is included in the loop.

list string

The list attribute is used with the index (or item in Lucee or CF 2016+) attribute to loop over a list, variable, or filename; contains a list

delimiters string
Default: ,

Character(s) that separates items in list

collection any

The collection attribute is used with the item attribute.
often to loop over a structure

item string

The item attribute is used with the collection attribute often to loop over a structure or array

NOTE: If you have item attribute without index, item represents the key. In Lucee 4.5+ you can use item with index, but keep in mind, that item will represent the value whereas index will be the key now!

array array

CF 8+ An array.

characters numeric

CF 8+ The number of characters to read during each iteration of the loop from the file specified in the file attribute.
If the value of the characters attribute is more than the number of characters in the file,
ColdFusion uses the number of characters in the file.

file string

CF 8+ The absolute path and filename of the text file to read, one line at a time.
This is helpful when reading large text files, because you can reuse the value of the index variable,
which contains the current line of the file.
When the loop completes, ColdFusion closes the file.

times numeric

Lucee 5+ If you want to have a specific iterations you can simply use times param instead of from and to

Examples
Sample code using the cfloop tag

General Purpose Loop

for (i = 1; i <= 10; i++) {
    writeOutput(i); 
}

Expected Result: 12345678910

General Purpose Loop

<cfloop index="i" from="1" to="10">
    <cfoutput>#i#</cfoutput>
</cfloop>

Expected Result: 1 2 3 4 5 6 7 8 9 10

Array Loop

myArray = ["a", "b", "c"];
// For Loop By index for CF9.0.0 and lower 
for (i = 1; i <= arrayLen(myArray); i++) {
    writeOutput(myArray[i]);
}
// By For In CF9.0.1+ 
for (currentIndex in myArray) {
    writeOutput(currentIndex);
}
// By arrayEach() member function CF11+
myArray.each(function(element, index) {
    writeOutput(element & " : " & index);
});

Array Loop

<cfset myArray = ["a", "b", "c"]> 
 <!--- By index ---> 
 <cfloop index="i" from="1" to="#arrayLen(myArray)#"> 
 <cfoutput>#myArray[i]#</cfoutput> 
 </cfloop> 
 <!--- By array ---> 
 <cfloop index="currentIndex" item="currentItem" array="#myArray#"> 
 <cfoutput>#currentIndex#</cfoutput> 
 
 <cfoutput>#currentItem#</cfoutput> 
 </cfloop>

Struct Loop

myStruct = {name: "Tony", state: "Florida"}; 
 // By struct 
 for (currentKey in myStruct) { 
 writeOutput("<li>#currentKey# : #myStruct[currentKey]#</li>"); 
 } 
 // By structEach() 
 myStruct.each(function(key, value) { 
 writeOutput("<li>#key# : #value#</li>"); 
 }); 
 

Loop over a Struct using the collection and item arguments of cfloop.

<!--- Define our struct ---> 
 <cfset myStruct = {name: "Tony", state: "Florida"}> 
 <!--- By struct ---> 
 <cfloop item="currentKey" collection="#myStruct#"> 
 <cfoutput><li>#currentKey# : #myStruct[currentKey]#</li></cfoutput> 
 </cfloop>

Lucee 4.5+ Loop over a Struct using the collection, index and item arguments of cfloop.

<!--- Define our struct --->
<cfset myStruct = {name: "Tony", state: "Florida"}>
<!--- By struct --->
<cfloop item="currentItem" collection="#myStruct#" index="currentKey">

<cfoutput><li>#currentKey# : #currentItem#</li></cfoutput>
</cfloop>

List Loop

// Define our list 
 myList = "a, b, c"; 
 // By array 
 for (item in listToArray(myList, ",")) { 
 writeOutput(item); 
 } 
 // By listEach() 
 myList.each(function(element, index) { 
 writeOutput(element & " : " & index); 
 }, ",");

List Loop

<!--- Define our list ---> 
 <cfset myList = "a, b, c"> 
 <!--- By list ---> 
 <cfloop index="item" list="#myList#"> 
 <cfoutput>#item#</cfoutput> 
 </cfloop> 
 <!--- By array ---> 
 <cfloop index="currentIndex" array="#listToArray(myList, ",")#"> 
 <cfoutput>#currentIndex#</cfoutput> 
 </cfloop>

Query Loop

// Define our query 
 platform = ["Adobe ColdFusion", "Railo", "Lucee"]; 
 myQuery = queryNew(" "); 
 queryAddColumn(myQuery, "platform", "CF_SQL_VARCHAR", platform); 
 // By row index 
 for (i = 1; i <= myQuery.recordCount; i++) { 
 writeOutput("<li>#myQuery["platform"][i]#</li>"); 
 } 
 // By query 
 for (row in myQuery) { 
 writeOutput("<li>#row.platform#</li>"); 
 }

Query Loop use grouping

q = queryNew("pk,fk,data", "integer,integer,varchar",[ 
 [1, 10, "aa"], 
 [2, 20, "bb"], 
 [3, 20, "cc"], 
 [4, 30, "dd"], 
 [5, 30, "ee"], 
 [6, 30, "ff"] 
]); 
cfloop(query=q, group="fk"){ 
    writeOutput("<strong>#fk#</strong><br />"); 
    cfloop(){ 
        writeOutput("&emsp;#pk#:#data#<br />"); 
    } 
    writeOutput("<hr>"); 
}

Query Loop

<!--- Define our query ---> 
 <cfset platform = ["Adobe ColdFusion", "Railo", "Lucee"]> 
 <cfset myQuery = queryNew(" ")> 
 <cfset queryAddColumn(myQuery, "platform", "CF_SQL_VARCHAR", platform)> 
 <!--- By row index ---> 
 <cfloop index="i" from="1" to="#myQuery.recordCount#"> 
 <cfoutput><li>#myQuery["platform"][i]#</li></cfoutput> 
 </cfloop> 
 <!--- By group ---> 
 <cfloop query="myQuery" group="platform"> 
 <cfoutput><li>#platform#</li></cfoutput> 
 </cfloop>

Pre-Condition Loop This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true

while (condition) { 
  // statements 
}

Post-Condition Loop This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true

do { 
 // statements 
} while(condition);

File Loop 16 characters at a time.

filePath = getCurrentTemplatePath(); 
 cfloop(file=filePath, index="chars", characters=16, charset="UTF-8"){ 
 writeOutput(chars); // outputs the contents of this file 
 }

Date-Time range Loop (work around)

from = now(); 
 to   = dateAdd("d", 7, from); 
 for(date=from; dateCompare(date, to, "d") <= 0; date = dateAdd("d", 1, date)){ 
 writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "<br>"); 
 }

Signup for cfbreak to stay updated on the latest news from the ColdFusion / CFML community. One email, every friday.

Fork me on GitHub