Oracle Fusion Middleware Tag Reference for Oracle ADF Faces 12c (12.2.1.4.0) E81455-03

# <af:forEach>

forEach foreach

The forEach tag provides additional functionality from the JSTL <c:forEach> tag. The tag is only supported in JSP.

The <af:forEach> is not supported in facelets. As a convenience, the tag handler for the <c:forEach> will be used in facelets when a <af:forEach> is used in a facelets page, but no ADF functionality will be supported.

The ADF forEach tag supports the following collections for the `items` attribute:

- Java array
- java.util.List
- org.apache.myfaces.trinidad.model.CollectionModel
- java.util.Map

When using a map, the map should be one that has a consistent order. Either the `java.util.LinkedHashMap` or `java.util.TreeMap` are examples of maps that provide this functionality. The keys for the maps must implement `java.io.Serializable`.

The for each tag is not as efficient as component stamping. When possible, the <af:iterator> should always be used instead of the for each tag. There are times this is not possible and usually involve the inclusion of content from other pages. For example, if different <jsp:include> tags need to be generated, pointing to different files based on items in a list, a for each tag must be used and not a stamping component like the ADF iterator.

Due to the way JSF and JSP create `ValueExpression` objects, the for each tag cannot safely map the expressions created and stored on JSF components to the iteration of the for each loop. As a result, it is possible to cause a discrepency between the component's location in the for each tag and the value expressions that are stored in the tag.

Due to this limitation, the forEach tag must place usage requirements on the pages they are placed on. For index based collections (arrays and lists), the components must be mapped to the index of the for each loop and not the item in the collection. In these cases, the index of the for each loop is stored into the value expressions created and stored into the components. This results in the component state (like expanded state of disclosure components) being tied to the index of the for each loop. As a result, a key based collection (map or collection model) is always recommended when the collection may change between requests.

For key based collections (map and collection model), the component IDs must be associated with the key of the collection. This is because the key of the collection is used in the value expressions and if the ID were not bound to the key, then the component state would not match the EL values. You should associate the component to the key using immediate EL in the ID attribute. See the examples below.

When the collection may change between requests, a key based collection should be used. When this is done, it is not recommended that JSF be allowed to generate the IDs of any components inside the for each tag. The reason is that JSF auto-generated IDs are based on the sequence that they are created in the current page. If items are re-arranged in the for each loop, the IDs will have a different generation order. As a result, JSF will not find the components with auto-generated IDs when it tries to map the JSP tag to the component ID. Existing components will be thrown out and new ones will be created and component state will be lost if this occurs.

Modifications to the collection in the same JSF view (between requests) are only supported with key based collections. Even with this being supported, the for each tag will not auto-rearrange the children.

When JSP seeks to locate a component that was created in a previous request, it creates the ID that it expects the component to have and then searches the children of the parent component of the tag for the child component with that ID. If the component is not found, a new one will be created. If it is found, the framework does not do anything to the component, it is left to exist where it is found. This means that if you reorder items in your collection between requests, the component order will no longer match the order of the items in the collection. Page authors must reorder the components when changes to the collection are made.

ADF supports re-ordering of components using the change manager (`org.apache.myfaces.trinidad.change.ChangeManager`) and the `org.apache.myfaces.trinidad.change.ReorderChildrenComponentChange` class. The change manager may be retrieved from the `org.apache.myfaces.trinidad.context.RequestContext` instance. See the ADF demo application for examples on how to reorder the components when the collections changes.

When using a key based collection, it is recommended to use a naming container to simplify tying the component ID to the key. See the examples below.

Please see the ADF demo application for complete examples.

## Attributes

Name | Type | Supports EL? | Description
--- | --- | --- | ---

begin | primitive int or java.lang.Number subclass | No | index at which iteration begins
end | primitive int or java.lang.Number subclass | No | index at which iteration ends
items | Object | Only EL | the collection to iterate over. Supported classes: Java array java.util.List org.apache.myfaces.trinidad.model.CollectionModel java.util.Map
step | primitive int or java.lang.Number subclass | No | number to increment the index by on each iteration
var | String | No | name of the variable exposed when iterating that references the item in the collection
varStatus | String | No | name of the loop status exposed when iterating. Properties:
Name | Description
--- | ---
index | the current index (int)
count | the current iteration number starting at one. If the start is 5, and the current index is 5, the count returns 1 (int)
step | the value to add to each index after an iteration (defaults to 1)
begin | the index to start at when collections are not used (int)
end | the last index when collections are not used (int)
first | true if this is the first iteration (boolean)
last | true if this is the last iteration (boolean)
key | the index (int) for index based collections and when the items has not been specified. The key (java.io.Serializable) for key based collections