动态创建 RadioGroups oracle APEX

发布于 2024-12-28 09:55:57 字数 764 浏览 1 评论 0原文

我目前正在使用 oracle APEX 4.1,并且在动态创建无线电组时遇到问题。

我有一个简单的要求(!)显示表格中的问题列表,并在每个问题旁边显示是/否单选组按钮。问题列表可能会有所不同,因此不是静态的。

为此,我决定创建一个 plsql 匿名块,代码示例如下:

For c1 IN (select * from question)
LOOP
v_row:=v_row+1;
v_rowName:='F'||v_row;
v_radioYes:='<input type="radio" name='||v_rowName||'  value="yes" />Yes';
v_radioNo:='<input type="radio" name='||v_rowName||'  value="no" />No';
v_radio:=v_radioYes||' '||v_radioNo;
htp.p('<tr><td>'||v_row||'. '||c1.Question_text||'</td><td>'||v_type||'</tr>');
END LOOP;

因此会显示问题,并且每个问题旁边还会显示单选组。

我的问题是,在提交时,我需要找出用户为每个问题选择了哪些选项并将其保存到数据库中。很简单,但我无法引用每个问题的单选按钮来了解用户检查的内容。 理想情况下,这些单选按钮应该使用 APEX 工具创建,但我无法动态地循环执行此操作。有没有办法引用这些动态创建的无线电组?我采取了错误的方法吗?

I am currently using oracle APEX 4.1 and have an issue with creating radiogroups dynamically.

I have a simple requirement(!) to display a list of questions from a table and display a yes/No radiogroup button next to each question. The list of questions may vary, so is not static.

To do this, I decided to create a plsql anonymous block and a sample of the code is below:

For c1 IN (select * from question)
LOOP
v_row:=v_row+1;
v_rowName:='F'||v_row;
v_radioYes:='<input type="radio" name='||v_rowName||'  value="yes" />Yes';
v_radioNo:='<input type="radio" name='||v_rowName||'  value="no" />No';
v_radio:=v_radioYes||' '||v_radioNo;
htp.p('<tr><td>'||v_row||'. '||c1.Question_text||'</td><td>'||v_type||'</tr>');
END LOOP;

So the questions are being displayed and the radiogroups are also being displayed next to each question.

My issue is that on submit, I need to find out what options a user has selected for each question and save to a database. Easy, but I cannot reference the radiobuttons for each question to find out what a user has checked.
Ideally, these radio button should have been created using the APEX tool, but I could not get this to do in a loop dynamically. Is there a way of referencing these radiogroups that have been created dynamically? Am I taking the wrong approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若无相欠,怎会相见 2025-01-04 09:55:57

我最近遇到了几乎同样的问题。我找到所选选项的解决方案是将 p_onchange 参数添加到 APEX_ITEM.RADIOGROUP 函数调用(请参阅 Apex 4.1 API 参考)。您可以在那里放置任何 JavaScript 代码。我编写了一个简单的函数来将选定的值分配给隐藏的输入字段。

这是js函数:

function put_selected_value(sel_value) { 
  $x('P66_SELECTED_VALUE').value=sel_value;
}

和RADIOGROUP

apex_item.RADIOGROUP(10, wrk_id, null, null, null, null, 
                     'javascript:put_selected_value(this.value);')

I have encountered almost the same problem recently. My solution to find the selected option was to add p_onchange parameter to APEX_ITEM.RADIOGROUP function invocation (refer to Apex 4.1 API Refernce). You can place any javascript code there. I have written a simple function to assign selected value to a hidden input field.

Here is the js function:

function put_selected_value(sel_value) { 
  $x('P66_SELECTED_VALUE').value=sel_value;
}

and RADIOGROUP

apex_item.RADIOGROUP(10, wrk_id, null, null, null, null, 
                     'javascript:put_selected_value(this.value);')
别闹i 2025-01-04 09:55:57

噗。起初我认为这会更容易一些,但经过一段时间的研究后,我发现无线电组非常令人讨厌。 (这是在 apex 4.1 顺便说一句)

通常我会回应使用 apex_item 将是动态创建项目的方法。然而,无线电组的反应却有所不同。

例如,如果您使用:

for r in(select level l, 'question '||level q, 'Y' a
           from dual 
        connect by level < 6)
loop
   htp.p('<div>'||r.q);
   htp.p(
      APEX_ITEM.TEXT(
       p_idx         => 1,
       p_value       => r.a,
       p_size        => 3,
       p_maxlength   => 1)
   );
   htp.p('</div>');
end loop;

输出将是:

<div>question 1
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 2
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 3
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 4
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 5
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>

太棒了!生成 5 个字段,可使用 apex_application.g_F01 数组访问,其中字段 1 为 apex_application.g_f01(1)

然而,无线电组的反应不同。 APEX_ITEM.RADIOGROUP 所做的实际上并不是创建单选组,而是创建单选按钮。该组将是 f01 数组。
哇哦!我不喜欢那样! F## 数组一开始仅从 1 到 50,因此如果您生成一些项目,这并不理想。
另外,你的逻辑也被搞砸了:突然你不再需要循环遍历数组,而是遍历数组。

例如,如果您将 apex_item.text 替换为 apex_item.radiogroup ,输出将如下

<div>question 1
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 2
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 3
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 4
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 5
<input

所示项目。如果您单击问题 4 处的按钮,并且问题 1 之前已被标记,则该标记将从问题 1 中删除并设置为 4。

