Another popular way to control the flow of an application is through the use of loops. Like IF statements, loops are an integral part of almost all programming languages. The concept of a loop is quite simple. By using a loop, we can get our application to loop over a particular piece of code over and over again until a certain condition is met. We have seen the concept of looping in action already in Step 3, "Databases and SQL." When we used <CFOUTPUT> with the QUERY attribute to display the results of a database query, <CFOUTPUT> looped over our recordset over and over again until we ran out of records to display. That looping functionality is built into <CFOUTPUT> when the QUERY attribute is used. If we want to loop over some other block of code, we can use the <CFLOOP> tag. Types of Loops We can use several types of loops with ColdFusion: Index loops. These repeat a set number of times (for example, 10 times). Conditional loops. These run while a certain condition is met (for example, while x is less than 10). List loops. These loop through all the values in a list. Query loops. These can be used to loop over query results similar to <CFOUTPUT>. Collection loops. These loop over a collection of items, such as the collection of fields submitted via a form or any other structure. In this step, we will look at Index loops and Conditional (or While) loops. Other types of loops will be covered in future steps. <CFLOOP> To create a loop, we use the <CFLOOP> tag. The <CFLOOP> tag is a container tag and requires a closing tag. <CFLOOP> also has many attributes. The attributes that are required depend on the type of loop being used. See the "Reference" section of the www.LearnColdFusionMX.com web site for a complete reference. Table 4.3 lists all the attributes for the <CFLOOP> tag. Table 4.3. <CFLOOP> Attributes Attribute | Use | Notes |
---|
COLLECTION | Used with collection type loops | The name of the collection to loop through | CONDITION | Used with While loops | The condition that a While loop will evaluate prior to execution | DELIMITERS | Used with List loops | Used if the delimiter in a list is something other than a comma | ENDROW | Used with Query loops | Used if you do not want to output all rows of a query | FROM | The Index loop start position | A numerical value that indicates where an Index loop will begin counting | INDEX | Used with Index and List loops | A variable that contains the current value in the loop | ITEM | Used with Collection loops | Contains the current item being looped over | LIST | Used with List loops | The list to be looped over | QUERY | Used with Query loops | The name of the query to be looped over | STARTROW | Used with Query loops | The row number to begin the loop if not starting from the first row | STEP | Used with Index loops | The interval to be used when counting | TO | Used with Index loops | A numerical value that indicates where an Index loop will stop counting | Index Loops The following code illustrates how we could use <CFLOOP> to create a list of 20 items with an Index loop: <HTML> <HEAD> <TITLE>Index Loop</TITLE> </HEAD> <BODY> <CFLOOP INDEX="x" FROM="1" TO="20"> <CFOUTPUT> Item #x#<BR> </CFOUTPUT> </CFLOOP> </BODY> </HTML> The Index loop requires three pieces of information. First we use the FROM attribute to tell the loop where to start counting; in this case, we start from 1. Next we use the TO attribute to tell the loop when to stop counting; in this case, we stop at 20. Finally, we use the INDEX attribute to nominate a variable to hold the current value in the loop (in this case "x"). With the preceding code, we have created a loop that will start at 1 and run through the loop. When the bottom of the loop is reached (the closing </CFLOOP> tag), the flow goes back up to the top of the loop and the INDEX value increments. The loop will execute again, but this time with a value of 2. This will continue until the INDEX value exceeds that of the TO attribute, in this case 20. We will then break out of the loop and continue with the rest of the code below the closing </CFLOOP> tag. While the loop is executing, we will store the current loop value in a variable. The name of the variable is specified by using the INDEX attribute of the <CFLOOP> tag. In this example, we will store the value of the loop INDEX in a variable named "x". We output the value of this variable the same way we output any variable, by using the <CFOUTPUT> tag. The first time the loop executes, the value of x is 1. We then output the text Item 1. We reach the end of the loop and start again at the top. This time through the loop, the value of x is 2, and we output Item 2. This pattern repeats until we reach 20. After the value of 20 has been exceeded, we are finished with the loop, and the execution of code below the closing </CFLOOP> tag continues as normal. Figure 4.2. Index loop output. NOTE You can also use an Index loop to loop through the results of a query. Take a look at the following code: <!--- query the database ---> <CFQUERY NAME="qEmployees" DATASOURCE="Staff"> SELECT FirstName, LastName FROM Employees </CFQUERY> <!--- step through the query with an index loop ---> <CFLOOP INDEX="x" FROM="1" TO="#qEmployees.RecordCount#"> <CFOUTPUT>#qEmployees.LastName[x]#, #qEmployees.FirstName[x]# <BR></CFOUTPUT> </CFLOOP> In this code, we use a standard query to grab all of our employees' names. We then tell the Index loop to start at 1 and loop through to the dynamic value of qEmployee.RecordCount (which might change each time the query is run). We then use <CFOUTPUT> to spit out each employee's name based on what row he is in the query. The current row we are outputting is determined by the INDEX value [x]. While Loops An Index loop will always loop a certain number of times, as specified by the FROM and TO attributes. A While loop is somewhat different; it will execute until a specified condition becomes FALSE. For example, we might want to check the value of a variable and continue to loop until the value of that variable meets a certain condition. The following code illustrates the use of a While loop: <HTML> <HEAD> <TITLE>While Loop</TITLE> </HEAD> <BODY> <!--- set x equal to 1 ---> <CFSET x=1> <!--- loop as long as x is less than 5 ---> <CFLOOP CONDITION="x LT 5"> <!--- display the current value of x ---> <CFOUTPUT>The value of x is #x#<BR></CFOUTPUT> <!--- add 1 to the current value of x ---> <CFSET x=x+1> </CFLOOP> </BODY> </HTML> Figure 4.3. While loop output. In the preceding loop, we begin by setting the value of x to 1 with a <CFSET> tag. We then begin the loop with x being equal to 1. The CONDITION attribute of the <CFLOOP> tag checks to see if x is less than 5, which it is. Because the condition we are checking for evaluates to TRUE, we begin the loop. The loop outputs the value of x (in this case, 1) and then adds 1 to the current value of x. We reach the bottom of the loop and begin again at the top, this time with x being equal to 2. The looping pattern continues until x equals 4. The <CFOUTPUT> tag then outputs, The value of x is 4. The <CFSET> tag then increments the value of x to 5. We go back to the top of the loop and evaluate the statement in the CONDITION attribute. Because x is now 5 (and 5 is not less than 5), the condition evaluates to FALSE, and we do not enter the loop again. Instead, we jump over the loop and begin executing the code below the closing </CFLOOP> tag. NOTE Try reversing the position of the <CFOUTPUT> and <CFSET> lines within the loop and see what happens. <CFBREAK> There might be a time during the course of a loop when we want to exit the loop if a particular event occurs. To accomplish this, you can use the <CFBREAK> tag. The <CFBREAK> stops the processing of a loop. Execution then jumps to the bottom of the loop and continues from there. The <CFBREAK> tag must be used between opening and closing <CFLOOP> tags, and it has no attributes. For example, if I were a superstitious person, I might never want to view the number 13. Going back to our Index loop code, I could put in a <CFBREAK> tag to stop loop processing if I come across the number 13. <HTML> <HEAD> <TITLE>Break</TITLE> </HEAD> <BODY> <CFLOOP INDEX="x" FROM="1" TO="20"> <!--- break out of the loop if we come across 13 ---> <CFIF x IS 13> <CFBREAK> </CFIF> <!--- output the item number ---> <CFOUTPUT> Item #x#<BR> </CFOUTPUT> </CFLOOP>Done </BODY> </HTML> The preceding code would produce the page displayed in Figure 4.4. Figure 4.4. The Index loop dislay using <CFBREAK>. |