How to select arabic menu name when login to Arabic application in APEX? - oracle-apex

I created multi language application in oracle apex to use English and Arabic from shared components then globalization selected from Application Language Derived From session
also created dynamic menu this is the query :
select level Level_value ,
menu_name label_value,
apex_page.get_url(p_page => module_id) target_value ,
null is_current,
icon_image image_value
from (
select menu_id , parent_m_id,m.module_id,decode(apex_util.get_session_lang,'en',ar,en) menu_name , icon_image,menu_seq
from system_menu m , user_rights r
where user_id = :APEX_USER_ID
and m.module_id = r.module_id
)
start with parent_m_id is null
connect by prior menu_id = parent_m_id
order siblings by menu_seq
also this is the columns of table system_menu
CREATE TABLE "SYSTEM_MENU"
( "HOSPITAL_NO" VARCHAR2(10) NOT NULL ENABLE,
"MENU_ID" NUMBER(5,0) GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
"PARENT_M_ID" NUMBER(5,0),
"MODULE_ID" NUMBER(5,0),
"AR" VARCHAR2(100) NOT NULL ENABLE,
"EN" VARCHAR2(100) NOT NULL ENABLE,
"ICON_IMAGE" VARCHAR2(100),
"IS_MENU" VARCHAR2(1) NOT NULL ENABLE,
"MENU_SEQ" NUMBER(5,0),
CONSTRAINT "SYSTEM_MENU_PK" PRIMARY KEY ("MENU_ID", "HOSPITAL_NO")
USING INDEX ENABLE
)
in the login page I created an item to select the language and created process to set the language depends on the selected language this is the process PL/SQL code
begin
apex_util.set_session_lang(p_lang => :P9999_LANG);
end;
now when I switch language to arabic its not read the menu arabic name always show EN value
How to read AR column value when select arabic language after login can I make if condition if :P9999_LANG = 'en-us' select EN name and if :P9999_LANG = 'ar-ae' select AR name from the table ?

Related

Set column value from Application Item by using JavaScript in Oracle APEX interactive grid

i want to set column value in IG when user press Save. i have 2 columns 'created_by' and 'updated_by', now when my primary key column :P8_ID is null then should set 'created_by' column value using application item :SESSION_USER_ID which was set at login and 'updated_by' when :P8_ID is not null.
i can set using process on a Form where 'Page Items' are available but how to do the same for IG columns? please guide. --using Apex 21.1--
A common practice in apex applications is to have the audit columns on a table (created (date), created_by, updated (date) and updated_by) set by a trigger. The advantage of this approach is that this is transparent in your application. You don't have to worry about the audit columns anywhere in the application where insert/updates are done.
Example on a dummy table:
create or replace trigger test_table_biu
before insert or update
on test_table
for each row
begin
if inserting then
:new.created := sysdate;
:new.created_by := coalesce(sys_context('APEX$SESSION','APP_USER'),user);
end if;
:new.updated := sysdate;
:new.updated_by := coalesce(sys_context('APEX$SESSION','APP_USER'),user);
end test_table_biu;
/

How to attatch Dynamic Action or Process to a Menu Popout list item - APEX 21.1