但是它可以工作。当您提交并循环 F01 数组时,它会传递值:

--this after submit process
for i in 1..apex_application.g_f01.count
loop
apex_debug_message.log_message('array F01: item '||i||': '||apex_application.g_f01(i));
end loop;

--results in this debug message:
--array F01: item 1: Y

好的,那么您有什么选择呢?不要使用这个。它不是动态的!你不能循环 50 个数组,除非你在每个数组上编写 50 个循环……

那么 APEX 实际上是如何工作的呢?查看页面项单选组的输出代码时,输​​出如下:

<input type="hidden" name="p_arg_names" value="50795996117686343389" />
<fieldset id="P3_RGROUP_PAGE_ITEM" tabindex="-1" class="radio_group">
<input type="radio" id="P3_RGROUP_PAGE_ITEM_0" name="p_t01" value="Yes" checked="checked"   />
<label for="P3_RGROUP_PAGE_ITEM_0">Y</label><br />
<input type="radio" id="P3_RGROUP_PAGE_ITEM_1" name="p_t01" value="No"    />
<label for="P3_RGROUP_PAGE_ITEM_1">N</label></fieldset>

看到隐藏项了吗?我假设 apex 将选定的值放入该隐藏项目中,因此您可以轻松引用单选组的选定值。

这可能是解决此问题的最佳方法。生成您的单选组和按钮,并使用 JavaScript 将选定的值放入隐藏项中。您可以使用 apex_item.hidden 创建隐藏项,谢天谢地,您之后可以在数组中轻松引用它。如果您使用p_idx =>; 1,所有隐藏项将存储到数组g_f01中。

您只需要将此隐藏项目搭载在您的无线电组容器中即可。然后将 onchange 事件绑定到您的单选按钮。
例如,看看这个 jsfiddle。这会将所选值保留在隐藏项中,该值将在提交时发布。

抱歉这篇文章太长了,我没想到它会变得如此复杂。希望有人能向我们展示一种简单的方法:)

Pfew. At first i thought this'd be a bit easier, but after mucking around a while i found radiogroups to be quite the toothgrinder. (this is on apex 4.1 btw)

Normally i'd respond that using apex_item would be the way to go to dynamically create items. However, radiogroups react with a twist.

If you'd use for example:

for r in(select level l, 'question '||level q, 'Y' a
           from dual 
        connect by level < 6)
loop
   htp.p('<div>'||r.q);
   htp.p(
      APEX_ITEM.TEXT(
       p_idx         => 1,
       p_value       => r.a,
       p_size        => 3,
       p_maxlength   => 1)
   );
   htp.p('</div>');
end loop;

The output would be:

<div>question 1
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 2
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 3
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 4
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>
<div>question 5
<input type="text" name="f01" size="3" maxlength="1" value="Y"  />
</div>

Great! 5 fields generated, accessible by using apex_application.g_F01 array, where field 1 would be apex_application.g_f01(1).

Radiogroups however react differenty. What APEX_ITEM.RADIOGROUP does is not actually creating a radiogroup, but creating a radiobutton. The group would then be the f01 array.
Woah! I don't like that! The F## arrays only go from 1 to 50 to start with, so if you'd generate a few items, this is not ideal.
Also, your logic gets screwed: suddenly you don't have to loop over an array anymore, but over arrays.

For example, the output would be like this if you'd replace apex_item.text with apex_item.radiogroup

<div>question 1
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 2
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 3
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 4
<input type="radio" name="f01" value="Y"   />Yes?
</div>
<div>question 5
<input

It sort of did what you asked: it created a radiogroup consisting of the items. If you'd click the button at question 4 and question 1 was previously marked, the mark will be removed from question 1 and set to 4.

It works however. When you submit and loop over the F01 array, it'll pass the value along:

--this after submit process
for i in 1..apex_application.g_f01.count
loop
apex_debug_message.log_message('array F01: item '||i||': '||apex_application.g_f01(i));
end loop;

--results in this debug message:
--array F01: item 1: Y

Okay, so what are your options then? Don't use this. It is not dynamic! You can't loop over the 50 arrays, unless you write 50 loops over each array...

So how does APEX actually work then? When looking at the output code of a page item radiogroup, this is the output:

<input type="hidden" name="p_arg_names" value="50795996117686343389" />
<fieldset id="P3_RGROUP_PAGE_ITEM" tabindex="-1" class="radio_group">
<input type="radio" id="P3_RGROUP_PAGE_ITEM_0" name="p_t01" value="Yes" checked="checked"   />
<label for="P3_RGROUP_PAGE_ITEM_0">Y</label><br />
<input type="radio" id="P3_RGROUP_PAGE_ITEM_1" name="p_t01" value="No"    />
<label for="P3_RGROUP_PAGE_ITEM_1">N</label></fieldset>

See the hidden item? I assume apex puts the selected value in that hidden item, so you can easily reference the chosen value of the radiogroup.

This is probably the best way you can solve this. Generate your radiogroups and buttons and put the selected value in a hidden item using javascript. You can create the hidden item using apex_item.hidden, which you can thankfully refer to easily in an array afterwards. If you'd use p_idx => 1, all hidden items will be stored to array g_f01.

You'll just need to piggyback this hidden item in your radiogroup container. Then bind an onchange event to your radiobuttons.
Example, look at this jsfiddle. This'll keep the selected value in the hidden item, which will be posted on submit.

Sorry for the lenghty post, i didn't think it'd get so complicated. Hopefully someone comes along and shows us an easy way :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文