How to conditionally render fields in oracle apex? - oracle

I'm trying to create a form that updates a table, but it should be in such that, only those fields that the admin wants to update appear in the form on the next page.
Suppose we choose a row with the id 1 to update,next the admin should be able to choose the fields he wants to update.

One option is to create a table which contains that page item names (e.g. P1_ID, P1_NAME, P1_ADDRESS, ...) and a column which says whether it'll be rendered or not (let's call it CB_RENDER). Admin would update that table and decide whether to render an item (and set cb_render = 1) or not. Table contents would then be
ITEM_NAME CB_RENDER
---------------- ---------
P1_ID 1
P1_NAME 1
P1_ADDRESS 0
Create a function which accepts item name as argument and returns cb_render value:
create or replace function f_render_item (par_item_name in varchar2)
return number
is
retval number;
begin
select cb_render
into retval
from that_table
where item_name = par_item_name;
return retval;
end;
Use that function in every item's Server-side condition; its type would be a function that returns Boolean:
return f_render_item (:APP_ITEM_NAME) = 1;
It evaluates to TRUE if function returns 1 (which means that item will be rendered).
That's all, more or less.

Related

Oracle APEX -How to combine server side condition of "requet = expression1" and "exisits ( sql query return atleast one row)

I want to call validation when
query return at least one row like ( select 1 from table where id = 1 )
and
when request "add_data" is called
Don't know what to select here:
The value of request can be accessed via the bind variable REQUEST . To tackle your specific problem you could add that to your condition of type 'Rows returned' like this:
SELECT 1
FROM table
WHERE (
id = 1 AND
:REQUEST = 'add_data'
)
If you're more a fan of pl/sql you could take the condition type 'PL/SQL Function Body' with code like this:
DECLARE
l_dummy NUMBER;
BEGIN
-- quit here if request value doesn't match
IF :REQUEST != 'add_data' THEN
RETURN false;
END IF;
-- check if we have rows in table.
BEGIN
SELECT 1
INTO l_dummy
WHERE EXISTS (select 1 from table where id = 1)
EXCEPTION WHEN NO_DATA_FOUND THEN
RETURN false;
END;
RETURN true;
END;
This is more code but you could find it easier to read which can be an advantage for maintenance later on.
The way I understood it, add_data request is related to a button you push. If that's so, then - if you don't do anything, request name equals button name - so let's pretend that button name is ADD_DATA. Therefore:
in "When Button Pressed" property select button's name (ADD_DATA, right?)
in "Condition Type" pick the condition you mentioned ("SQL query returns at least one row")

Navigation menu access control through DB - Apex oracle

I have a table with Page and its page numbers stored in it. I want to show only those bars on the navigation menu whose page numbers are assigned to the end user. How can I do it?
I'm using Apex 19.1
Create a function which returns a Boolean, saying whether certain user can (or can not) access certain page, e.g.
create table t_access as
select 1 page_no, 'LITTLE' app_user, 'Y' yn from dual union all --> can access page 1
select 2 page_no, 'LITTLE' app_user, 'N' yn from dual; --> can NOT access page 2
create or replace function f_access(par_page_no in number, par_app_user in varchar2)
return boolean
as
l_yn t_access.yn%type;
begin
select a.yn
into l_yn
from t_access a
where a.page_no = par_page_no
and a.app_user = par_app_user;
return l_yn = 'Y';
exception
when no_data_found then
return false;
end;
Use that function in navigation list entry's conditions property; make it a "PL/SQL function body returning a Boolean" as
return f_access(1, :APP_USER);

Return one variable from a SELECT inside a function

