CFLOOP How-To
Remarks#
Big thanks to
- Pete Freitag for his CFScript Cheat Sheet
- Adam Cameron for CF 11: CFLOOP in CFScript is Very Broken (and it still is in CF 2016).
Looping through a collection using CFML tags.
Looping through a collection using CFSCRIPT.
Index
Parameters
Attribute | Required | Type | Default | Description |
---|---|---|---|---|
index | true | string | Variable name for the loop’s index. Defaults to the variables scope. |
|
from | true | numeric | Starting value for the index. | |
to | true | numeric | Ending value for the index. | |
step | false | numeric | 1 | Value by which to increase or decrease the index per iteration. |
Basic index loop
Final value of
x
is 10.
<!--- Tags --->
<cfoutput>
<cfloop index="x" from="1" to="10">
<li>#x#</li>
</cfloop>
</cfoutput>
<!--- cfscript --->
<cfscript>
for (x = 1; x <= 10; x++) {
writeOutput('<li>' & x & '</li>');
}
</cfscript>
<!--- HTML Output --->
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Increase step to 2
Final value of
x
is 11.
<!--- Tags --->
<cfoutput>
<cfloop index="x" from="1" to="10" step="2">
<li>#x#</li>
</cfloop>
</cfoutput>
<!--- cfscript --->
<cfscript>
for (x = 1; x <= 10; x += 2) {
writeOutput('<li>' & x & '</li>');
}
</cfscript>
<!--- HTML Output --->
- 1
- 3
- 5
- 7
- 9
Decrement step by 1
Final value of
x
is 0.
<!--- Tags --->
<cfoutput>
<cfloop index="x" from="10" to="1" step="-1">
<li>#x#</li>
</cfloop>
</cfoutput>
<!--- cfscript --->
<cfscript>
for (x = 10; x > 0; x--) {
writeOutput('<li>' & x & '</li>');
}
</cfscript>
<!--- HTML Output --->
- 10
- 9
- 8
- 7
- 6
- 5
- 4
- 3
- 2
- 1
CFLoop in a Function
Make sure to
var
orlocal
scope the index inside a function.Foo()
returns 11.
<!--- var scope --->
<cffunction name="foo" access="public" output="false" returntype="numeric">
<cfset var x = 0 />
<cfloop index="x" from="1" to="10" step="1">
<cfset x++ />
</cfloop>
<cfreturn x />
</cffunction>
<!--- Local scope --->
<cffunction name="foo" access="public" output="false" returntype="numeric">
<cfloop index="local.x" from="1" to="10" step="1">
<cfset local.x++ />
</cfloop>
<cfreturn local.x />
</cffunction>
ColdFusion 11 through current
The cfscript function
cfloop
has no support forindex
as a stand alone counter mechanism.
Condition
Tag syntax
Parameters
Attribute | Required | Type | Default | Description |
---|---|---|---|---|
condition | true | string | Condition that manages the loop. Cannot contain math symbols like < , > or = . Must use ColdFusion text implementations like less than , lt , greater than , gt , equals or eq . |
Final value of x
is 5.
<cfset x = 0 />
<cfoutput>
<cfloop condition="x LT 5">
<cfset x++ />
<li>#x#</li>
</cfloop>
</cfoutput>
Generated HTML
This will also have a line break between each line of HTML.
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
CFScript
Previous to ColdFusion 8
<cfscript>
x = 0;
while (x LT 5) {
x = x + 1;
writeOutput('<li>' & x & '</li>');
}
</cfscript>
ColdFusion 8 through current
<cfscript>
x = 0;
while (x LT 5) {
x = x++;
writeOutput('<li>' & x & '</li>');
}
</cfscript>
ColdFusion 11 through current
The cfscript function
cfloop
has no support forcondition
.
Generated HTML
Notice that the cfscript output is all on one line.
<li>one</li><li>two</li><li>three</li><li>four</li>
Date or time range
Example for date or time range.
Query
Consider the table dbo.state_zip
, which contains the columns city
, statecode
and zipcode
and has over 80,000 records.
Parameters
Attribute | Required | Type | Default | Description |
---|---|---|---|---|
query | true | string | The variable name of a query object. | |
startrow | false | numeric | The starting row index of the query object. | |
endrow | false | numeric | The ending row index of the query object. | |
group | false | string | The query column name on which to group records. |
Example query
<cfquery name="geo" datasource="reotrans-dev">
SELECT city, stateCode, zipCode
FROM dbo.state_zip
</cfquery>
Tag syntax
Using the query object geo
as the source for cfloop
. Since the table dbo.state_zip
has so many records, the HTML generated will take quite some time. This example shows only the first 20 records’ worth of HTML.
<cfoutput>
<ul>
<cfloop query="geo">
<!--- Scope the column names with the query name. --->
<li>#geo.city# | #geo.stateCode# | #geo.zipCode#</li>
</cfloop>
</ul>
</cfoutput>
Generated HTML
```- 100 PALMS | CA | 92274
- 1000 PALMS | CA | 92276
- 12 MILE | IN | 46988
- 1ST NATIONAL BANK OF OMAHA | NE | 68197
- 29 PALMS | CA | 92277
- 29 PALMS | CA | 92278
- 3 STATE FARM PLAZA | IL | 61710
- 3 STATE FARM PLAZA | IL | 61791
- 30TH STREET | PA | 19104
- 3M CORP | MN | 55144
- 65TH INFANTRY | PR | 00923
- 65TH INFANTRY | PR | 00924
- 65TH INFANTRY | PR | 00929
- 65TH INFANTRY | PR | 00936
- 7 CORNERS | VA | 22044
- 88 | KY | 42130
- 9 MILE POINT | LA | 70094
- A A R P INS | PA | 19187
- A A R P PHARMACY | CT | 06167
- A H MCCOY FEDERAL BLDG | MS | 39269
Limiting output to specific rows
To limit the query’s output to a specific range of rows, specify startrow
and endrow
.
<cfloop query="geo" startrow="100" endrow="150">
<li>#geo.city# | #geo.stateCode# | #geo.zipCode#</li>
</cfloop>
Grouping Output
In the example data, the same state listed multiple times in relation to the multiple cities that are associated to each state. You can also see the same city listed multiple times in relation to the multiple zip codes associated to each city.
Let’s group the output by state first. Notice the 2nd instance of cfloop
wrapped around the content that will be output under the stateCode
grouped content.
<cfoutput>
<ul>
<cfloop query="geo" group="stateCode">
<!--- Scope the column names with the query name. --->
<li>#geo.stateCode#
<ul>
<cfloop>
<li>#geo.city# | #geo.zipCode#</li>
</cfloop>
</ul>
</li>
</cfloop>
</ul>
</cfoutput>
Generated HTML (extract) from one grouped cfloop
tag.
<ul>
<li>AK
<ul>
<li>KONGIGANAK | 99545</li>
<li>ADAK | 99546</li>
<li>ATKA | 99547</li>
<!-- etc. -->
</ul>
</li>
<li>AL
<ul>
<li>ALEX CITY | 35010</li>
<li>ALEXANDER CITY | 35010</li>
<li>ALEX CITY | 35011</li>
<!-- etc. -->
</ul>
</li>
<!-- etc. -->
</ul>
Finally, let’s group the output by stateCode
, then by city
in order to see all the zipCode
entries per city. Notice the 2nd cfloop
is now grouped by city
and a 3rd cfloop
exists to output the zipCode
data.
<cfoutput>
<ul>
<cfloop query="geo" group="stateCode">
<li>#geo.stateCode#
<ul>
<cfloop group="city">
<li>#geo.city#
<ul>
<cfloop>
<li>#geo.zipCode#</li>
</cfloop>
</ul>
</li>
</cfloop>
</ul>
</li>
</cfloop>
</ul>
</cfoutput>
Generated HTML (extract) from two grouped cfloop
tags.
<ul>
<li>AK
<ul>
<li>ADAK
<ul>
<li>99546</li>
<li>99571</li>
</ul>
</li>
<li>AKHIOK
<ul>
<li>99615</li>
</ul>
</li>
<!--- etc. --->
<li>BARROW
<ul>
<li>99723</li>
<li>99759</li>
<li>99789</li>
<li>99791</li>
</ul>
</li>
<!--- etc. --->
</ul>
</li>
<!--- stateCodes etc. --->
</ul>
CFScript
ColdFusion 6 (MX) though current
```ColdFusion 8 though current
```ColdFusion 10 though current
> With the `FOR IN` syntax, `x` is a query row object, not the row index.<cfscript>
for (x in geo) {
writeOutput( '<li>' & x.city & ' | ' &
x.stateCode & ' | ' & x.zipCode & '</li>');
}
</cfscript>
ColdFusion 11 though current
> ColdFusion 11 allows most tags to be written as cfscript. ```- ');
cfloop() { // no arguments, just as in the tag syntax.
writeOutput('
- ' & geo.zipCode & ' '); } writeOutput('
List
Consider this list:
<cfset foo = "one,two,three,four" />
Tag syntax
Parameters
Attribute | Required | Default | Description |
---|---|---|---|
list | true | A list object. The variable must be evaluated (wrapped with ##) | |
index | true | The current element of the list. | |
``` | |||
<cfloop list="#foo#" index="x">
<li>#x#</li>
</cfloop>
Generated HTML
This will also have a line break between each line of HTML.
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
CFScript
Previous to ColdFusion 8
<cfscript>
for (x = 1; x LTE listLen(foo); x = x + 1) {
writeOutput("<li>" & listGetAt(foo, x) & "</li>");
}
</cfscript>
ColdFusion 8 through current
<cfscript>
for (x = 1; x <= listLen(foo); x++) {
writeOutput("<li>" & listGetAt(foo, x) & "</li>");
}
</cfscript>
ColdFusion 9 through current
<cfscript>
for (x in foo) {
writeOutput("<li>" & x & "</li>");
}
</cfscript>
ColdFusion 11 through current
The cfscript function
cfloop
has no support forlist
.
Generated HTML
Notice that the cfscript output is all on one line.
<li>one</li><li>two</li><li>three</li><li>four</li>
Array
The ability to directly use an
array
object withcfloop
was added in ColdFusion 8.
Consider this array;
<cfset aFoo = [
"one"
, "two"
, "three"
, "four"
] />
Tag syntax
ColdFusion 8 through current
Using the attribute index
by itself.
Parameters
Attribute | Required | Default | Description |
---|---|---|---|
array | true | An array object. The variable must be evaluated (wrapped with ##) | |
index | true | The current element of the array. | |
``` | |||
<cfloop array="#aFoo#" index="x">
<li>#x#</li>
</cfloop>
Generated HTML
This will also have a line break between each line of HTML.
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
ColdFusion 2016 through current
The attribute
item
changes the behavior ofcfloop
as of Coldfusion 2016.
Using the attribute item
instead of or in addition to index
.
Parameters
Attribute | Required | Default | Description |
---|---|---|---|
array | true | An array object. The variable must be evaluated (wrapped with ##) | |
item | true | The current element of the array. | |
index | false | The current index of the array. | |
``` | |||
<cfloop array="#aFoo#" item="x" index="y">
<li>#x# | #y#</li>
</cfloop>
Generated HTML
This will also have a line break between each line of HTML.
<li>one | 1</li>
<li>two | 2</li>
<li>three | 3</li>
<li>four | 4</li>
CFScript
Previous to ColdFusion 8
<cfscript>
for (i = 1; x LTE arrayLen(aFoo); i = i + 1) {
writeOutput("<li>" & aFoo[i] & "</li>");
}
</cfscript>
ColdFusion 8 through current
<cfscript>
for (i = 1; i <= arrayLen(aFoo); i = i++) {
writeOutput("<li>" & aFoo[i] & "</li>");
}
</cfscript>
ColdFusion 9 through current
With the
FOR IN
syntax, x is the current array element, not the array index.
<cfscript>
for (x in aFoo) {
writeOutput("<li>" & x & "</li>");
}
</cfscript>
ColdFusion 11 through current
> The cfscript function `cfloop` has no support for `array`.Generated HTML
Notice that the cfscript
output is all on one line.
<li>one</li><li>two</li><li>three</li><li>four</li>
File
<cfloop list="#myFile#" index="FileItem" delimiters="#chr(10)##chr(13)#">
<cfoutput>
#FileItem#<br />
</cfoutput>
</cfloop>
Structure
Consider this structure:
<cfset stFoo = {
a = "one"
, b = "two"
, c = "three"
, d = "foue"
} />
Tag syntax
Parameters
Notice the use of the attribute
item
instead ofindex
.
Attribute | Required | Type | Default | Description |
---|---|---|---|---|
collection | true | structure | A struct object. The variable must be evaluated (wrapped with ##). |
|
item | true | string | The current structure key , |
Using Structure Functions
<cfoutput>
<cfloop collection="#stFoo#" item="x">
<li>#structFind(stFoo, x)#</li>
</cfloop>
</cfoutput>
Implicit Structure Syntax
<cfoutput>
<cfloop collection="#stFoo#" item="x">
<li>#stFoo[x]#</li>
</cfloop>
</cfoutput>
Generated HTML
This will also have a line break between each line of HTML.
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
CFScript
With the
FOR IN
syntax,x
is akey
of the structure object.
Output the structure's keys
<cfscript>
for (x in stFoo) {
writeOutput("<li>" & x & "</li>");
}
</cfscript>
Generated HTML
```Output the value of the structure's keys
Using Structure Functions
<cfscript>
for (x in stFoo) {
writeOutput("<li>" & structFind(stFoo, x) & "</li>");
}
</cfscript>
Implicit Structure Syntax
<cfscript>
for (x in stFoo) {
writeOutput("<li>" & stFoo[x] & "</li>");
}
</cfscript>
ColdFusion 11 through current
The cfscript function
cfloop
has no support forcollection
.
Generated HTML
Notice that the cfscript output is all on one line.
<li>one</li><li>two</li><li>three</li><li>four</li>