Introduction
Oracle APEX offers powerful templating features that allow developers to render dynamic content within region templates using directives. Among these tools, the loop directive is frequently used to display repeated items like lists, tags, or related values. To enhance the flexibility and control of rendering inside a loop, Oracle APEX provides system variables such as APEX$ITEM
and APEX$I
. These variables are especially useful when you need to access the current loop item or track the loop index. Understanding how to properly use APEX$ITEM
and APEX$I
can help you create cleaner, more intelligent templates in your reports and cards.
How to Use APEX$ITEM and APEX$I Within Loop Directives in Oracle APEX
-
What is APEX$ITEM?
APEX$ITEM
represents the current value in the loop iteration. It's a shorthand for directly referencing the current item without having to name it explicitly. It's particularly helpful when your loop doesn’t define a custom alias withas
.Example:
{loop TAGS} <span class="badge">{APEX$ITEM}</span> {endloop}
-
What is APEX$I?
APEX$I
is a special loop counter variable that returns the current iteration index (starting at 1). This is useful when you need to apply styles or logic based on the position of the item in the loop.Example:
{loop TAGS} <div>{APEX$I}: {APEX$ITEM}</div> {endloop}
-
Customizing Loop Behavior with Both
CombineAPEX$ITEM
andAPEX$I
to render advanced logic in your display. For example:{loop NAMES} <span class="user-label">{APEX$I}. {APEX$ITEM}</span><br> {endloop}
-
Using Delimiters
When your data uses a delimiter other than a comma, you can specify it within the loop:{loop COLORS delimiter:";"} <div class="color-box">{APEX$ITEM}</div> {endloop}
Best Practices
-
Use
APEX$ITEM
when a custom alias is not necessary. -
Use
APEX$I
for conditional formatting, zebra striping, or labeling. -
Always clean and validate delimited data at the SQL level to avoid runtime errors or HTML injection.
-
Avoid overcomplicating loop logic in the template—delegate logic-heavy operations to SQL or PL/SQL if needed.
-
Use semantic HTML elements within loop content to improve accessibility and responsiveness.
Oracle APEX Documentation
Official documentation for template directives and their variables can be found here:
Oracle APEX Template Directives Guide
In Oracle APEX, when working with loop directives, two special data substitutions — APEX$ITEM and APEX$I — are available to make your loop content even more dynamic and flexible.
APEX$ITEM: This is the value of the current item in the loop.
APEX$I: This is the 1-based index of the current item in the list, which represents the position of the item in the iteration.
These substitutions can be used to manipulate and display dynamic data more effectively. You can use APEX$ITEM for accessing individual items and APEX$I for tracking the position within the loop, such as for adding dynamic numbering, styles, or labels.
Step 1: Basic Understanding of the Loop Syntax
A typical loop directive with APEX$ITEM and APEX$I would look something like this:
{loop [SEP] NAME/}
<!-- Displaying each item -->
Item #{APEX$I}: {APEX$ITEM}
{endloop/}
{loop [SEP] NAME/}: Starts the loop over a collection named NAME, with a separator SEP between items.
{APEX$I}: Displays the 1-based index (position) of the current item in the loop.
{APEX$ITEM}: Displays the actual value of the current item in the loop.
{endloop/}: Ends the loop.
Step 2: Example 1 — Displaying a List with Index and Value
Scenario:
You have a list of items such as product names and you want to display them in a numbered list with their respective positions.
Steps:
Create a Page Item or Collection: Assume you have a page item :P1_PRODUCT_LIST containing the list of product names:
Product A
Product B
Product C
Create a Static Content Region.
Use the following HTML expression:
{loop [", "] :P1_PRODUCT_LIST/}
<p>Item #{APEX$I}: {APEX$ITEM}</p>
{endloop/}
Explanation:
The :P1_PRODUCT_LIST contains the list of product names.
The {APEX$I} represents the index of the current item in the list (1, 2, 3, etc.).
The {APEX$ITEM} represents the value of the current item (e.g., "Product A").
Expected Output:
Item #1: Product A
Item #2: Product B
Item #3: Product C
Step 3: Example 2 — Styling Items Based on Index Using APEX$I
Scenario:
You want to apply different styles to each item based on its position. For instance, the first item should be bold, the second should be italic, and the rest should have a normal style.
Steps:
Use the following HTML expression in the Static Content Region:
{loop [", "] :P1_PRODUCT_LIST/}
{if APEX$I = 1}
<p style="font-weight: bold;">Item #{APEX$I}: {APEX$ITEM}</p>
{elsif APEX$I = 2}
<p style="font-style: italic;">Item #{APEX$I}: {APEX$ITEM}</p>
{else}
<p>Item #{APEX$I}: {APEX$ITEM}</p>
{/if}
{endloop/}
Explanation:
The loop will iterate over the items in :P1_PRODUCT_LIST.
APEX$I is used to check the position of the current item.
Depending on the value of APEX$I, different styles are applied:
Bold for the first item (APEX$I = 1).
Italic for the second item (APEX$I = 2).
Normal style for all other items.
Expected Output:
Item #1: Product A (in bold)
Item #2: Product B (in italic)
Item #3: Product C (normal style)
Step 4: Example 3 — Generating a List with Custom Separator Using APEX$ITEM
Scenario:
You want to display the list of products in a single line, separated by a custom separator (e.g., a hyphen -), but without adding the separator at the end.
Steps:
Create a Static Content Region.
Use the following HTML expression:
{loop [" - "] :P1_PRODUCT_LIST/}
{APEX$ITEM}
{endloop/}
Explanation:
The loop will iterate through the items in :P1_PRODUCT_LIST.
[" - "] is the separator that will be inserted between each item, but it won't be added after the last item.
{APEX$ITEM} will display the value of the current item in the list.
Expected Output:
Product A - Product B - Product C
Step 5: Example 4 — Displaying a Product List with Item Numbers and Values
Scenario:
You want to display each product in the list with its corresponding item number and product value.
Steps:
Create a Static Content Region.
Use the following HTML expression:
{loop [", "] :P1_PRODUCT_LIST/}
<p>Item #{APEX$I}: {APEX$ITEM}</p>
{endloop/}
Explanation:
{APEX$I} will output the item index (e.g., 1, 2, 3).
{APEX$ITEM} will output the corresponding product name (e.g., "Product A", "Product B", etc.).
Expected Output:
Item #1: Product A
Item #2: Product B
Item #3: Product C
Step 6: Example 5 — Using Loops to Create a Table with Index and Item Values
Scenario:
You want to display a list of products in an HTML table format, with a column for the item number and a column for the item value.
Steps:
Use the following HTML expression:
<table border="1">
<thead>
<tr>
<th>Item Number</th>
<th>Product Name</th>
</tr>
</thead>
<tbody>
{loop [", "] :P1_PRODUCT_LIST/}
<tr>
<td>{APEX$I}</td>
<td>{APEX$ITEM}</td>
</tr>
{endloop/}
</tbody>
</table>
Explanation:
The loop iterates over the :P1_PRODUCT_LIST page item.
{APEX$I} is used to display the 1-based index (item number).
{APEX$ITEM} is used to display the actual product name.
Expected Output:
<table border="1">
<thead>
<tr>
<th>Item Number</th>
<th>Product Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Product A</td>
</tr>
<tr>
<td>2</td>
<td>Product B</td>
</tr>
<tr>
<td>3</td>
<td>Product C</td>
</tr>
</tbody>
</table>
:
APEX$ITEM allows you to access the value of the current item in the loop.
APEX$I provides the 1-based index of the current item, which can be used for dynamic numbering, conditional formatting, and more.
These features are essential when you need to display or manipulate dynamic data within a loop, providing you with the flexibility to create sophisticated user interfaces with ease.
In Oracle APEX, when using loop directives, you have access to several special data substitutions to enhance the flexibility and functionality of your templates. Specifically, APEX$ID, APEX$I, and APEX$META are useful for manipulating and displaying information about the records being iterated over. These substitutions allow you to:
APEX$ID: Access the identity of the current record.
APEX$I: Get the 1-based index of the current record.
APEX$META: Get metadata about the current record.
These can be particularly helpful in templates for reports, interactive grids, or any dynamic data display in APEX.
Overview of Special Data Substitutions
APEX$ID:
This substitution holds the identity of the record.
It is typically used to reference the record’s primary key or unique identifier.
You can retrieve the Record ID from model#getRecordId.
APEX$I:
This represents the 1-based index of the current record in the loop.
Useful for generating row numbers, applying row-specific styles, or displaying dynamic content that depends on the record position.
APEX$META:
This is an object containing metadata about the current record.
The object includes several properties that provide information about the record's state, validation, selected status, and more. These properties are:
valid: Whether the record is valid (Y) or has errors/warnings (N).
state: The state of the record (O, D, I, U, or empty).
allowedOperations: Determines if the record is editable (Update/Delete).
selected: Whether the record is selected (Y or N).
agg: The name of the aggregate record (e.g., "SUM").
highlight: The highlight name applied to the record.
endControlBreak: Indicates if this is the end of a control break.
grandTotal: Indicates if this is a grand total for the aggregate.
errorMessage: The error message if applicable.
warningMessage: The warning message if applicable.
Step 1: Loop Syntax with APEX$ID, APEX$I, and APEX$META
The general structure for using APEX$ID, APEX$I, and APEX$META in a loop looks like this:
{loop ["SEP"] NAME/}
Record ID: {APEX$ID}
Record Index: {APEX$I}
Metadata - State: {APEX$META.state}
Metadata - Valid: {APEX$META.valid}
{endloop/}
{loop ["SEP"] NAME/}: Starts the loop through a collection or set of data named NAME. The separator SEP is used between items (if needed).
{APEX$ID}: Displays the identity (primary key) of the current record.
{APEX$I}: Displays the 1-based index of the current record in the loop.
{APEX$META.state}: Displays the state of the current record (e.g., "I" for inserted, "U" for updated).
Step 2: Example 1 — Displaying Record ID and Index
Let's say you have a list of records and want to display the record ID and its position in the list.
Scenario:
You have a collection of products, and you want to display the product's record ID and the position (index) of the product in the list.
Create a Static Content Region.
Use the following HTML expression:
{loop ["SEP"] :P1_PRODUCTS/}
<p>Product #{APEX$I} - Record ID: {APEX$ID}</p>
{endloop/}
Explanation:
:P1_PRODUCTS is the collection of products (could be a page item or a result set).
{APEX$I}: Displays the position of the current product in the loop.
{APEX$ID}: Displays the unique record ID for the current product.
Expected Output:
For a list of products like:
Product 1 with ID 101
Product 2 with ID 102
Product 3 with ID 103
The output will look like this:
Product #1 - Record ID: 101
Product #2 - Record ID: 102
Product #3 - Record ID: 103
Step 3: Example 2 — Using APEX$META to Display Record Status
Scenario:
You want to show the status of each record, including whether it is new (inserted), updated, or deleted. You will also use the valid property to indicate whether the record is valid or has errors.
Use the following HTML expression:
{loop ["SEP"] :P1_RECORDS/}
<p>Record ID: {APEX$ID}</p>
<p>Index: {APEX$I}</p>
<p>State: {APEX$META.state}</p>
<p>Valid: {APEX$META.valid}</p>
<p>Selected: {APEX$META.selected}</p>
<p>Errors: {APEX$META.errorMessage}</p>
{endloop/}
Explanation:
{APEX$META.state}: Displays the state of the record (O, D, I, U, or empty string).
{APEX$META.valid}: Indicates if the record is valid ("Y" for valid, "N" for invalid).
{APEX$META.selected}: Displays if the record is selected.
{APEX$META.errorMessage}: Displays the error message if one exists.
Expected Output:
For records with different states, the output could look like this:
Record ID: 101
Index: 1
State: I (Inserted)
Valid: Y
Selected: N
Errors:
Record ID: 102
Index: 2
State: U (Updated)
Valid: N
Selected: Y
Errors: Missing value in required field
Record ID: 103
Index: 3
State: D (Deleted)
Valid: Y
Selected: N
Errors:
Step 4: Example 3 — Highlighting Specific Records Based on Metadata
Scenario:
You want to highlight certain records, such as aggregate records, records with errors, or selected records, by using different background colors.
Use the following HTML expression:
{loop ["SEP"] :P1_RECORDS/}
<div style="background-color: {if APEX$META.selected = 'Y'}#FFEB3B{elsif APEX$META.errorMessage != ''}#FFCDD2{else}#FFFFFF{/if}">
<p>Record ID: {APEX$ID}</p>
<p>Index: {APEX$I}</p>
<p>State: {APEX$META.state}</p>
<p>Valid: {APEX$META.valid}</p>
</div>
{endloop/}
Explanation:
If the record is selected, the background color will be yellow (#FFEB3B).
If the record has an error message, the background will be light red (#FFCDD2).
Otherwise, the background color will be white (#FFFFFF).
Expected Output:
For selected records and those with errors, the output might look like this:
<div style="background-color: #FFEB3B;">
<p>Record ID: 101</p>
<p>Index: 1</p>
<p>State: I</p>
<p>Valid: Y</p>
</div>
<div style="background-color: #FFCDD2;">
<p>Record ID: 102</p>
<p>Index: 2</p>
<p>State: U</p>
<p>Valid: N</p>
</div>
<div style="background-color: #FFFFFF;">
<p>Record ID: 103</p>
<p>Index: 3</p>
<p>State: D</p>
<p>Valid: Y</p>
</div>
Step 5: Example 4 — Aggregating Data Using APEX$META.agg
Scenario:
You have a collection that includes aggregate records (e.g., sum, average), and you want to display them separately from normal records.
Use the following HTML expression:
{loop ["SEP"] :P1_AGGREGATES/}
{if APEX$META.agg != ''}
<p><strong>{APEX$META.agg} Aggregation:</strong> {APEX$ID} - {APEX$I}</p>
{else}
<p>Record ID: {APEX$ID} - Index: {APEX$I}</p>
{/if}
{endloop/}
Explanation:
The loop checks if the aggregate name (APEX$META.agg) is non-empty, meaning it's an aggregate record.
If it's an aggregate, it shows the aggregation type (e.g., "SUM", "AVG").
Otherwise, it displays normal records.
Expected Output:
<strong>SUM Aggregation:</strong> 104 - 1
Record ID: 102 - Index: 2
Record ID: 103 - Index: 3
Conclusion
Using APEX$ITEM
and APEX$I
within loop directives in Oracle APEX unlocks powerful formatting options and simplifies iteration logic. Whether you're creating stylish badges, indexed lists, or data-driven UI elements, these built-in loop variables provide essential context within each iteration. Mastering them enhances the declarative power of your APEX applications and makes your template code cleaner and more maintainable.