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 :)