Two Layers of Defense
Interactive Grid validation should work at two levels: client-side for instant feedback as the user types, and server-side for business rule enforcement before DML. Client-side catches obvious errors immediately; server-side catches everything the client missed and enforces rules that require database access.
Client-Side: Column-Level Validation
Use the column’s “Validate” JavaScript function to check values as the user leaves a cell:
// Column validation function (set in column attributes)
function(value, item, record, model) {
if (value !== null && value < 0) {
return { valid: false, message: "Quantity cannot be negative" };
}
if (value !== null && value > 10000) {
return { valid: false, message: "Quantity exceeds maximum of 10,000" };
}
return { valid: true };
}
Client-Side: Cross-Column Validation
For validations that involve multiple columns on the same row, use a Dynamic Action on the column change event:
// Check that end date is after start date
var grid = apex.region("myGrid").widget().interactiveGrid("getViews","grid");
var model = grid.model;
var record = grid.getSelectedRecords()[0];
if (record) {
var startDate = new Date(model.getValue(record, "START_DATE"));
var endDate = new Date(model.getValue(record, "END_DATE"));
if (endDate <= startDate) {
// Show inline error
apex.message.showErrors([{
type: "error",
location: "page",
message: "End date must be after start date"
}]);
}
}
Server-Side: Page Validation
Create a page-level Validation that runs before the DML process. Use the "Rows Returned" type to check for invalid data across all submitted rows:
-- Validation: Check for duplicate line numbers
SELECT 1
FROM (SELECT line_number, COUNT(*) AS cnt
FROM (SELECT c001 AS line_number
FROM apex_collections
WHERE collection_name = 'IG_DATA')
GROUP BY line_number
HAVING COUNT(*) > 1)
WHERE ROWNUM = 1;
Server-Side: Row-Level Validation in the DML Process
-- Inside the custom DML process, before the DML statement
IF :APEX$ROW_STATUS IN ('C', 'U') THEN
IF :ORDER_DATE > SYSDATE THEN
APEX_ERROR.ADD_ERROR(
p_message => 'Order date cannot be in the future.',
p_display_location => APEX_ERROR.C_INLINE_IN_NOTIFICATION,
p_page_item_name => NULL
);
END IF;
IF :QUANTITY * :UNIT_PRICE > 50000 AND :APPROVAL_ID IS NULL THEN
APEX_ERROR.ADD_ERROR(
p_message => 'Orders over $50,000 require approval.',
p_display_location => APEX_ERROR.C_INLINE_IN_NOTIFICATION
);
END IF;
END IF;
Displaying Errors Back in the Grid
When server-side validation fails, APEX marks the affected row in the grid with a red indicator. The error message appears when the user hovers over or clicks the indicator. For the best user experience, return specific error messages that tell the user exactly what to fix rather than generic "validation failed" messages.