exercising ARP on a page with plenty of items - oracle-apex

I have an apex form composed of around 50~ text fields and radio buttons.
I tried to create a page process for automated row processing. It works fine but only if my table has a column for each page item.
even though the page items are plenty, actually the question behind them is the same. So what I really want to perform is to collect those data row by row. i.e.
instead of
1 True False True foo
I'd like to store my data like this
1 True foo
2 True goo
3 False hoo
50 False zoo
Since I couldn't find a way to customize ARP, I decided to do it with some manual work.
However I still have this feeling that my efort is futile. I can't help but thinking there must be some other, wiser solutions than being have to create insert/update statements for entire page. I mean I can't be the only one who came up with this need, right?
Thank you very much in advance.

I hope you can achieve your requirement using APEX_COLLECTION. It stores the data temporarily that are associated with the session of the user currently logged into the application. below is the sample code for your reference.
begin
if not apex_collection.collection_exists('SAMPLE_COLLECTION') then
APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(p_collection_name => 'SAMPLE_COLLECTION');
apex_collection.add_member(
p_collection_name => 'SAMPLE_COLLECTION',
p_c001 => :P1_TEST_ITEM1,
p_c002 => :P1_TEST_ITEM2,
p_c003 => :P1_TEST_ITEM3,
p_c004 => :P1_TEST_ITEM4,
p_c005 => :P1_TEST_ITEM5,
);
end if;
end;
You can select the data stored using the below SELECT statement.
select c001, c002,c003,c004, c005
from apex_collections where collection_name = 'SAMPLE_COLLECTION'
Please refer this link to explore more on APEX_COLLECTION

Related

Oracle APEX - how to read a cell from interactive grid