I'm trying to create a function that return a varchar, one of the fields form a select, the aggregation field. I'm getting the next error:
ORA-01422: exact fetch returns more than requested number of rows
What I understand is that the select produce more than one row before aggregating and this triggers the error when trying to put them 'into k, s, categories'
Here is the function:
FUNCTION get_cat(kind_id IN varchar, system_id IN Number) RETURN VARCHAR2
AS categories VARCHAR2(2000);
k STANDARDS.KIND_ID%TYPE;
s SEEDTEST_RESULT.SLRN_ID%TYPE;
BEGIN
SELECT STANDARDS.KIND_ID, SEEDTEST_RESULT.SLRN_ID,
listagg(CAT_LEVEL, ' ' ) within group (order by cat_level)
INTO k, s, categories
FROM STANDARDS, SEEDTEST_RESULT
WHERE STANDARDS.CL_PRIORITY = SEEDTEST_RESULT.CL_PRIORITY
AND SEEDTEST_RESULT.RESULT = 1
AND SEEDTEST_RESULT.TEST_TYPE = 'C'
AND STANDARDS.KIND_ID = trim(kind_id)
AND SEEDTEST_RESULT.SLRN_ID = system_id
GROUP BY STANDARDS.KIND_ID, SEEDTEST_RESULT.SLRN_ID;
RETURN categories;
END get_cat;
The select statement works outside the function when I run it with specific values for kind_id and system_id.
I've been trying to create a temp table so I can get the initial rows from the select and then return categories, but so far I haven't been able to find any helpful information for this particular case. Does anyone knows how can I do this, please?
Thank you.
The problem is with your variable names:
FUNCTION get_cat(kind_id IN varchar, ...
...
AND STANDARDS.KIND_ID = trim(kind_id)
You have a column called kind_id and the query will use that in preference to the PL/SQL variable of the same name.
From the documentation:
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
So you aren't matching the passed-in value, you're actually finding all rows which match system_id for any value of kind_id. (Except null, and if they have leading/trailing whitespace...)
Change your variable names so they do not clash and there is no confusion. It's common to prefix passed-in argument with, say, a p prefix so you'd be comparing with = p_kind_id, and local variables with an l prefix.
If you really want to keep the names you have, you can also prefix the references to those with the function name:
AND STANDARDS.KIND_ID = trim(get_cat.kind_id)

Changing a 0 or 1 value to "Yes" and "No" in APEX report

I have a report region on my page and it's getting data from a students table. Within that table, there's a column called cv_lodged which is either 1 or 0 representing Yes or No. In the report it shows this columns data as 0 or 1, I want to change it to show Yes or No.
How can I do this?
You can put a CASE statement in your query
SELECT (CASE WHEN cv_lodged = 1
THEN 'Yes'
ELSE 'No'
END) cv_lodged,
other_columns
FROM students
If this is something that is likely to be common, you're probably better served creating a function that converts your pseudo-boolean data to a string. Something like
CREATE FUNCTION my_bool_to_str( p_num IN NUMBER )
RETURN VARCHAR2
IS
BEGIN
IF( p_num = 1 )
THEN
RETURN 'Yes';
ELSE
RETURN 'No';
END IF;
END;
that you would call in your query
SELECT my_bool_to_str( cv_lodged ) cv_lodged,
other_columns
FROM students
I've usually just created a static LOV in Shared Components called YES1_NO0, with 2 entries: 'Yes' -> 1, 'No' -> 0.
In Interactive Reports you can then change these columns. To do this, edit the column of the IR. Change 'Display Type' to 'Display as Text (based on LOV, escape special characters)'. Then under 'List of Values' set 'Column Filter Type' to 'Use Named List of Values to Filter Exact Match' and select the named LOV.
But sure, you can totally do this in SQL.
Currently, there is a simpler way to do this.
First open the APEX page with the "Yes/No" item as developer and click on the item to open the page item settings.
Change the Settings value from Use component settings to Custom.
Afterwards change the Yes Value to 1 and the No Value to 0.
This solution has some advantages:
No need to decode the value 1 or 0 to Y or N (select decode(mycolumn, 1, 'Y', 'N') from mytable where id = 123;) or select case when ...
No need to decode the submitted value back to 1 or 0 from Y or N

Setting the value of a form field from a Query

I have a form field where one of the values has a default value defined in a an application settings table. The user would see the default value upon display of the create form, but could change it to another value if they wanted prior to saving the new row.
I don't see any way in the field defaults to specify that the default value is the result of an SQL query (e.g. select default_rate from app_defaults where row_key = 1).
Surely this has to be possible, but how?
As posted to Jeffrey above, final solution can be done completely within APEX but using the Default Value Type = PL/SQL Function Body on the page item.
DECLARE default_value number(9,2);
BEGIN
SELECT deflt_rate INTO default_value FROM app_defaults WHERE row_key = 1;
RETURN default_value;
END;
You can use the SQL query in a PL/SQL block to assign it directly, e.g.
SELECT default_rate
INTO :myblock.rate
FROM app_defaults
WHERE row_key = 1;

Resources