Tuesday, July 14, 2009

APEX: How to Dynamically Render Regions

Suppose you needed to enable and disable report regions on each page based on a parameter. You could add a condition to each region. If the conditions were all the same, the smart thing to do would be to create a function and have your condition reference the function.

What if your application had 100 pages? Would you remember to apply the condition to each report region in the 100 pages?

This is not a problem that most developers run into, however when you are building large applications something similar may come up. If you can find a way to dynamically control items, regions, processes, etc this can save on development time.

At the ODTUG Kaleidoscope conference Dennis Vanill gave a presentation on how to use Page 0 items to enable and disable APEX objects dynamically. Using this logic, here's an example on how to dynamically disable a region.

Note: Use this when appropriate. For basic conditions stick with using "regular" conditions

A demo is available here: http://apex.oracle.com/pls/otn/f?p=20195:1900

1- Create a page with some report regions

-- Interactive Report:
SELECT *
FROM emp

-- Regular Report
SELECT ename, sal
FROM emp


2- Create Page Process: On Load - Before Header

DECLARE
BEGIN
IF NVL (:p1900_hide_reports_flag, 'N') = 'Y' THEN
FOR x IN (SELECT region_id
FROM apex_application_page_regions
WHERE application_id = :app_id
AND page_id = :app_page_id
AND source_type IN ('Report', 'Interactive Report')) LOOP
FOR i IN 1 .. apex_application.g_plug_id.COUNT LOOP
IF apex_application.g_plug_id (i) = x.region_id THEN
apex_application.g_plug_display_condition_type (i) := 'NEVER';
END IF;
END LOOP;
END LOOP;
END IF;
END;


2- (For Demo purposes only)
I added the following on Page 0 to display in the example application. This shows that no conditions were applied to a region

SELECT region_id,
region_name,
source_type,
condition_type,
condition_expression1,
condition_expression2,
build_option,
authorization_scheme
FROM apex_application_page_regions
WHERE application_id = :app_id
AND page_id = :app_page_id


You can use the same logic to control computations, items, etc. Take a look at apex_application (desc apex_application) for more options.

2 comments:

  1. A notice from the development :-)

    Before you are going to use one of these variables,
    please be aware that most of the apex_application global arrays and variables are for internal use only! They are subject to change.

    If you really go that route, at least make sure that you encapsulated access to them, so that it's easier for you to adapt to future changes.

    Regards
    Patrick

    ReplyDelete
  2. Hi Patrick,

    Thanks for the heads up.

    Martin

    ReplyDelete