The same question once again but with (I hope) better explanation:
I created the most simple case:
An Interactive Grid IG with data source EMP ( table with 14 records contains Ename, Job, HireDate, Salary etc. etc.)
Text field P7_ENAME
After running it looks like below:
What I would like to do is to copy Ename from selected record of IG to P7_ENAME field .
I found several tutorials (text and video) how to do it. Most of them suggest to create dynamic action SelectionChange on IG and when TRUE add a JavaScript code something like below:
var v_ename;
model = this.data.model;
v_ename = model.getValue( this.data.selectedRecords[0], "Ename");
apex.item( "P7_ENAME" ).setValue (v_ename);
and the second step is to create another action: Refresh.
So finally I have a dynamic action with two steps : the first one is a Java script code and the second refresh function on my P7_ENAME field.
Sounds simple and it is simple to repeat/implement. A guy (I suppose) from India published a video on YouTube (https://www.youtube.com/watch?v=XuFz885Yndw) which I followed and in his case it works good. In my case it simple does not work - field P7ENAME is always empty, no errors appears. Any idea why ? Any hints, suggestion ?
thanks for any help
K.
The best way to debug and achieve what you are trying to do is as follows:
create the Dynamic action with the following setup:
-when -> selection change[interactive grid],
-selection type -> region, region -> your IG region,
-client side condition -> javascript expression: ```this.data.selectedRecords[0] != undefined```
First action of the true of the DA with the type: execute javascript code and fire on initialization is turned on, code: console.log(this.data.selectedRecords);
Run your page, and check the browser console. You should see an array of columns when you select a record from that IG as follows:
Find in that array, which sort number of the array contains the data that you want to use for the page item. Let's say I want the 3rd element which is "2694" then I should change my dynamic action's execute javascript code to:
var value = this.data.selectedRecords[0][2];
apex.item( "P7_ENAME" ).setValue (value);
The last thing I should do is add another true action (and the refresh action at the end) to the same dynamic action with type 'SET VALUE' and 'PLSQL EXPRESSION' as type, put :P7_ENAME in the expression, items to submit P7_ENAME and affected element: item / P7_ENAME as follows:

Get the values of the selected rows with checked checkbox

Having a report of the services table with checkbox for each row, I am trying to get the values of the selected service, so that when I click on next I can create a report with the services chosen in the new page.
I have tried in this way:
Report of the services table.
select code,
name,
cost,
apex_item.hidden(p_idx => 1,
p_value => code) ||
apex_item.hidden(p_idx => 2,
p_value => cost) ||
apex_item.checkbox2(p_idx => 3,
p_value => code) CheckBox
from services
I created a process.
Source:
begin
apex_collection.CREATE_OR_TRUNCATE_COLLECTION ('SDBA_ORDER_ITEMS1');
for i in 1..apex_application.g_f01.count loop
apex_collection.add_member(
p_collection_name => 'SDBA_ORDER_ITEMS1',
p_c001 => to_number(apex_application.g_f01(i)), -- service_code
p_c002 => to_number(apex_application.g_f02(i)), -- cost
p_c003 => to_number(apex_application.g_f03(i)) -- service_code
);
end loop;
end;
Server-side Condition:
begin
for i in 1..apex_application.g_f01.count loop
for j in 1..apex_application.g_f03.count loop
if apex_application.g_f01(i) = apex_application.g_f03(j) then
return true;
else
return false;
end if;
end loop;
end loop;
end;
Report on the next page.
select (select name from services where code = c001) as service_name,
c002 as cost
from apex_collections
where collection_name = 'SDBA_ORDER_ITEMS1'
order by 1
Report on the next page.
select (select name from services where code = c001) as service_name,
c002 as cost
from apex_collections
where collection_name = 'SDBA_ORDER_ITEMS1'
order by 1
In this report it shows all the services of the table instead of the selected ones.
How can I get only the selected rows? Can anybody help me please?
Thanks in advance.
Checkboxes are formed into dense collections, not potentially sparse like the other item types. I think this is a product of web tech, not APEX.
So if you had ID, Name, Checkbox
1 - ada - checked
2 - charles - not checked
3 - alan - checked
There would be 3 index elements in ID and Names array, and only 2 in the checkbox array - and index element 3 would be empty.
So you need to match checkbox existence by indexing by the code value, and checking for existence more like
apex_application.g_f03(apex_application.g_f01.code)
While taking care of potential no_data_found
Reading Oracle documentation:
Note that check boxes displayed using APEX_ITEM.CHECKBOX only contain values in the APEX_APPLICATION arrays for those rows which are checked. Unlike other items (TEXT, TEXTAREA, and DATE_POPUP) which can contain an entry in the corresponding APEX_APPLICATION array for every row submitted, a check box only has an entry in the APEX_APPLICATION array if it is selected.
I've build my report referencing rownum on APEX_ITEM.CHECKBOX.
Report code:
SELECT APEX_ITEM.CHECKBOX(p_idx => 1, p_value => ROWNUM) checkb
,APEX_ITEM.HIDDEN(p_idx => 2, p_value => CUSTOMER_ID)||CUSTOMER_ID CUSTOMER_ID
,APEX_ITEM.HIDDEN(p_idx => 3, p_value => CUST_STATE)||CUST_STATE CUST_STATE
,CUST_FIRST_NAME ||' '||CUST_LAST_NAME
FROM DEMO_CUSTOMERS
And then based on that checked rows, the process is recovering the values in the hidden items arrays corresponding position.
Process PL/SQL code:
BEGIN
--
FOR i IN 1..APEX_APPLICATION.G_F01.COUNT LOOP
--
INSERT INTO ROMINA_TEST (LOG)
VALUES ('CUSTOMER_ID: '||APEX_APPLICATION.G_F02(APEX_APPLICATION.G_F01(i))||' - CUST_STATE: '||APEX_APPLICATION.G_F03(APEX_APPLICATION.G_F01(i)));
--
END LOOP;
--
END;
And it works! =)

Select list display issue

Good morning,
within Oracle Apex Application Builder I'm trying to create a order product page which displays products from a product table, shows a select list which a user can use to define the quantity in which they want to order. Using a classic report to display my code, the declared table columns were generated and outputted on the report, however the select list column only shows the html syntax used to create a select list and not the actual drop down select list with values.
Here is the code:
select p.product_id,
p.product_name,
p.product_price,
apex_item.hidden(1, p.product_id) ||
apex_item.hidden(2, p.product_price) ||
apex_item.select_list(
p_idx => 3,
p_value => nvl(c.c003,'Add_to_cart'),
p_list_values => '1,2,3,4,5,6,7,8,9,10',
p_show_null => 'YES',
p_null_value => 0,
p_null_text => '0',
p_item_id => 'f03_#ROWNUM#',
p_item_label => 'f03_#ROWNUM#',
p_show_extra => 'NO') "add_to_cart"
from prod p, apex_collections c
WHERE c.collection_name (+) = 'ORDER_ITEMS'
and c.c001 (+) = p.product_id
Can someone explain why this is happening, how to correct my issue and if there are better ways to implement a select list; as I need this code to work for my project?
Thanks in-advance for the help!
In Builder, navigate to that column so that you'd see its properties. Scroll down to Escape special characters and set it to "No". Then run the report and see whether there's any improvement (should be).

