Skip to main content

Custom Action Menu in Oracle APEX Reports

Couple of days before, my client asked me to bring an action menu in interactive report instead of bringing multiple icons (buttons) in each row. I searched in google and found excellent blog post from John Snyders, where he explained the steps to bring custom action menu in oracle apex interactive report is amazing. He has done his job with lots of love. I tried his solution and it worked.

Here I am giving an example to create custom menus in Oracle apex interactive report using JavaScript.

This demo consists of 3 pages. The main page (page 1) is an Interactive Report showing the departments from the eba_demo_chart_dept table. The report includes an Actions column with a menu button in it. This means there is a menu button in each row and the actions in that menu are specific to the department in the row. 

Opening the menu gives you the option to Edit the department in a modal dialog page (page 3) or go to an employee report page (page 2) that shows all the employees from the eba_demo_chart_emp table in that department. 

The ACCOUNTING department has the Edit menu item disabled.

Create a interactive report region to the page 1 using below query.

SELECT edcd.deptno,
       edcd.dname,
       edcd.loc,
       CASE WHEN edcd.deptno = 10
            THEN 'Y'
            ELSE 'N'
        END AS LOCKED,
       trim( BOTH '''' FROM regexp_substr( apex_util.prepare_url( 'f?p='
                  || v('APP_ID')
                  || ':3:'
                  || v('APP_SESSION')
                  || '::NO::P3_DEPTNO:'
                  || edcd.deptno ), '''f\?p=[^'']*''')) AS edit_link
FROM eba_demo_chart_dept edcd

The LOCKED column will be used to control the disabling of menu items. You will have your own business rules.

The EDIT_LINK to extract the dialog URL. It calls PREPARE_URL with the desired URL that includes the DEPTNO page item value. It then uses a regular expression to extract the URL and then strips off the single quotes.

LOCKED and EDIT_LINK columns are both hidden as the values are only needed in the Actions column. 

The DEPTNO select column is the report Actions column and uses the following HTML Expression.


<div class="report-actions">
<button type="button" class="t-Button t-Button--icon t-Button--noLabel js-menuButton" 
data-menu="actionsMenu" aria-label="Actions" title="Actions" 
data-id="#DEPTNO#" data-link="#EDIT_LINK#" data-title="#DNAME#" 
data-locked="#LOCKED#"><span aria-hidden="true" 
class="fa fa-bars a-icon"></span><span aria-hidden="true" 
class="fa fa-chevron-down"></span></button>
</div>

To create the menu, the following code to be added to the page Execute when Page Loads attribute.


var menu$ = $("<div id='actionsMenu'></div>");
$("body").append(menu$);
menu$.menu({
    iconType: "fa",
    items: [
        {
            type: "action",
            labelKey: "ACTION_EDIT",
            icon: "fa-pencil",
            action: function(menu, btn) {
                // open dialog page 3 for the specific department
                // the dialog url including checksum is in the data-link attribute 
                // on the button that opens the menu
                var link,
                button$ = $(btn);
                // get the link and unescape unicode chars
                link = button$.attr("data-link").replace(/\\u(\d\d\d\d)/g,
 function(m,d) {
                    return String.fromCharCode(parseInt(d, 16));
                });
                apex.navigation.dialog(link,
                                       {title: apex.lang.getMessage("TITLE_DEPT"), 
                                        resizable: true, draggable: true, height: 280,
 width: 460}, 
                                       "t-Dialog--standard",
                                       button$);
            },
            disabled: function() {
                var btn$ = $("button.is-active.js-menuButton");
                return btn$.attr("data-locked") === "Y";
            }
        },
        {
            type: "action",
            labelKey: "ACTION_EMP",
            icon: "fa-users",
            action: function(menu, btn) {
                // go to the employee page (2) for the specific department
                var btn$ = $(btn);
                apex.navigation.redirect(apex.util.makeApplicationUrl({
                    pageId:2,
                    itemNames: ["P2_DEPTNO", "P2_TITLE"],
                    itemValues: [btn$.attr("data-id"), btn$.attr("data-title")]
                }));
            }
        }
    ]
});

[Create Text Messages] Go to Shared Component => Text Messages with Used in JavaScript set to Yes. In the demo app I created the following text messages.


The demo is here.

Download and import the Custom Menu Demo App in your work space.

Output:

That's it.

Happy APEXing!!!...

Reference/Credits:

Comments

Post a Comment

Popular posts from this blog

Printing Page Numbers in RTF Template [Oracle BI Publisher]

Here I am giving an example to print the page numbers dynamically in the RTF (Rich Text Format) template. Step 1:  Go to page footer and copy and paste the below script. Page |  <?fo:page-number?>  of  <?fo:page-number-citation:xdofo:lastpage-joinseq?> <fo:page-number> :   This is the object, which is used to represent the current page-number. <?fo:page-number-citation:xdofo:lastpage-joinseq?> :  This is the syntax, which is used to represent the total number of pages. Step 2:  Load the XML and preview the result. Output: That's it. References: fo:page-number Printing Page Number Code in Oracle XMLP RTF Template

Generating the report with APEX_DATA_EXPORT

With the APEX_DATA_EXPORT package, you are able to export data from Oracle Application Express in the following file types: PDF, XLSX, HTML, CSV, XML, and JSON. Step 1: Create a table and populate it with some sample records. CREATE TABLE emp   (     empno        NUMBER,     first_name   VARCHAR2(240),     last_name    VARCHAR2(240),     mgr          NUMBER,     deptno       NUMBER,     sal          NUMBER,     created_date TIMESTAMP (6),     comm         NUMBER,     hiredate     DATE,     JOB          VARCHAR2(240),     ename        VARCHAR2(240),     PRIMARY KEY (empno) USING INDEX ENABLE   ); /    INSERT INTO emp (empno, first_name, last_name, mgr,                   deptno, sal, created_date)         VALUES                 (1, 'Larry', 'Ellison', ,                  10, 5000, LOCALTIMESTAMP);   INSERT INTO emp (empno, first_name, last_name, mgr,                   deptno, sal, created_date)         VALUES                 (2, 'Juan', 'Juan', 1,  

Save Selected Interactive Grid Records into a Collection - Oracle APEX

Here I am giving an example to save selected interactive grid records into a oracle apex collection. Step 1: Create a new blank page. Note: Mine was page 20. You will need to update reference to " P20 " with your page number if it's different. Step 2: Create a new interactive grid report region to the page using below query. Set Static Id "EmpDetails" to the region. SELECT  *     FROM   ( SELECT  emp . empno ,                emp . ename ,                emp . JOB ,                dept . dname department ,                dept . loc  LOCATION ,                mgr . ename  manager ,                emp . hiredate ,                 nvl ( emp . sal , 0 )  salary ,                 nvl ( emp . comm , 0 )  commission            FROM  eba_demo_chart_emp emp ,                eba_demo_chart_dept dept ,                eba_demo_chart_emp mgr           WHERE  emp . deptno = dept . deptno             AND  emp . mgr      = mgr . empno  ( + )           ORDER   BY  emp . ename