【问题标题】:APEX 3.2 (Oracle): on change of an item dynamically populates the values of other items on the pageAPEX 3.2 (Oracle):在更改项目时动态填充页面上其他项目的值
【发布时间】:2012-12-05 00:10:39
【问题描述】:

我在 APEX 3.2 上,并使用用于在表 f 中插入字段 f1 和 f2 的表单,我希望有几个文本项将根据在 f1 中键入的数据和查询自动填充和显示在表 t 上。换句话说,在 f1 中输入 empno,移动到 f2 框,用户应该会自动看到 emp last_name 和 first_name 显示。这样她就可以验证输入的 empno 是否正确,在 f2 中输入其他数据并提交表单。

关于如何达到这个范围有什么建议吗?

我想我应该使用一些 javascript。

非常感谢。 加布里埃尔

【问题讨论】:

  • 我在我的帖子上看到了您尝试的编辑:最好发表评论并简要说明无法正常工作的内容,如果您觉得需要发布一些代码,最好将其编辑为您的原始代码问题。但是,根据我从中收集到的信息,您可能应该从使用允许检查 ajax 调用的浏览器开始。您可以使用 Firefox 的 Firebug 插件或使用开发工具在 Chrome 中执行此操作。检查是否触发了 ajax 调用。有没有抛出任何错误?如果没有,请检查调用的响应,看看它是否确实返回了一个对象!

标签: oracle-apex


【解决方案1】:

我可以看到您可能已经走上了 javascript 的道路...我过去曾使用 APEX 3.2 处理过类似的问题,并且不知道足够的 javascript 来从平台中获取这种动态功能.如果您想尝试另一种方法,您可以调整您的用户界面以提供您寻求的功能,但您必须与用户核实他们是否可以适应这种方法,您应该能够使用现有 3.2 功能且无需额外的脚本:

要求:

根据 field1 和 field2 的字段输入,使用现有表中的数据自动填充 apex 页面,以便用户确认在 field1 和 field2 中输入的数据是否正确。将搜索结果中的数据用作输入新流程或表单的参数。

建议设计:

第 1 页: 从空白页开始,然后添加三个项目:field1、field2 和一个“提交”按钮。 添加页面进程(提交后,以提交按钮项为条件),从第 1 页表单上的值重定向到第 2 页设置项 P2_field1 和 P2_field2。

第 2 页: 报告页面。设置一个查询,该查询将通过部分或完整字符串搜索对员工表进行搜索,从而搜索现有员工表。 APEX 3.2 过去使用以下约定来解决部分匹配和区分大小写的匹配问题:

SELECT field1, field2, field3, field4, ...
FROM table1
WHERE instr(upper(field1), upper(:P2_field1), 1, 1) > 0
  AND instr(upper(field2), upper(:P2_field2), 1, 1) > 0

当同一搜索查询可能有多个答案时,为搜索工作创建报告输出“表格”会有所帮助...例如常见名称,如“Smith”或“John”...

在报表输出中添加一个附加列,或将名称列(字段 1 或字段 2)设为链接列,该列将转到第 3 页,提供来自员工表的查询数据。

将属性添加到报告编辑器上的列值:重定向到“第 3 页”,设置 P3_key = #KEY# 其中第 3 页是您的最终目标表单或进程,“key”是索引或主键您正在搜索的表...或者您可以提供已经从查找表中查询到的 n 个值,以填充第 2 页报告。

我想重要的收获是了解旧版本 Apex 的局限性以及可能高级网络脚本语言知识的局限性。即使您只熟悉 Apex 版本的基础知识和一点 SQL,您的要求仍然可以实现。

注意:如果您的查找表非常庞大(数十万条记录),您可能需要咨询您的 DBA 以获取优化表以处理 SQL 搜索查询的帮助。在没有额外优化帮助的情况下,将 UPPER 和 INSTR 函数添加到 WHERE 条件并不是查询大型数据集的最有效方法。

【讨论】:

  • 感谢 Richard 提出的这个替代想法。我实际上是一名 DBA,我对 SQL 和查询优化更有信心。问题是我对 APEX 和 javascript 的了解不够,但这是开始学习的好机会 :-)。如果 js via 失败,我将尝试使用您的...并且可能会要求您提供更多帮助;-) 非常感谢。加布里埃尔