I'm trying to add a dropdown menu button to a classic report row and assign the menu items either a process or DA. I've used the Universal Theme docs to help me figure out how to get the menu button added to a classic report, but now I'm stuck and do not understand how to assign/attach a Dynamic Action or Process to each item in my menu list:
APPROVE WORKLOAD
ASSIGN WORKLOAD
For this instance, both menu items will just open a dialog page passing in the primary key of the row (MASTER_ID), but some other actions elsewhere will need to handle more complex logic where APEX Processing or DA would be best.
I would be surprised APEX does not have something like this to be implemented natively since there is something similar with Interactive Grids and is a common web pattern.
UPDATE: I went ahead and added this as an APEX Idea (FR-2133) here. If you think this is something worth adding to APEX, please give it an upvote.
There isn't a built-in solution for this unfortunately. There is a good blog post by John Snyders that describes a way of building this yourself.
I have also built some similar functionality, which I have a demo of here. This uses a bespoke table to store the menu options, and makes an AJAX call when the menu is opened to get the appropriate menu entries to display. These can be conditional e.g. the "Calculate commission" menu entry is only applicable to employees with job='SALESMAN'.
Tables
create table report_menus
( menu_name varchar2(30),
constraint report_menus_pk primary key (menu_name)
);
create table report_menu_entries
( menu_name varchar2(30) not null enable,
entry_title varchar2(100) not null enable,
entry_target varchar2(1000) not null enable,
display_sequence number,
condition_type varchar2(30),
condition_expression varchar2(4000),
constraint report_menu_entries_pk
primary key (menu_name, display_sequence),
constraint report_menu_entries_fk1
foreign key (menu_name)
references report_menus (menu_name)
);
(Table REPORT_MENUS is there for completeness but doesn't do much in this demo).
Sample data
For my example I created a single menu called 'EMPLOYEE_MENU' with 2 options:
insert into report_menu_entries values
( 'EMPLOYEE_MENU',
'Update',
'f?p=&APP_ALIAS.:3:&SESSION.::&DEBUG.:3:P3_EMPNO:<pk>',
1,
'NOT_EXISTS',
'select * from emp where empno=<pk> and job = 'PRESIDENT''');
insert into report_menu_entries values
( 'EMPLOYEE_MENU',
'Calculate commission',
'javascript:alert('Not yet implemented');',
2,
'EXISTS',
'select * from emp where empno=<pk> and job='SALESMAN''');
I have invented a special placeholder <pk> which I use wherever I want to plug in the primary key of the record we are on (i.e. the EMPNO in this demo). This is required in the target URL and in conditions that depend on the data.
Report region
In the report, I create a dummy column for the menu by selecting null as menu. I make this into a Link with a target URL of # (we don't need the target really) and these properties:
Property
Value
Link text
<span class="fa fa-navicon" aria-hidden="true" title="report menu"></span>
Link attributes
class="report-menu" data-key="#EMPNO#" data-menu="EMPLOYEE_MENU"
The link text displays a suitable icon, and the properties are what make it start to work. The data-key attribute defines the primary key value for this row, and the data-menu attribute specifies which of our REPORT_MENUS to use.
Dynamic Action
We now need a dynamic action to handle clicking on the menu. This uses a jQuery selector .report-menu to identify the link being clicked, and it executes this Javascript code:
showReportMenu (this.triggeringElement);
Javascript code
showReportMenu is a Javascript function defined as follows:
function showReportMenu (pLink) {
var theLink = $(pLink);
var dataMenu = theLink.attr("data-menu");
var dataKey = theLink.attr("data-key");
apex.server.process ( "Show_Report_Menu", {
x01: dataMenu,
x02: dataKey
}, {
success: function( pData ) {
$('div#reportMenu').remove();
var html = '<div id="reportMenu" ><ul>';
for (i=0; i<pData.menu.length; i++) {
if (pData.menu[i].url == '') {
html = html + '<li><span>' + pData.menu[i].title + '</span></li>';
} else {
html = html + '<li>' + pData.menu[i].title + '</li>';
}
}
html = html + '</ul></div>';
$(theLink).after(html);
$('#reportMenu').menu({}).menu("toggle",theLink);
}
});
}
That invokes an AJAX callback application process 'Show_Report_Menu' which returns JSON containing the menu options, which are then displayed.
Application process
The 'Show_Report_Menu' process just calls a procedure:
report_menu_pkg.render_menu
( p_menu_name => apex_application.g_x01
, p_keyvals => apex_application.g_x02
);
Package procedure code
The procedure does the work of looking up the menu entries for the menu, deciding whether they should be shown for the key value, and returning the JSON for the ones to show. It looks like this:
procedure render_menu
( p_menu_name varchar2
, p_keyvals varchar2
)
is
l_first boolean := true;
k_template constant long := '{"title": "%0", "url": "%1"}';
l_buffer long;
l_test_sql long;
l_count integer;
begin
-- Construct a JSON object to return the menu entries e.g. {"menu": [{"title": "Update", "url": ".."}, {"title": "Delete", "url": "..."}]}
sys.htp.p('{"menu": [');
-- Process the menu entries in display sequence order and check any condition before adding to the JSON
<<entries>>
for r in (
select *
from report_menu_entries
where menu_name = p_menu_name
order by display_sequence
) loop
-- Check any condition, substituting placeholder <pk> with the actual key value
case r.condition_type
when 'EXISTS' then
l_test_sql := 'select count(*) from dual where exists (' || replace (r.condition_expression, '<pk>', p_keyvals) || ')';
execute immediate l_test_sql into l_count;
continue entries when l_count = 0;
when 'NOT_EXISTS' then
l_test_sql := 'select count(*) from dual where exists (' || replace (r.condition_expression, '<pk>', p_keyvals) || ')';
execute immediate l_test_sql into l_count;
continue entries when l_count = 1;
else
null;
end case;
-- Separate entries by commas (no comma befor first)
if l_first then
l_first := false;
else
sys.htp.p (',');
end if;
-- Replace placeholders in target URL including the key value
r.entry_target := replace (r.entry_target, '<pk>', p_keyvals);
r.entry_target := replace (r.entry_target, '&APP_ALIAS.', v('APP_ALIAS'));
r.entry_target := replace (r.entry_target, '&SESSION.', v('SESSION'));
r.entry_target := replace (r.entry_target, '&DEBUG.', v('DEBUG'));
r.entry_target := apex_util.prepare_url (r.entry_target);
-- Construct JSON entry
l_buffer := apex_string.format (k_template, r.entry_title, r.entry_target);
sys.htp.p(l_buffer);
end loop entries;
if l_first then
l_buffer := apex_string.format (k_template, '(No actions available)', null);
sys.htp.p(l_buffer);
end if;
sys.htp.p(']}');
end;
I think that's everything. There is room for improvement, as this is only demo code. Ideally the JSON would be constructed more robustly using APEX_JSON or whatever, and it should be able to handle composite keys e.g. by passing in a comma-separated list of values and specifying e.g. <pk1>,<pk2> as placeholders.

How to ajax refresh a region in ORACLE Apex - based on a selection in a Badge List [Plugin]

I have a badge list plug in returning a few items:
SQL for the badgel list plug-in is below:
WITH
STUDY_MV AS
(
SELECT /* MATERIALIZE */
* FROM VW_GRET_CTA_STUDIES
WHERE GRET_ID = :P14_GRET_ID
AND STUDY_CODE = :P14_STUDY_CODE
AND VARIATION_REQUEST_ID IS NULL
AND APPLICATION_TYPE = 'Clinical Trial Application'
)
select
'1) Despatched CTA' as label,
(SELECT COUNT(DISTINCT REGISTRATION_UID) FROM STUDY_MV
WHERE
STUDY_STATUS = 'Despatched'
) as value,
'Despatched' AS STUDY_STATUS,
APEX_PAGE.GET_URL (
p_page => 15,
p_items => 'P15_GRET_ID,P15_PREVIOUS_PAGE,P15_STUDY_CODE,P15_STUDY_STATUS',
p_values => :P14_GRET_ID || ',14,' || :P14_STUDY_CODE || ',Despatched') as url
from dual
UNION
select
'2) Submitted CTA' as label,
(SELECT COUNT(DISTINCT REGISTRATION_UID) FROM STUDY_MV
WHERE
STUDY_STATUS = 'Submitted'
) as value,
'Submitted' AS STUDY_STATUS,
APEX_PAGE.GET_URL (
p_page => 15,
p_items => 'P15_GRET_ID,P15_PREVIOUS_PAGE,P15_STUDY_CODE,P15_STUDY_STATUS',
p_values => :P14_GRET_ID || ',14,' || :P14_STUDY_CODE || ',Submitted') as url
from dual
This works...
I was originally using the URL to go to another page (page 15), and was passing parameters to it...but I now need to do a refresh (ajax/dynamic action) of another region on the same page based on the selection in the badge list. i.e. if they click the "Submitted" bage, then an interactive grid on the same page gets refreshed over ajax to only show "Submitted" records).
The interactive grid has the following SQL:
SELECT
DISTINCT
reg_flag_passive,
study_status,
registration_uid,
application_stage,
application_type,
lu_withdrawn_dt,
country_display_label,
authorization_status,
registration_name_details,
registration_number,
reg_remarks,
region,
preferred_trade_name,
lu_despatched_dt,
LU_SUBMITTED_DT,
lu_resubmitted_dt,
lu_approved_dt,
lu_non_submission_approval_dt,
lu_approved_inc_non_sub_year,
lu_approved_inc_non_sub_dt,
lu_cancelled_dt,
lu_report_due_dt,
lu_rejected_dt,
lu_planned_submission_dt,
LU_EXPECTED_APPROVAL_DT,
cta_ind_no,
study_code,
gret_id
FROM
vw_gret_cta_studies WHERE STUDY_CODE = :P14_STUDY_CODE AND GRET_ID = :P14_GRET_ID
AND VARIATION_REQUEST_ID IS NULL
AND APPLICATION_TYPE = 'Clinical Trial Application'
AND
1 = (CASE WHEN :P14_STUDY_STATUS IS NULL THEN 1 ELSE CASE WHEN STUDY_STATUS = :P14_STUDY_STATUS THEN 1 ELSE 0 END END)
What I need to do is POPULATE the :P14_STUDY_STATUS page item, to session, with the selected STUDY_STATUS value clicked within the badge-list plug in, and then perform a refresh of the interactive grid region - which will pick up the :P14_STUDY_STATUS value in the query.
I am guessing that in order to write things into session via javascript, and then refresh a region (e.g. call a dynamic action to do it) - then I need to perhaps modify the URL I am generating in the badge list SQL to make a javascript call? But having no luck at all.