Update cell of APEX_COLLECTION in interactive grid

I have a interactive grid with a full join on the wwv_flow_qb_saved_query table and the apex_collection, like this:
Select
qbsq.ID,
qbsq.TITLE,
qbsq.QB_SQL,
qbsq.DESCRIPTION,
ac.collection_name,
ac.seq_id,
ac.C001 as new_TITLE,
ac.CLOB001 as new_QB_SQL,
ac.C002 as new_DESCRIPTION
FROM APEX_050100.WWV_FLOW_QB_SAVED_QUERY qbsq
full join apex_collections ac
on qbsq.TITLE = ac.C001
The result look like this:
Now I need to make the possibility for users to change the title of the apex_collection, so the title in the "imported queries" column group. If the title is updated and different from the title of the existing queries, there would be a new grid entry.
I tried to do it in the "save interactive grid data" process => settings => target type => pl/sql code with
declare
collection_name varchar2(255);
seq_id number;
new_title varchar2(4000);
begin
collection_name := :COLLECTION_NAME;
seq_id := :SEQ_ID;
new_title := :NEW_TITLE;
case v('APEX$ROW_STATUS')
when 'U' then
APEX_COLLECTION.UPDATE_MEMBER_ATTRIBUTE (
p_collection_name => collection_name,
p_seq => seq_id,
p_attr_number => 1,
p_attr_value => new_title);
end case;
end;
But something just doesn't work and I can't change the title. Am I missing something? Please could someone help me find the problem. I couldn't find any other helpful posts..
Thanks
Thanks to Tony Andrews, for the solution I just had to change in the regions attributes the "Allowed Row Operations Column" to "null".
WHy are you using collection? With IG you can modify data , change the pagination and return to the previous pagination , all your change will be there.

How can I assign a shared foreign key to all records inserted using the Data Load Wizard?

I have an ApEx application which, amongst other purposes, has a requirement to upload billing data provided by telecommunications providers. The data is being provided as a CSV file.
We have two tables. The first table, phone_invoice, contains per-invoice metadata such as billing dates and provider name. The second table, phone_invoice_detail is based largely on call logs.
phone_invoice_detail has a foreign key, invoice_id, which keys into phone_invoice(id). This creates a stock-standard master-detail relationship.
We have used the ApEx Data Load Wizard to set up the import capability for our users. But I need to assign the invoice_id to each imported row.
Currently, I have a Phone Invoice page. Users click a button, "Import Data for Invoice", which branches to the Data Load Wizard and sets a page item, P1000_INVOICE_ID with the value of that invoice ID -- P999_ID.
When the user begins the process, the CSV data supplied has all the fields except for an invoice ID. What I want is for that column in the underlying table -- invoice_id -- to be set to to the value of P1000_INVOICE_ID.
My current focus is on using the Transformation Rules. This has been tremendously frustrating because the documentation tells you nothing about them and there are no examples.
Permutations I have tried:
-- PL/SQL Expression:
:INVOICE_ID := :P1000_INVOICE_ID
:INVOICE_ID := :P999_ID
SELECT :P1000_INVOICE_ID INTO :INVOICE_ID FROM DUAL
SELECT :P999_ID INTO :INVOICE_ID FROM DUAL
-- Replace:
-- Expression 1 Expression 2
:P1001_INVOICE_ID :INVOICE_ID
:P999_INVOICE_ID :INVOICE_ID
As you can see, APEX creates 4 pages for import. And it use apex collection named LOAD_CONTENT to store imported data. So, you can change this collection before it will be loaded into the table.
Go to the page named 'Data Validation' (this page have report Data Validation), and add page process, with next parameters:
Type: PL/SQL anonymous block
Process Point: On Load - Before Header
Source:
declare
-- Local variables here
i integer;
begin
for i in (
select t.seq_id
from apex_collections t
where t.collection_name = 'LOAD_CONTENT'
) loop
apex_collection.update_member_attribute(
p_collection_name => 'LOAD_CONTENT',
p_seq => i.seq_id,
p_attr_number => 3, -- here number of your column you want update
p_attr_value => :P1000_INVOICE_ID -- value
);
end loop;
end;
But change in this process number of your column.
I've tried this example in my APEX version 4.1 - it works fine.