Oracle APEX交互式网格日期验证延迟问题求助
Oracle APEX交互式网格日期验证延迟问题
问题场景
需求:验证交互式网格(IG)中出发日期(Departure)不能晚于到达日期(Arrival),不符合规则时弹出错误提示并清空错误日期。
异常表现:
- 首次选择错误的出发日期时,验证函数虽被调用,但无法识别新选的日期值,错误日期可正常保存
- 再次编辑该日期时,才会触发错误提示,验证存在明显的一步延迟
原代码
function validateDate() { console.log("Validation function called"); var regionStaticId = "my_ig"; var grid; try { grid = apex.region(regionStaticId).widget().interactiveGrid("getViews", "grid"); } catch (e) { console.error("Interactive grid not found.", e); return false; } var model = grid.model; var arrivalIdx = model.getFieldKey("Arrival"); var departureIdx = model.getFieldKey("Departure"); apex.message.clearErrors(); var currentRecord = grid.view$.grid("getSelectedRecords")[0]; if (currentRecord) { var arrival = currentRecord[arrivalIdx]; var departure = currentRecord[departureIdx]; console.log("Checking record: ", currentRecord); console.log("Arrival: ",arrival, "Departure: ",departure); if (arrival && departure) { var arrivalDate = new Date(arrival); var departureDate = new Date(departure); console.log("Arrival Date: ",arrivalDate, "Departure Date: ",departureDate); if (arrivalDate < departureDate) { console.log("Invalid date detected"); apex.message.showErrors([{ type: "error", location: "page", message: "Pick a different date.", pageItem: null }]); grid.view$.grid("gotoCell", { row: model.getRecordId(currentRecord), field: departureIdx }); model.setValue(currentRecord, departureIdx, null); return false; } } } else { console.error("No editable record selected."); } return true; } $(document).ready(function() { $("input[name=fo6]").on("change", function(event) { if (!validateDate()) { event.preventDefault(); } }); }); // 在动态动作中调用上述函数
问题根源
- 原生input监听时机不对:
input[name=fo6]的change事件触发时,APEX IG的模型(model)还未同步更新新输入的日期值,导致getSelectedRecords获取的是旧值 - 依赖选中记录而非实时编辑值:
getSelectedRecords返回的是模型缓存的记录,而非当前编辑单元格的实时输入值
解决方案
修改思路
- 改用APEX IG原生的
interactivegridviewmodelchange事件监听值变更,确保模型已同步最新值 - 直接获取当前活跃编辑的单元格,从模型中提取实时更新的字段值
- 移除原生input的监听逻辑,避免时机冲突
修改后的代码
function validateDate() { console.log("Validation function called"); var regionStaticId = "my_ig"; var grid; try { grid = apex.region(regionStaticId).widget().interactiveGrid("getViews", "grid"); } catch (e) { console.error("Interactive grid not found.", e); return false; } var model = grid.model; var arrivalIdx = model.getFieldKey("Arrival"); var departureIdx = model.getFieldKey("Departure"); apex.message.clearErrors(); // 获取当前活跃编辑的单元格(替换原getSelectedRecords) var activeCell = grid.view$.grid("getActiveCell"); if (!activeCell) { console.error("No active cell found."); return true; } var currentRecord = model.getRecord(activeCell.rowId); if (!currentRecord) { console.error("Record not found for active cell."); return true; } // 从模型获取最新的字段值(而非直接取currentRecord属性) var arrival = model.getValue(currentRecord, arrivalIdx); var departure = model.getValue(currentRecord, departureIdx); console.log("Checking record: ", currentRecord); console.log("Arrival: ", arrival, "Departure: ", departure); if (arrival && departure) { var arrivalDate = new Date(arrival); var departureDate = new Date(departure); console.log("Arrival Date: ", arrivalDate, "Departure Date: ", departureDate); if (arrivalDate < departureDate) { console.log("Invalid date detected"); apex.message.showErrors([{ type: "error", location: "page", message: "出发日期不能晚于到达日期,请重新选择。", pageItem: null }]); // 聚焦到错误单元格 grid.view$.grid("gotoCell", { row: activeCell.rowId, field: departureIdx }); // 清空错误值 model.setValue(currentRecord, departureIdx, null); return false; } } return true; } // 改用IG原生事件监听值变更 $(document).ready(function() { var regionStaticId = "my_ig"; apex.region(regionStaticId).widget().on("interactivegridviewmodelchange", function(event, ui) { // 仅当Departure字段变更时触发验证 if (ui.field === model.getFieldKey("Departure")) { validateDate(); } }); }); // 动态动作设置:触发条件改为「交互式网格 - 字段值变更」,字段选Departure,执行动作调用validateDate
关键改动说明
- 获取实时值:用
model.getValue()替代直接访问currentRecord属性,确保拿到模型同步后的最新值 - 监听原生事件:
interactivegridviewmodelchange是APEX IG专为模型变更提供的事件,触发时机晚于原生input事件,确保模型已更新 - 精准触发:仅当Departure字段变更时触发验证,避免不必要的性能消耗
动态动作配置建议
- 触发条件选择「交互式网格 → 字段值变更」
- 选择对应的IG区域,字段指定为「Departure」
- 执行动作选择「执行JavaScript代码」,调用
validateDate()函数
内容的提问来源于stack exchange,提问作者user28260183
相关产品推荐
相关产品推荐

