How to Validate Interactive Grid Rows Before Saving in Oracle APEX

Add row validations to an editable Interactive Grid, catch duplicate products per order, and see where a database constraint must take over.

An editable Interactive Grid saves many rows at once, so its checks have to work row by row: a quantity out of range, a product entered twice on one order, a required value missing. Oracle APEX runs validations for every created and changed row when the validation is tied to the grid's region, and shows the error at the cell it concerns. This guide adds two such validations to an order lines grid, shows what each catches, and covers the case no row validation can see: duplicates between new rows of the same save.

The Grid

Page 60 has a select list of open orders, P60_ORDER_ID, and an editable Interactive Grid on ORDER_LINES with the Where Clause order_id = :P60_ORDER_ID and P60_ORDER_ID in Page Items to Submit. PRODUCT_ID is a select list column on the PRODUCTS table, and ORDER_ID is hidden.

For new rows, a row-level PL/SQL process with Editable Region Order Lines, placed before the grid's save process, sets the parent key on the server, so the browser cannot choose it:

Example:

:ORDER_ID := :P60_ORDER_ID;

In a grid process or validation, :COLUMN_NAME refers to the current row's value, and :P60_ORDER_ID to the page item, which the grid sends with every save because it is in Page Items to Submit.

Validation 1: Quantity Between 1 and 100

In the Processing tab, create a validation and set:

  • Editable Region: Order Lines. This makes it a row validation, run for each row.
  • Type: Expression, Language PL/SQL, PL/SQL Expression :QUANTITY between 1 and 100.
  • Error Message: Quantity must be between 1 and 100. Associated Column: QUANTITY.

Changing a quantity to 0 and saving shows the message, and marks the cell:

Oracle APEX Interactive Grid with the Quantity cell 0 marked in red and the error Quantity must be between 1 and 100
The row validation flags the cell that broke the rule.

Validation 2: A Product Only Once per Order

This rule needs the other lines of the order, so it is a query:

  • Editable Region: Order Lines. Type: No Rows returned, with the query below.
  • Error Message: This product is already on the order. Associated Column: PRODUCT_ID.
  • Server-side Condition: Expression, PL/SQL, :APEX$ROW_STATUS in ('C', 'U'), so the check runs for created and updated rows, not for deleted ones.

Example:

select 1
from   order_lines
where  order_id   = :P60_ORDER_ID
and    product_id = :PRODUCT_ID
and    line_id   <> nvl(:LINE_ID, -1)
Page Designer showing the validation Product only once per order with Editable Region Order Lines, type No Rows returned and its SQL query
The validation in Page Designer: tied to the Order Lines region, with the row status condition.

The LINE_ID condition excludes the row itself, so updating an existing line does not count as a duplicate of itself; new rows have no LINE_ID yet, hence the NVL. Adding a second Docking Station line to an order that already has one is rejected:

Oracle APEX Interactive Grid with a new Docking Station row and the error This product is already on the order
The new row is rejected; nothing is saved.

The Case Row Validations Cannot See

Each row is validated against the rows already in the table. Two new rows with the same product, added in the same save, both pass, because neither is in the table yet. Only the database can catch that, here with a unique constraint on (ORDER_ID, PRODUCT_ID):

Oracle APEX Interactive Grid error ORA-00001 unique constraint ORDER_LINES_PRODUCT_UK violated after adding two Keyboard rows
Two identical new rows in one save: the unique constraint stops them.

The save is rolled back, so no partial data is written. To show a friendly message instead of ORA-00001, translate the constraint name in an application error handling function. Keep the constraint either way: it also protects the data from every other program that writes to the table.

A Valid Save

A new Headset line passes both validations; the process sets its ORDER_ID, and the grid saves it:

Example:

select l.order_id, p.name as product, l.quantity, l.unit_price
from   order_lines l join products p on p.product_id = l.product_id
where  l.order_id = 1
order  by l.line_id;

Output:

   ORDER_ID PRODUCT               QUANTITY    UNIT_PRICE
___________ __________________ ___________ _____________
          1 Monitor 27                   2           320
          1 Docking Station              2           180
          1 Headset                      1            95

Things to Know

  • Column-level checks, such as Value Required or a maximum length, are set on the column itself and are checked in the browser too.
  • Execution Scope on a row validation decides which rows it runs for: by default created and modified rows.
  • Validations that do not name an editable region run once per page submit, not per row.
  • Associated Column for a grid validation is the plain column name; the message then appears at that column's cell.

Related Guides

Conclusion

Validate Interactive Grid rows by tying validations to the grid's editable region and using :COLUMN_NAME for the current row's values. Use a condition on :APEX$ROW_STATUS where deleted rows should be skipped, set parent keys in a row process on the server, and back the row checks with database constraints for what one row cannot see.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted