MvFOREACH#
Is designed to make dealing with arrays of items more convenient. Each item in the array is represented in the loop as an iterator variable, simplifying the syntax. Optionally you can exit the loop using
<MvFOREACH ITERATOR = "{ expression } | variable name"
ARRAY = "{ expression } | array name"
INDEX = "{ expression } | variable name"
FIRST = "{ expression }"
NEXT = "{ expression }"
LAST = "{ expression }"
COUNT = "{ expression }">
<MvFOREACHSTOP>
<MvFOREACHCONTINUE>
</MvFOREACH>
When combined with the -C
(compatibility) compiler flag, <MvFOREACH>
generates code that will run on any engine version 5.00 or newer, using runtime engine version checks to either call these functions or emulate their behavior.
Attributes#
Attribute | Description |
---|---|
ITERATOR |
Name of the variable which will contain a specific element in the array. The mechanism used is the same as <MvREFERENCE> and <MvREFERENCEARRAY> . |
ARRAY |
The array over which to iterate. |
INDEX |
(Optional) Name of the variable used to track the iterations through the loop. When specified, the variable can be used inside the expressions for NEXT and LAST , and is present within the <MvFOREACH> loop. If omitted, an internal variable is used. |
FIRST |
(Optional) Expression defining the index of the first element to iterate. If omitted, the loop starts at the first element present in the array (* see below). |
NEXT |
(Optional) Expression evaluated at the end of each iteration to increment the INDEX variable. If omitted, the loop transitions to the next element present in the array (* see below). |
LAST |
(Optional) Expression defining the upper bound of the loop, i.e., the last element to iterate. If omitted, the loop terminates after the last element in the array (* see below). |
COUNT |
(Optional) Shorthand for dense arrays: iterates from 1 to COUNT , incrementing by 1 each time. When specified, FIRST , NEXT , and LAST must be omitted (* see below). |
Note
Only the ITERATOR
and ARRAY
elements are required. When COUNT
is specified, FIRST
, NEXT
, and LAST
must be omitted. When COUNT
is omitted, FIRST
, NEXT
, and LAST
may be used together in any combination. When NEXT
is used the expression must increment the INDEX
.
Examples#
Basic Iteration#
This example uses <MvFOREACH>
in its simplest form to output a numbered list of orders:
<MvFOREACH ITERATOR="l.item" ARRAY="l.orders" INDEX="l.pos">
<MvEVAL EXPR="{ l.pos }">. <MvEVAL EXPR="{ l.item:Fname }"> <MvEVAL EXPR="{ l.item:Lname }"><br>
</MvFOREACH>
Limiting by Count#
This variation limits output to 25 items by using the COUNT
attribute. It assumes no array elements are empty and the number of items is known.
<MvASSIGN NAME="l.items_per_page" VALUE="{ 25 }">
<MvFOREACH ITERATOR="l.item" ARRAY="l.orders" INDEX="l.pos" COUNT="{ l.items_per_page }">
<MvEVAL EXPR="{ l.pos }">. <MvEVAL EXPR="{ l.item:Fname }"> <MvEVAL EXPR="{ l.item:Lname }"><br>
</MvFOREACH>
Specifying Bounds#
This example allows precise control by specifying FIRST
, NEXT
, and LAST
:
<MvASSIGN NAME="l.items_per_page" VALUE="{ 25 }">
<MvFOREACH ITERATOR="l.item"
ARRAY="l.orders"
INDEX="l.pos"
FIRST="{ 1 }"
NEXT="{ l.pos + 1 }"
LAST="{ l.items_per_page }">
<MvEVAL EXPR="{ l.pos }">. <MvEVAL EXPR="{ l.item:Fname }"> <MvEVAL EXPR="{ l.item:Lname }"><br>
</MvFOREACH>
Paging Through Results#
By incrementing a page number, you can output subsequent pages of 25 items:
<MvASSIGN NAME="g.page_num" VALUE="{ g.page_num + 1 }">
<MvASSIGN NAME="l.items_per_page" VALUE="{ 25 }">
<MvASSIGN NAME="l.first" VALUE="{ ((g.page_num - 1) * l.items_per_page) + 1 }">
<MvASSIGN NAME="l.last" VALUE="{ l.first + l.items_per_page - 1 }">
<MvFOREACH ITERATOR="l.item"
ARRAY="l.orders"
INDEX="l.pos"
FIRST="{ l.first }"
NEXT="{ l.pos + 1 }"
LAST="{ l.last }">
<MvEVAL EXPR="{ l.pos }">. <MvEVAL EXPR="{ l.item:Fname }"> <MvEVAL EXPR="{ l.item:Lname }"><br>
</MvFOREACH>
Skipping and Stopping#
This example loops through the orders
array, skipping any “test orders” using <MvFOREACHCONTINUE>
or exiting the loop on error with <MvFOREACHSTOP>
:
<MvFOREACH ITERATOR="l.item" ARRAY="l.orders" INDEX="l.pos" COUNT="{ 100 }">
<MvCOMMENT>Filter out any test orders</MvCOMMENT>
<MvIF EXPR="{ 'test order' IN l.item:fname }">
<MvFOREACHCONTINUE>
</MvIF>
<MvCOMMENT>If this field is empty display an error and exit the loop.</MvCOMMENT>
<MvIF EXPR="{ ISNULL l.item:code }">
<MvEVAL EXPR="{ 'Error in order number ' $ l.item:id $ '. code not found.' }">
<MvFOREACHSTOP>
</MvIF>
</MvFOREACH>