javascript 选中/未选中时用于操作其他值的 Oracle ApEx 复选框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12038392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:08:04  来源:igfitidea点击:

Oracle ApEx Checkbox to Manipulate Other Values When Checked/Unchecked

javascriptsqlcheckboxoracle11goracle-apex

提问by tonyf

Firstly, I am using the latest version of Oracle ApEx 4.1.1 and have the following standard report that has a checkbox selection so when clicked, would like to set another field with sysdate, including time.

首先,我使用的是最新版本的 Oracle ApEx 4.1.1 并有以下标准报告,其中包含一个复选框选择,因此在单击时,我想使用 sysdate 设置另一个字段,包括时间。

When unchecked, would like to reset to NULL the date set in my previous statement as well as a comments fields

未选中时,想将我之前的语句中设置的日期以及注释字段重置为 NULL

Report might look like:

报告可能如下所示:

select id,
       name,
       telephone,
       apex_item.checkbox2(10,id) as "Tick when Contacted",
       apex_item.display_and_save(20,:P2_DATE) as "Date Contacted",
       apex_item.textarea(30,:P2_COMMENT,5,80) as "Comment"
from   my_table

As an example of the above report, there might be a total of 10 records, so as each of the 10 record checkboxes are checked by the user, I would like to set the date field to sysdate, on the spot. I would also like the reverse done, when the checkbox is unchecked - set both date and comments to NULL.

作为上述报告的示例,可能总共有 10 条记录,因此当用户选中 10 条记录复选框中的每一个时,我想将日期字段设置为 sysdate,当场。当复选框未选中时,我还希望完成相反的操作 - 将日期和注释都设置为 NULL。

How should I approach this? Is the above possible via a Dynamic Action or straight via a JavaScript/on demand process?

我应该如何处理这个问题?以上是否可以通过动态操作或直接通过 JavaScript/按需流程实现?

Would definitely prefer the Dynamic Action approach if possible, in order to learn new methods of performing my required task.

如果可能的话,肯定会更喜欢动态操作方法,以便学习执行我所需任务的新方法。

回答by Tom

Example on EMP table:

EMP 表上的示例:

select 
apex_item.checkbox2(p_idx => 1, p_value => empno, p_attributes => 'class="check_select"') empselection,
apex_item.text(2, ename) empname,
empno,
ename
from emp

Add a class to the checkbox item. This makes it easy to target with jQuery.

向复选框项添加一个类。这使得使用 jQuery 定位变得容易。

Create a new dynamic action, eg "checkbox click".
Event: Click
SelectionType: jQuery Selector
jQuerySelector: .check_select(this is the class we added to the checkbox in the sql)
Condition: JavaScript Expression
Value: $(this.triggeringElement).prop('checked')

创建一个新的动态操作,例如“单击复选框”。
事件:点击
选择类型:jQuery选择器
jQuery选择器:(.check_select这是我们在sql中添加到checkbox的类)
条件:JavaScript表达式
$(this.triggeringElement).prop('checked')

The condition is a check on the checkbox element to see whether it has been checked or unchecked. prop() tests a property of an element, and returns true or false in this case. When true, a true action will fire, else a false action.

条件是检查复选框元素以查看它是否已被选中或未选中。prop() 测试元素的属性,并在这种情况下返回 true 或 false。当为真时,将触发真动作,否则将触发假动作。

True Action:
Action: Execute JavaScript Code
Code: $(this.triggeringElement).closest("tr").find("td[headers='EMPNAME'] input").val('test');

真动作:
动作:执行 JavaScript 代码
代码$(this.triggeringElement).closest("tr").find("td[headers='EMPNAME'] input").val('test');

False Action:
Action: Execute JavaScript Code
Code: $(this.triggeringElement).closest("tr").find("td[headers='EMPNAME'] input").val('');

错误动作:
动作:执行 JavaScript 代码
代码$(this.triggeringElement).closest("tr").find("td[headers='EMPNAME'] input").val('');

Both have no selection types since we need to target items in the same row as that of the clicked checkbox. There isn't really a way to do this through the apex selection possibilities. Target the column through the headers, and don't forget to target the input inside of the td (or: the textarea!)

两者都没有选择类型,因为我们需要定位与单击复选框位于同一行中的项目。没有真正的方法可以通过顶点选择可能性来做到这一点。通过标题定位列,不要忘记定位 td 内部的输入(或:textarea!)

When the dynamic action has been created, go back in. Under Advancedchange the Event Scopeto Live. This is necessary to account for pagination. If you don't change this, no actions will be bound to elements after pagination.

创建动态操作后,返回。在高级下将事件范围更改为Live。这是考虑分页所必需的。如果您不更改此设置,则分页后不会将任何操作绑定到元素。

Then edit the true and false action, and uncheckFire on Page Load.

然后编辑 true 和 false 操作,并取消选中Fire on Page Load

Now to account for your date:
Since you want the sysdate as a default value, i'd suggest to add a hidden item to your page, eg P9_DEF_DATE. As a source, use a PLSQL expression, and use SYSDATE.
You can then use the value of that field as a default value, eg:

现在考虑您的日期:
由于您希望将 sysdate 作为默认值,我建议向您的页面添加一个隐藏项目,例如 P9_DEF_DATE。作为,使用PLSQL 表达式,并使用SYSDATE.
然后您可以使用该字段的值作为默认值,例如:

