You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle APEX 22.1.7日期选择器输入动态格式化需求及尝试方案

Oracle APEX 22.1.7日期选择器动态格式化输入实现

需求

  • 手动输入8位数字(比如20022025),失去焦点后自动转成DD.MM.YYYY格式(即20.02.2025)
  • 用日期选择器选的日期,保持DD.MM.YYYY格式不变
  • 已将日期选择器的格式掩码设为DD.MM.YYYY

试过的方案

1. 无判断的PL/SQL动态操作

直接强制转换输入值,未区分手动输入和选择的日期,会把已格式化的日期也当成8位数字处理,容易触发转换错误:

declare
begin
  SELECT TO_CHAR(TO_DATE(:BIRTH_DATE, 'DDMMYYYY'), 'DD.MM.YYYY') 
    INTO :BIRTH_DATE
    FROM DUAL;
end;

2. 带条件的PL/SQL动态操作

用正则匹配8位数字后拼接格式,但未处理非匹配场景的赋值,非8位输入会被清空:

declare
  v_formatted_date varchar2(10);
begin
  if regexp_like(:BIRTH_DATE, '^\d{8}$') then
    v_formatted_date := substr(:BIRTH_DATE, 1, 2) || '.' || 
                        substr(:BIRTH_DATE, 3, 2) || '.' || 
                        substr(:BIRTH_DATE, 5, 4);
  end if;
  :BIRTH_DATE:= v_formatted_date;
end;

3. JavaScript动态操作

前端通过正则匹配8位数字后格式化,逻辑可行,但需绑定正确的触发事件:

var pid = $(this.triggeringElement).attr("id");
var value = apex.item(pid).getValue(); 
console.log("value:", value);

if (/^\d{8}$/.test(value)) {
  var formattedValue = value.substring(0, 2) + '.' + 
                       value.substring(2, 4) + '.' + 
                       value.substring(4);
  console.log("Formatted value:", formattedValue);
  apex.item(pid).setValue(formattedValue);
}

4. 带条件的PL/SQL设置值操作

仅在匹配8位数字时转换,避免了强制转换非8位值的错误,但需要服务器交互,响应速度慢:

declare
begin
  IF REGEXP_LIKE(:BIRTH_DATE, '^\d{8}$') THEN
    SELECT TO_CHAR(TO_DATE(:BIRTH_DATE, 'DDMMYYYY'), 'DD.MM.YYYY') 
      INTO :BIRTH_DATE
      FROM DUAL;
  end if;
end;

最优方案:前端JavaScript实现

推荐用前端处理,无服务器往返,体验更流畅,还能精准控制场景:

操作步骤

  1. 打开页面编辑器,选中目标日期选择器项
  2. 创建动态操作,触发事件选择失去焦点(Blur)
  3. 执行动作选择执行JavaScript代码,使用以下优化后的代码:
var item = apex.item(this.triggeringElement);
var value = item.getValue().trim();

// 仅处理8位纯数字的输入
if (/^\d{8}$/.test(value)) {
  // 拆分并格式化为DD.MM.YYYY
  var formatted = `${value.substring(0,2)}.${value.substring(2,4)}.${value.substring(4)}`;
  item.setValue(formatted);
}

可选:增加日期有效性验证

如果要确保输入的是真实存在的日期(比如避免2月30号这类无效值),可以添加校验逻辑:

var item = apex.item(this.triggeringElement);
var value = item.getValue().trim();

if (/^\d{8}$/.test(value)) {
  var day = parseInt(value.substring(0,2), 10);
  var month = parseInt(value.substring(2,4), 10);
  var year = parseInt(value.substring(4), 10);
  
  // 验证日期合法性
  var date = new Date(year, month - 1, day);
  if (date.getFullYear() === year && date.getMonth() + 1 === month && date.getDate() === day) {
    var formatted = `${value.substring(0,2)}.${value.substring(2,4)}.${value.substring(4)}`;
    item.setValue(formatted);
  } else {
    apex.message.showErrors([{
      type: "error",
      location: "page",
      message: "输入的日期无效,请检查格式",
      unsafe: false
    }]);
    item.setValue(''); // 清空无效输入
  }
}

为什么不选PL/SQL方案?

PL/SQL需要服务器往返处理,响应速度慢;而且如果用户选择的日期已经是DD.MM.YYYY格式,用TO_DATE(:BIRTH_DATE, 'DDMMYYYY')会直接触发转换错误,还得额外处理格式判断,远不如前端直接处理省心。

内容的提问来源于stack exchange,提问作者Vuu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:50:54