If the name is John or Robert, it sets both the male variable and the found variable to True.
CFScript includes the following types of statements:
- Assignment statements and functions
- Conditional processing statements
- Looping statements
Using assignment statements and functions
CFScript assignment statements are the equivalent of the cfset tag. These statements have the following form:
lval = expression;
eval is any ColdFusion variable reference; for example:
x = "positive"; y = x; a[3]=5; structure.member=10; ArrayCopy=myArray;
You can use ColdFusion function calls, including UDFs, directly in CFScript. For example, the following line is a valid CFScript statement:
StructInsert(employee,"lastname",FORM.lastname);
Using conditional processing statements
CFScript includes the following conditional processing statements:
- if and else statements, which serve the same purpose as the cfif, cfelseif, and cfelse tags
- switch, case, and default statements, which are the equivalents of the cfswitch, cfcase, and cfdefaultcase tags
Using if and else statements
The if and else statements have the following syntax:
if(expr) statement [else statement]
In its simplest form, an if statement looks as follows:
if(value EQ 2700) message = "You've reached the maximum";
A simple if-else statement looks like the following:
if(score GT 1) result = "positive"; else result = "negative";
CFScript does not include an elseif statement. However, you can use an if statement immediately after an else statement to create the equivalent of a cfelseif tag, as the following example shows:
if(score GT 1) result = "positive"; else if(score EQ 0) result = "zero"; else result = "negative";
As with all conditional processing statements, you can use curly brackets to enclose multiple statements for each condition, as follows:
if(score GT 1) { result = "positive"; message = "The result was positive."; } else { result = "negative"; message = "The result was negative."; }
Often, you can make your code clearer by using braces even where they are not required.
Using switch and case statements
The switch statement and its dependent case and default statements have the following syntax:
switch (expression) { case constant: [case constant:]... statement(s) break; [case constant: [case constant:]... statement(s) break;]... [default: statement(s)] }
Use the following rules and recommendations for switch statements:
- You cannot mix Boolean and numeric constant values in a switch statement.
- Each constant value must be a constant (that is, not a variable, a function, or other expression).
- Multiple case constant: statements can precede the statement or statements to execute if any of the cases are true. This lets you specify several matches for one code block.
- No two constant values can be the same.
- The statements following the colon in a case statement block do not have to be in curly brackets. If a constant value equals the switch expression, ColdFusion executes all statements through the breakstatement.
- The break statement at the end of the case statement tells ColdFusion to exit the switch statement. ColdFusion does not generate an error message if you omit a break statement. However, if you omit it, ColdFusion executes all the statements in the following case statement, even if that case is false. In nearly all circumstances, this is not what you want to do.
- You can have only one default statement in a switch statement block. ColdFusion executes the statements in the default block if none of the case statement constants equals the expression value.
- The default statement does not have to follow all case statements, but it is good programming practice to do so. If any case statements follow the default statement, you must end the default block code with a break statement.
- The default statement is not required. However, use one if the case constants do not include all possible values of the expression.
The following switch statement takes the value of a name variable:
-
-
If the name is Mary, it sets the male variable to False and the found variable to True.
-
Otherwise, it sets the found variable to False.
switch(name) { case "John": case "Robert": male=True; found=True; break; case "Mary": male=False; found=True; break; default: found=False; } //end switch
Dynamic switch case
In earlier versions of ColdFusion, Switch Cases were static. The value of a Case statement had to be hard coded in the source code.
In ColdFusion (2021 release), switch cases are dynamic values. Both script and tag syntax are supported.
The following examples show the usage of dynamic switch case.
Tag syntax
<cfswitch expression="#(() => 1)()#" > <cfcase value="5">I like kiwi!</cfcase> <cfcase value="#(5 GT 1)#">I like Orange!</cfcase> <cfdefaultcase>Fruit, what fruit?</cfdefaultcase> </cfswitch>
Output
I like Orange!
Arithmetic operator
<cfscript> s=-1 switch((()=> 1)()) { case 3/4: writeoutput("22") break; case s+ 2: writeoutput("21") break; } </cfscript>
Output
21
Variable reference
<cfscript> s=123 switch((()=> 123)()) { case s: writeoutput("21") break; } </cfscript>
Output
21
Default case
<cfscript> s = 125; switch((()=> 125)()) { case 20 : default : writeoutput("6") break; case s : writeoutput("21") break; } switch((()=> 125)()) { case s : case 125 : writeoutput("21") break; default : writeoutput("6") break; } switch((()=> 125)()) { default : writeoutput("6") break; case 125 : writeoutput("21") break; } </cfscript>
Output
212121
UDF
<cfscript> public string function f() { return "yes" } switch((()=> "yes")()) { case round(3.14159): writeoutput("22") break; case f(): writeoutput("23") break; default: writedump("via UDF") } </cfscript>
Output
23
Unary operator
<cfscript> s = 123 switch((()=> 125)()) { case -(-s) + 2: writeoutput("22") break; } </cfscript>
Output
22
Ternary operator
<cfscript> switch((()=> "hi")()) { case (5 GT 1)? "h" & "i" : "hello" : writeoutput("21") break; } </cfscript>
Output
21
String operator
<cfscript> switch((()=> "hi")()) { case "h" & "i" : writeoutput("21") break; } </cfscript>
Output
21
Logical operator
<cfscript> public string function f() { return "yes" } switch((()=> true)()) { case f() && false: writeoutput("23") break; case !f(): writeoutput("22") break; case !(6 - 3 * 2): writeoutput("22") break; } </cfscript>
Output
22
IIFE
<cfswitch expression="#(() => 1)()#" > <cfcase value="#(()=> 1)()#" >I like kiwi!</cfcase> </cfswitch>
Output
I like kiwi!
Array reference
<cfscript> b = [2, 21, 211] switch((()=> 1)()) { case 1 + Round(3.14159)/Round(3.14159): writeoutput("22") break; case b[1] - 1: writeoutput("21") break; } </cfscript>
Output
21
Struct reference
<cfscript> b = { e = 2, f = 21, g = 211} switch((()=> 21)()) { case b.e: writeoutput("2"); break; case b.f: writeoutput("21") ; break; } </cfscript>
Output
21
Using looping statements
CFScript provides a richer selection of looping constructs than those supplied by CFML tags. It enables you to create efficient looping constructs like those in most programming and scripting languages. CFScript provides the following looping constructs:
- For
- While
- Do-while
- For-in
CFScript also includes the continue and break statements that control loop processing.
Using for loops
The for loop has the following format:
for (initial-expression; test-expression; final-expression) statement
The i_nitial-expression_ and final-expression can be one of the following:
- A single assignment expression; for example, x=5 or loop=loop+1
- Any ColdFusion expression; for example, SetVariable("a",a+1)
- Empty
The test-expression can be one of the following:
Any ColdFusion expression; for example:
A LT 5 index LE x status EQ "not found" AND index LT end
- Empty
The test expression is re-evaluated before each repeat of the loop. If code inside the loop changes any part of the test expression, it can affect the number of iterations in the loop.
The statement can be a single semicolon terminated statement or a statement block in curly brackets.
When ColdFusion executes a for loop, it does the following:
-
Evaluates the initial expression.
-
Evaluates the test-expression.
-
If the test-expression is False, exits the loop and processing continues following the statement._If the _test-expressionis True:
a. Executes the statement (or statement block).
b. Evaluates the final-expression .
c. Returns to Step 2.
For loops are most commonly used for processing in which an index variable is incremented each time through the loop, but it is not limited to this use.
The following simple for loop sets each element in a 10-element array with its index number.
for(index=1; index LTE 10; index = index + 1) a[index]=index;
The following, more complex, example demonstrates two features:
- The use of curly brackets to group multiple statements into a single block.
- An empty condition statement. All loop control logic is in the statement block.
<cfscript> strings=ArrayNew(1); ArraySet(strings, 1, 10, "lock"); strings[5]="key"; indx=0; for( ; ; ) { indx=indx+1; if(Find("key",strings[indx],1)) { WriteOutput("Found key at " & indx & ".<br>"); break; } else if (indx IS ArrayLen(strings)) { WriteOutput("Exited at " & indx & ".<br>"); break; } } </cfscript>
This example shows one important issue that you must remember when creating loops: always ensure that the loop ends. If this example lacked the else if statement, and there was no "key" in the array, ColdFusion would loop forever or until a system error occurred; you would have to stop the server to end the loop.
The example also shows two issues with index arithmetic: in this form of loop you must make sure to initialize the index, and keep track of where the index is incremented. In this case, because the index is incremented at the top of the loop, initialize it to 0 so it becomes 1 in the first loop.
Using while loops
The while loop has the following format:
while (expression) statement
The while statement does the following:
- Evaluates the expression.
- If the expressionis True, it does the following:
- Executes the statement, which can be a single semicolon-terminated statement or a statement block in curly brackets.
Returns to step 1.
If the expression is False, processing continues with the next statement.The following example uses a whileloop to populate a 10-element array with multiples of five.
a = ArrayNew(1); loop = 1; while (loop LE 10) { a[loop] = loop * 5; loop = loop + 1; }
As with other loops, make sure that at some point the{{ while}} expression is False and be careful to check your index arithmetic.
Using do-while loops
The do-while loop is like a while loop, except that it tests the loop condition after executing the loop statement block. The do-while loop has the following format:
do statement while (expression);
The do while statement does the following:
-
Executes the statement, which can be a single semicolon-terminated statement or a statement block in curly brackets.
-
Evaluates the expression.
-
If the expression is true, it returns to step 1.
If the expression is False, processing continues with the next statement.
The following example, like the while loop example, populates a 10-element array with multiples of 5:
a = ArrayNew(1); loop = 1; do { a[loop] = loop * 5; loop = loop + 1; } while (loop LE 10);
Because the loop index increment follows the array value assignment, the example initializes the loop variable to 1 and tests to make sure that it is less than or equal to 10.
The following example generates the same results as the previous two examples, but it increments the index before assigning the array value. As a result, it initializes the index to 0, and the end condition tests that the index is less than 10.
a = ArrayNew(1); loop = 0; do { loop = loop + 1; a[loop] = loop * 5; } while (loop LT 10);
The following example loops through a query:
<cfquery ... name="myQuery"> ... sql goes here... </cfquery> <cfscript> if (myQuery.RecordCount gt 0) { currRow=1; do { theValue=myQuery.myField[CurrRow]; currRow=currRow+1; } while (currRow LTE myQuery.RecordCount); } </cfscript>
Using for-in loops
The for-in loop loops over the elements in a ColdFusion structure. It has the following format:
for (variable in structure) statement
The variable can be any ColdFusion identifier; it holds each structure key name as ColdFusion loops through the structure. The structure must be the name of an existing ColdFusion structure. The statement can be a single semicolon terminated statement or a statement block in reference.
The following example creates a structure with three elements. It then loops through the structure and displays the name and value of each key. Although the curly brackets are not required here, they make it easier to determine the contents of the relatively long WriteOutput function. In general, you can make structured control flow, especially loops, clearer by using curly brackets.
myStruct=StructNew(); myStruct.productName="kumquat"; mystruct.quality="fine"; myStruct.quantity=25; for (keyName in myStruct) { WriteOutput("myStruct." & Keyname & " has the value: " & myStruct[keyName] &"<br>"); }
Unlike the cfloop tag, CFScript for-in loops do not provide built-in support for looping over queries and lists.
Using continue and break statements
The continue and break statements enable you to control the processing inside loops:
- The continue statement tells ColdFusion to skip to the beginning of the next loop iteration.
- The break statement exits the current loop or case statement.
Using continue
The continue statement ends the current loop iteration, skips any code following it in the loop, and jumps to the beginning of the next loop iteration. For example, the following code loops through an array and display's each value that is not an empty string:
for ( loop=1; loop LE 10; loop = loop+1) { if(a[loop] EQ "") continue; WriteOutput(loop); }
(To test this code snippet, you must first create an array, a, with 10 or more elements, some of which are not empty strings.)
The continue statement is useful if you loop over arrays or structures and you want to skip processing for array elements or structure members with specific values, such as the empty string.
Using break
The break statement exits the current loop or case statement. Processing continues at the next CFScript statement. You end case statement processing blocks with a break statement. You can also use a test case with a break statement to prevent infinite loops, as shown in the following example. This script loops through an array and prints the array indexes that contain the value key. It uses a conditional test and abreak statement to make sure that the loop ends when at the end of the array.
strings=ArrayNew(1); ArraySet(strings, 1, 10, "lock"); strings[5]="key"; strings[9]="key"; indx=0; for( ; ; ) { indx=indx+1; if(Find("key",strings[indx],1)) { WriteOutput("Found a key at " & indx & ".<br>"); } else if (indx IS ArrayLen(strings)) { WriteOutput("Array ends at index " & indx & ".<br>"); break; } }
for-in construct (for arrays)
You can loop over arrays in CFScript using for-in construct.
h7. Example
public String foo(array a) { for(var item in a) { writedump(item); } }
for-in construct (for query)
Similar to looping over array and struct, using for-in construct, you can loop over query object in CFScript.
h7. Example
In this example, query resultset is available in the variable arts and the for-in loop is used to loop over the resultset. The variable row used in the for-in construct is a struct that contains query columns as keys. You can use arts.currentrow to reference the current row.
<cfquery name="arts" datasource="cfartgallery"> select * from art </cfquery> <cfscript> cols = listToArray(listsort(arts.columnlist, "textnocase")); for(row in arts) { for(col in cols) writeoutput(arts.currentrow & " ..." & col & ": " & row[col] & "<br>"); writeoutput("<hr>"); } </cfscript>
You have to prefix queryname to access the query result variables such as recordcount or currentrow (as shown in the example).
var declaration within for loop
This feature applies only if you have installed ColdFusion 9 Update 1.
You can use var inline with for-in construct to bind variable to the local scope for both structs and arrays.
Example
public String foo(struct s) { for(var item in s) { writedump(item & ": " & s[item]); } writedump(local); }
For arrays example, see for-in construct (for arrays).
For-in constructs support Java arrays
Apart from native ColdFusion arrays, for-in constructs now support Java arrays as shown in the following example:
<cfscript> a = CreateObject("java","java.util.Arrays").AsList(ToString("CF,10,Zeus").split(",")); for (var1 in a) { WriteOutput(var1); } </cfscript>
Label support for loops with break and continue
In any programming paradigm a developer has to write some code dealing with loops. Loops are beneficial when we have to do some repetitive tasks. Most developers write the code of multiple loops, loops within a loop etc. In complex scenarios, there are situations in which a developer has to break out of the outer loop while iterating in an inner loop.
Loop Syntax
// For Loop: <OuterLabel> : for(){ <InnerLabel> : for(){ break OuterLabel; continue OuterLabel; } }
*// While Loop: <OuterLabel> : while(){ <InnerLabel> : while(){ break OuterLabel; continue OuterLabel; } }
Labels are the corresponding points which can be used as trace marks to break or continue within a loop. <Labels> will be used by corresponding break and continue statements to (break out)/(continue from) the corresponding loop at which the label is defined. In general if we write just break; or continue; statements it breaks out or continue from the closest loops from where the corresponding statement is executed.
Break and Continue Syntax
break <label>; // where label is defined before the start of for/while loop
continue <label>; // where label is defined before the start of for/while loop
Example 1
<cfscript> xyz : for(i=110;i<115;i++){ abc : for(j=10;j<20;j++) { writeDump(i); if(j%3 == 0) continue xyz; writeDump(j); } writeDump("<br>"); } </cfscript>
Output
110 10 110 11 110 111 10 111 11 111 112 10 112 11 112 113 10 113 11 113 114 10 114 11 114
Example 2
<cfscript> // breaking out using a label x = 0; WhileLabel: while (x < 10){ writeOutput("x is #x#<br>"); switch (x){ case 1: break; case 3: break WhileLabel; } x++; writeOutput("end of of loop<br>"); } writeOutput("After loop, x is #x#<br>"); </cfscript>
Output
x is 0
end of of loop
x is 1
end of of loop
x is 2
end of of loop
x is 3
After loop, x is 3
Example 3
<cfloop index="i" from="1" to="10" label="xyz"> <cfoutput>#i#</cfoutput> <br> <cfif i Ge 5> <cfcontinue xyz> </cfif> <cfoutput>#i#->#i#</cfoutput> <br> </cfloop>
Output
1
1->1
2
2->2
3
3->3
4
4->4
5
6
7
8
9
10