$(this.triggeringElement).closest("tr").find("td[headers='EMPNAME'] input").val($v('P9_DEF_DATE'));

Last note: blanking out a value through val: use val('')with SINGLEquotes! Won't work with double in my experience.

最后要注意的:消隐通过VAL的值:使用val('')引号!根据我的经验,不会使用 double 。

Some links for Dynamic actions docs:

动态操作文档的一些链接:

An example of an ajax process:
So let's say that i want to update the COMM column of the employee i checked.

ajax 流程的一个例子:
假设我想更新我检查过的员工的 COMM 列。

Create a new process on the page of the report, give it an easy enough name and don't put spaces in it. For example, i'm running with "update_emp".

在报告页面上创建一个新流程,给它一个足够简单的名称,不要在其中放置空格。例如,我正在运行“update_emp”。

update emp
set comm = apex_application.g_x02
where empno = apex_application.g_x01;

Add another true action to the dynamic action, type "Execute JavaScript Code".

向动态动作添加另一个真实动作,键入“执行 JavaScript 代码”。

$.post('wwv_flow.show', 
       {"p_request"      : 'APPLICATION_PROCESS=update_emp',
        "p_flow_id"      : $v('pFlowId'), //app id
        "p_flow_step_id" : $v('pFlowStepId'), //page id
        "p_instance"     : $v('pInstance'), //session id
        "x01"            : $(this.triggeringElement).val(),
        "x02"            : '88', //just a bogus value to demonstrate
        },
        function(data){
           /*normally you'd handle the returned value here
             an example would be a JSON return with which to set item values*/
        }
        );

This javascript will post to the page, targetting the update_empprocess. x01and x02are a sort of 'temp' variables. They exist so we don't have to submit page items all the time in order to post values to the session state. They are part of the apex_application package.
So here i'm using x01to store the empno (value of the checkbox, hence this.triggeringElement), and x02to pass in the value for the commision. I hardcoded it here but you can get any value you'd like of course.

此 javascript 将发布到页面,针对该update_emp过程。x01并且x02是一种“临时”变量。它们存在,因此我们不必一直提交页面项目以将值发布到会话状态。它们是 apex_application 包的一部分。
所以在这里我使用x01来存储 empno(复选框的值,因此this.triggeringElement),并x02传入佣金的值。我在这里对其进行了硬编码,但您当然可以获得任何您想要的值。

$.postis a jQuery method posting to the page.

$.post是一种发布到页面的 jQuery 方法。

When you're learning dynamic actions or trawling forums, you may come across another method to post to the page, namely htmldb_Get, and this is built in in the apex javascript files. I don't use it because it is not true Ajax (asynchronous), but Sjax (synchronous), and is not transparant enough in my opinion. There is i believe some GetAsyncpart to it, which is good and all, but you'll barely ever see it used in any example. Now get.get();may look easy, and you can achieve the same result in 3 lines of code instead of my piece of js, consider it a good practice to implement real ajax calls. You might the wait to finish a process too much at times, and realise all those htmldb_Getcalls in your applications aren't as fun as you think they were...

当您学习动态操作或拖网论坛时,您可能会遇到另一种发布到页面的方法,即htmldb_Get,这是内置在 apex javascript 文件中的。我不使用它,因为它不是真正的 Ajax(异步),而是 Sjax(同步),并且在我看来不够透明。我相信GetAsync它的某些部分,这很好,但是您几乎不会在任何示例中看到它的使用。现在get.get();看起来可能很简单,你可以用 3 行代码而不是我的一段 js 来实现相同的结果,认为实现真正的 ajax 调用是一个很好的做法。有时您可能会等待太多时间来完成一个过程,并意识到htmldb_Get应用程序中的所有这些调用并不像您想象的那么有趣......

Things are also more complicated with this report setup. With page items you can take another route: instead of executing a javascript block you can execute a plsql code block. There you can specify items to be submitted to session state (so they can be used in the plsql block) and items to have their value set by this plsql block. (sql blocks are run server side, which means referenced items need to have their values in session sate). I'd advice to play around with that aswell.
That being said, you could do this with the report actions too, but you'd need to set up some bogus items to temporarily hold values which can then be submitted to session state. Again, i'm no fan of that so i didn't went with that (another 'imo' thus).

此报告设置的情况也更加复杂。对于页面项目,您可以采取另一条路线:您可以执行 plsql 代码块,而不是执行 javascript 块。在那里,您可以指定要提交到会话状态的项目(因此它们可以在 plsql 块中使用)和由该 plsql 块设置其值的项目。(sql 块在服务器端运行,这意味着引用的项目需要在会话状态中具有它们的值)。我建议也玩这个。
话虽如此,您也可以使用报告操作来执行此操作,但是您需要设置一些虚假项目来临时保存值,然后可以将这些值提交到会话状态。再说一次,我不喜欢那个,所以我没有这样做(另一个“imo”)。

Essentially, have a browser inspection tool such as firebug open. It allows you to inspect ajax calls made on pages, and provides a great way to look into this.

本质上,打开一个浏览器检查工具,例如 firebug。它允许您检查在页面上进行的 ajax 调用,并提供了一种很好的方式来查看它。