【解决方案2】:

我不是 3.2 wiz,我没有使用它。我知道没有动态操作,也没有页面按需处理点,所以我已经考虑到了这一点。

申请流程:'get_emp_details'
(我不知道3.2中你可以/需要选择的处理点。如果你可以按需选择,那就去吧。) 代码:

DECLARE
   lEmp emp%rowtype;
BEGIN
   SELECT *
     INTO lEmp
     FROM emp
    WHERE empno = :P7_EMPNO;

   htp.p('{"result":"ok", "emp":{"ename":"'||lEmp.ename||'","job":"'||lEmp.job||'"}}');
EXCEPTION 
WHEN no_data_found THEN
   htp.p('{"result":"nok", "emp":{}}');
END;

在您的页面上(在我的情况下,我使用的是第 7 页,将页码更改为您的页码!)将其放在 html 标题部分(或者如果您有 javascript 部分,则将 javascript 代码放在那里,而无需脚本标签):
编辑:在console.log 行中添加。请注意,当开发人员工具(F12)未打开时,这些将在 IE 中产生 javascript 错误!

<script type="text/javascript">
$(document).ready(function(){
   console.log('document is ready');
   $("#P7_EMPNO").change(function(){
      var oDBGet = new htmldb_Get(null, $('pFlowId').val(), "APPLICATION_PROCESS=get_emp_details", '0');
      oDBGet.add('P7_EMPNO', $("#P7_EMPNO").val());
      var oResult = oDBGet.get();
      var lReturn = $.parseJSON(oResult);
      if(lReturn.result=='ok'){
         var lEmp = lReturn.emp;
         $("#P7_ENAME").val(lEmp.ename);
      } else {
         alert('ename could not be found for this empno!');
      };
   });
});
</script>