Oracle Apex - How Show Image in a Dynamic List

I have created dynamic list for sub-menu page,now i want to show image for each list entry
A nice feature is to use Apex Font Awesome icons.
Here's an example of a dynamic list query, based on Scott's DEPT table:
select
null lvl,
dname,
'#' target,
null is_current,
case when deptno = 10 then 'fa-thumbs-o-up'
when deptno = 20 then 'fa-thumbs-o-down'
end icon
from dept
order by deptno
When you add the list to the page (as a region), navigate to its "Attributes" and modify template options by setting the "Display icons" property to "For all items".
Once you run the page, you'll see a thumb up icon by department 10 and thumb down for department 20.
List of all available icons is here.
The answer is in Example 1 in the SQL page of the Create List wizard:
Example 1:
SELECT null,
ENAME label,
null target,
'YES' is_current,
'#APP_IMAGES#del.gif' image, -- <-- HERE
'width="20" height="20"' image_attrib,
ENAME image_alt
FROM emp
ORDER BY ename
first use query like below:
select
1 level,
dname label,
'#' target,
null is_current,
'IMAGE'||img_name image
from dept
order by deptno
with this query img_name set as class for each card. after that use this javascript code on page load:
var spns = document.getElementsByTagName("span");
for (var i = 0; i < spns.length; i++) {
if (spns[i].className.includes('-IMAGE')) {
spns[i].style.backgroundImage = "url(#IMAGE_PREFIX#"+spns[i].className.substring(5)+")";
$('.'+spns[i].className.substring(5)).css("background-size", "cover");
}
}
for this background image url should exist images on ords server.
good luck

