Class Loop
java.lang.Object
ortus.boxlang.runtime.components.Component
ortus.boxlang.runtime.components.system.Loop
@BoxComponent(description="Create loops for iterating over collections and ranges",
requiresBody=true)
public class Loop
extends Component
The Loop component provides various iteration mechanisms for BoxLang applications.
This component is the BoxLang equivalent of ColdFusion's cfloop tag and supports
multiple loop types including query loops, array loops, list loops, collection loops,
conditional loops, numeric range loops, file iteration, and grouped query loops.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class ortus.boxlang.runtime.components.Component
Component.BodyResult, Component.ComponentBody -
Field Summary
Fields inherited from class ortus.boxlang.runtime.components.Component
componentService, declaredAttributes, DEFAULT_RETURN, functionService, ignoreEnableOutputOnly, interceptorService, logger, name, runtime -
Constructor Summary
ConstructorsConstructorDescriptionLoop()Constructs a new Loop component with all supported attributes configured. -
Method Summary
Modifier and TypeMethodDescription_invoke(IBoxContext context, IStruct attributes, Component.ComponentBody body, IStruct executionState) Executes the appropriate loop type based on the provided attributes.Methods inherited from class ortus.boxlang.runtime.components.Component
announce, getDeclaredAttributes, getName, invoke, isIgnoreEnableOutputOnly, processBody, processBody, setIgnoreEnableOutputOnly, setName, validateAttributes
-
Constructor Details
-
Loop
public Loop()Constructs a new Loop component with all supported attributes configured.The Loop component supports multiple, mutually exclusive loop types. Different combinations of attributes determine which loop type is executed:
- Query Loop: Requires
queryattribute - Grouped Query Loop: Requires
queryandgroupattributes - Array Loop: Requires
arrayattribute - List Loop: Requires
listattribute - Collection Loop: Requires
collectionanditemattributes - Numeric Range Loop: Requires
index,from, andtoattributes - Conditional Loop: Requires
conditionattribute - Times Loop: Requires
timesattribute - File Loop: Requires
fileandindexattributes
- Query Loop: Requires
-
-
Method Details
-
_invoke
public Component.BodyResult _invoke(IBoxContext context, IStruct attributes, Component.ComponentBody body, IStruct executionState) Executes the appropriate loop type based on the provided attributes.This method serves as the main entry point for all loop operations, analyzing the provided attributes to determine which specific loop type to execute and delegating to the appropriate helper method.
Supported Loop Types
- Query Loop: Iterate over query recordsets with optional row range constraints
- Grouped Query Loop: Process query data with grouping on specified columns
- Array Loop: Iterate over array elements with optional index tracking
- List Loop: Process delimited lists with customizable delimiters
- Collection Loop: Iterate over Java collections and structures
- Numeric Range Loop: Loop through numeric ranges with configurable step values
- Conditional Loop: Continue looping while a condition remains true
- Times Loop: Execute a specific number of iterations
- File Loop: Read text files line by line
Loop Control
All loop types support standard loop control statements:
break- Exit the loop immediatelycontinue- Skip to the next iterationreturn- Exit from the containing function/component
Loop control statements can be labeled to target specific nested loops:
<bx:loop label="outer" array="#outerArray#" item="outerItem"> <bx:loop array="#innerArray#" item="innerItem"> <bx:if condition="#someCondition#"> <bx:break label="outer" /> // Breaks out of outer loop </bx:if> </bx:loop> </bx:loop>Usage Examples
Query Loop
// Simple query loop <bx:loop query="#myQuery#"> <bx:output>#myQuery.name#: #myQuery.email#</bx:output> </bx:loop> // Query loop with row range <bx:loop query="#myQuery#" startRow="5" endRow="15"> <bx:output>Row #currentRow#: #myQuery.name#</bx:output> </bx:loop>
Grouped Query Loop
// Group by department <bx:loop query="#employeeQuery#" group="department"> <h3>Department: #department#</h3> <bx:loop> // Inner loop for employees in this department <p>#name# - #position#</p> </bx:loop> </bx:loop> // Nested grouping (department > manager > employee) <bx:loop query="#employeeQuery#" group="department"> <h2>Department: #department#</h2> <bx:loop group="manager"> <h3>Manager: #manager#</h3> <bx:loop> // Individual employees <p>#name# - #position#</p> </bx:loop> </bx:loop> </bx:loop>Array Loop
// Loop with item only <bx:loop array="#myArray#" item="currentItem"> <bx:output>#currentItem#</bx:output> </bx:loop> // Loop with both item and index <bx:loop array="#myArray#" item="currentItem" index="currentIndex"> <bx:output>Item #currentIndex#: #currentItem#</bx:output> </bx:loop>
List Loop
// Default comma delimiter <bx:loop list="apple,banana,cherry" item="fruit"> <bx:output>#fruit#</bx:output> </bx:loop> // Custom delimiter <bx:loop list="apple|banana|cherry" item="fruit" delimiters="|"> <bx:output>#fruit#</bx:output> </bx:loop>
Numeric Range Loop
// Basic range <bx:loop from="1" to="10" index="i"> <bx:output>#i#</bx:output> </bx:loop> // With step <bx:loop from="0" to="100" step="10" index="i"> <bx:output>#i#</bx:output> // Outputs: 0, 10, 20, 30... </bx:loop> // Backward iteration <bx:loop from="10" to="1" step="-1" index="i"> <bx:output>#i#</bx:output> // Outputs: 10, 9, 8, 7... </bx:loop>
Collection Loop
// Structure iteration <bx:loop collection="#myStruct#" item="key"> <bx:output>#key#: #myStruct[key]#</bx:output> </bx:loop>
Conditional Loop
<bx:loop condition="#hasMoreData()#"> <bx:set processNextBatch() /> </bx:loop>
Times Loop
<bx:loop times="5" index="i"> <bx:output>Iteration #i#</bx:output> </bx:loop>
File Loop
<bx:loop file="/path/to/file.txt" index="line"> <bx:output>#line#</bx:output> </bx:loop>
- Specified by:
_invokein classComponent- Parameters:
context- The context in which the Component is being invokedattributes- The attributes to the Componentbody- The body of the ComponentexecutionState- The execution state of the Component- Returns:
- A BodyResult indicating how the loop terminated (normal completion, break, continue, or return)
- Throws:
BoxRuntimeException- if required attributes are missing or invalid for the detected loop type
-