这将在 EMPNO 更改时执行 ajax 回调,并更改员工的 ename。由于没有可以使用的临时应用程序项目 (apex_application.g_x##),我将所需的页面项目提交到会话状态。在这种情况下,P7_EMPNO 被添加到 p_arg_names 数组中,并且它的值位于 p_arg_values 数组中的相应位置。这是必要的,因为 P7_EMPNO 的会话状态在应用程序中使用。

在 Firebug 中检查控制台选项卡时:
ajax调用的post值:
ajax调用的响应值:

【讨论】:

  • 感谢汤姆的详细回答!
  • 感谢汤姆的详细解答!我已经根据我的情况修改了您的代码,但它不起作用(可能我犯了一些错误)。在我的情况下,表格是针对表 t 的,而我从 emp 中获取 last_name 和 first_name,其中 t.badge=emp.badge(用徽章代替 empno)。我将在下一个答案中发布您修改后的代码。请看一看。无论如何,非常感谢。加布里埃尔
  • 嗨,汤姆。我使用FF并有萤火虫。我可以看到加载的 Ajax 脚本,我不知道它是否被触发(我如何检查这个?)并且我没有收到任何错误。同时我会尝试一些警报。再次感谢你!加布里埃尔
  • 当您更改页面项目时P7_BADGE。但请注意,这必须是手动更改,即您需要通过键入一些内容来更改值,然后通过 fe 选项卡退出该项目。这应该会触发 ajax 调用。
  • 这正是我所做的:我输入 P2_BADGE,转到另一个字段 (P2_DATE),但 P2_LAST_NAME 中什么也没有发生。
【解决方案3】:

汤姆, 这是您修改后的代码以在我的系统中工作:

-- 按需申请流程get_emp_details:

DECLARE
   lEmp emp%rowtype;
BEGIN
   SELECT *
     INTO lEmp
     FROM emp
    WHERE badge = :P2_BADGE;

   htp.p('{"result":"ok", "emp":{"lastname":"'||lEmp.last_name||'","firstname":"'||lEmp.first_name||'"}}');
EXCEPTION 
WHEN no_data_found THEN
   htp.p('{"result":"nok", "emp":{}}');
END;

-- 页面标题中的 Javascript:

<script type="text/javascript">
$(document).ready(function(){
   $("#P2_BADGE").change(function(){
      $.post('wwv_flow.show', 
             {"p_request"      : "APPLICATION_PROCESS=get_emp_details",
              "p_flow_id"      : $v('pFlowId'),
              "p_flow_step_id" : '0',
              "p_instance"     : $v('pInstance'),
              "p_arg_names"    : ['P2_BADGE'],
              "p_arg_values"   : [$('#P2_BADGE').val()]},
              function(data){
                 if(data){
                    var lReturn = $.parseJSON(data);
                    if(lReturn.result=='ok'){
                       var lEmp = lReturn.emp;
                       $("#P2_LAST_NAME").val(lEmp.last_name);
                    } else {
                       alert('ename could not be found for this empno!');
                    };
                 };
              }
      );        
   });
});
</script>

我可能遗漏了一些东西,当我在 P2_BADGE 中键入徽章编号时,它不会在 P2_LAST_NAME 中显示 last_name。

谢谢, 加布里埃尔

Tom,这是我在 firebug 的监视右侧窗口中的功能(数据)步骤:

this
  function()

arguments
[
"wwv_flow.show"
, Object { p_request=
"APPLICATION_PROCESS=get_emp_details"
,  p_flow_id=
"120"
,  p_flow_step_id=
"0"
,  more...}, function()]

0

"wwv_flow.show"

1
  Object { p_request=
"APPLICATION_PROCESS=get_emp_details"
, p_flow_id=
"120"
, p_flow_step_id=
"0"
, more...}

p_arg_names
[
"P2_BADGE"
]

p_arg_values
[
"155752"
]

p_flow_id
"120"

p_flow_step_id
"0"

p_instance
"2189517750670012"

p_request
"APPLICATION_PROCESS=get_emp_details"
2
  function()
e
"wwv_flow.show"
r
Object { p_request=
"APPLICATION_PROCESS=get_emp_details"
, p_flow_id=
"120"
, p_flow_step_id=
"0"
, more...}
p_arg_names
[
"P2_BADGE"
]
p_arg_values
[
"155752"
]

p_flow_id
"120"
p_flow_step_id
"0"
p_instance
"2189517750670012"
p_request
"APPLICATION_PROCESS=get_emp_details"
s
undefined
i
function()
toString
  function()

Closure Scope
  Closure Scope { toString=function()}
Closure Scope
  Closure Scope { toString=function()}
Window
  Window f?p=120:2:2189517750670012::NO:::

从我的 firebug 1.10.6 控制台:

文件准备好了

f?p=12...::NO:::(第 29 行)

empno 变了

f?p=12...::NO:::(第 31 行)

使用 empno 值执行帖子:未定义

f?p=12...::NO:::(第 32 行)

发布

400 错误请求 48毫秒
wwv_fl....min.js(第 2 行) HeadersPostResponseHTMLCookies

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY><H1>Bad Request</H1>
The HTTP client sent a request that this server could not understand.</BODY></HTML>

-- 以及帖子标签:

Parametersapplication/x-www-form-urlencoded
p_arg_names[]   P2_BADGE
p_arg_values[]  155751
p_flow_id   120
p_flow_step_id  0
p_instance  4466366911674565
p_request   APPLICATION_PROCESS=get_emp_details
Source
p_request=APPLICATION_PROCESS%3Dget_emp_details&p_flow_id=120&p_flow_step_id=0&p_instance=4466366911674565&p_arg_names%5B%5D=P2_BADGE&p_arg_values%5B%5D=155751

【讨论】:

  • Gabriele,请参阅我对您问题的评论。我们需要找到你卡在哪里。最好能够检查 ajax 调用。希望您有可用的浏览器来执行此操作(例如,您不能使用 IE8)。如果你不这样做,那么代码应该会充斥着 javascript 警报:一个在更改函数体中,一些在 ajax 调用的成功函数中。
  • 对不起,汤姆,我是 stackoverflow 的新手,我没有正确使用它......我很抱歉。我使用FF并有萤火虫。我可以看到加载的 Ajax 脚本,我不知道它是否被触发(我如何检查这个?)并且我没有收到任何错误。同时我会尝试一些警报。再次感谢你!加布里埃尔
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
相关资源
最近更新 更多