Complex SQL syntax

I have a game, and in the database I'm saving the user actions by date & time.
CREATE TABLE user_actions
(
aId BIGSERIAL PRIMARY KEY NOT NULL,
userId BIGINT NOT NULL REFERENCES users(uId) DEFERRABLE INITIALLY DEFERRED,
aDate TIMESTAMP without time zone DEFAULT now(),
aType INTEGER NOT NULL DEFAULT 0
);
My users are identified with email
CREATE TABLE users(
uId BIGSERIAL PRIMARY KEY NOT NULL,
uName VARCHAR (50) NOT NULL,
uEmail VARCHAR (75) UNIQUE NULL
);
and each day new prizes are added each day has a different number of prizes
CREATE TABLE prizes(
pId BIGSERIAL PRIMARY KEY NOT NULL,
pDate TIMESTAMP without time zone DEFAULT now(),
pType INTEGER NULL
pSize INTEGER NULL
);
This query list the userId and his last action date, per user
select distinct userId, max(aDate) from user_actions GROUP BY userId order by userId;
I want to create a query that will count the number of prizes added since each user last action.
I'm running:
OS: Debian
DB: Postgresql
code: Django
I think I will use CTE though It has not been tested
WITH last_actions AS (
SELECT DISTINCT userId, MAX(aDate) as last_logged
FROM user_actions
GROUP BY userId ORDER BY userId)
SELECT a.userId, COUNT(b.pDate)
FROM last_actions a, prizes b
WHERE b.pDate >= a.last_logged
GROUP BY a.userId;