Thursday, July 16, 2009

APEX_APPLICATION.DO_SUBSTITUTIONS

I've run into several instances where I needed to store HTML in a table. The problem is sometimes the HTML references APEX Items. For example if your HTML needs to reference a picture, odds are you'll need to reference &APP_IMAGES. (or some image location item). In the past I've done manual REPLACE calls for known items, but it was fairly restrictive.

APEX has a great function (not yet documented to my knowledge) called APEX_APPLICATION.DO_SUBSTITUTIONS. If you pass in a string, it will substitute any APEX values. Here's an example app: http://apex.oracle.com/pls/otn/f?p=20195:2000

To create demo:

1- Create table and insert values


CREATE TABLE tp2000(line_content CLOB NOT NULL);

INSERT INTO tp2000
VALUES ('Google Canada Picture: ');

INSERT INTO tp2000
VALUES ('My Current Session: ' || CHR (38) || 'APP_SESSION.');


2- Create Report Region (with substitutions)

SELECT apex_application.do_substitutions (line_content) content_with_subs
FROM tp2000


3- Create Report Region (without substitutions)

SELECT line_content content_without_subs
FROM tp2000

Wednesday, July 15, 2009

APEX: How to Develop in 2 Browser Tabs

I saw this during a presentation by Anton Nielsen last year. If you've developed with APEX for a while then you've probably wanted to have 2 developer tabs open on your browser at the same time. You'll quickly find out that this doesn't work to well.

There's an easy way around it. Lets say you're developing on an instance running on your laptop. The URL you normally go to looks something like: http://localhost:8080/apex/

Go into your hosts file (C:\WINDOWS\system32\drivers\etc\hosts for Windows users). You should see an entry like this:

127.0.0.1 localhost

Add: 127.0.0.1 giffy01 on a new line (where "giffy01" is any arbitrary name).

Your hosts file should now look like:

127.0.0.1 localhost
127.0.0.1 giffy01

In your favorite web browser,



open the following URLs in 2 different tabs:

http://localhost:8080/apex/
http://giffy01:8080/apex/

You can now have 2 development tabs open at the same time.

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.

Thursday, July 2, 2009

APEX: Saving item values for each user

Someone asked me today if APEX could remember input values for specific page items. For example if you have a page with report parameters could APEX remember the report parameters that the user last used the next time they logged in?

APEX doesn't support this out of the box, however it does have some great features which can enable you to do this. You can use cookies for this but I wanted to make the solution work no matter where the user was accessing the application from.

To make things a bit more difficult, I don't want to remember all item values on a page so I must be able to control which items are "remembered" and which items aren't. I can do this by using a naming convention in my items, however I don't want to rename all my page items (I already have a lot of them). Instead I decided to create a table which will list all the items a user can remember.

You can try the demo here (follow the instructions on the page).


CREATE TABLE tapex_remember_page_item(
application_id NUMBER NOT NULL,
page_id NUMBER NOT NULL,
item_name VARCHAR2(255) NOT NULL);

-- You don't need to add a UK, however it may be a good idea.
ALTER TABLE tapex_remember_page_item ADD(
CONSTRAINT tapex_remember_page_item_uk1
UNIQUE (application_id, page_id, item_name));

-- Since I name all my APEX items in uppercase, just do this as an extra precaution
CREATE OR REPLACE TRIGGER trg_tapex_remember_pg_itm_buir
BEFORE UPDATE OR INSERT
ON tapex_remember_page_item
FOR EACH ROW
BEGIN
:NEW.item_name := UPPER (:NEW.item_name);
END;
/

INSERT INTO tapex_remember_page_item
(application_id, page_id, item_name)
VALUES (20195, 1800, 'P1800_DEPTNO');


INSERT INTO tapex_remember_page_item
(application_id, page_id, item_name)
VALUES (20195, 1800, 'P1800_MIN_SAL');


For this example we'll store the values as APEX Preferences, however you could easily create your own preferences table to manage your data. I think they're several advantages to managing the preferences in your own table, however if you have a small application with a limited number of users then I'd recommend using the APEX_UTIL preference options


Create 2 Application Processes:

AP_GET_PAGE_ITEM_PREFS
On Load: Before Header (page template header)


DECLARE
BEGIN
FOR x IN (SELECT item_name
FROM tapex_remember_page_item
WHERE :app_page_id = page_id
AND :app_id = application_id) LOOP
apex_util.set_session_state (p_name => x.item_name,
p_value => apex_util.get_preference (p_preference => x.item_name,
p_user => :app_user
)
);
END LOOP;
END;



AP_SET_PAGE_ITEM_PREFS
On Submit: After Page Submission - After Computations and Validations


DECLARE
BEGIN
FOR x IN (SELECT item_name
FROM tapex_remember_page_item
WHERE :app_page_id = page_id
AND :app_id = application_id) LOOP
apex_util.set_preference (p_preference => x.item_name, p_value => v (x.item_name), p_user => :app_user);
END LOOP;
END;


For those of you that are curious APEX Preferences are stored in : apex_030200.wwv_flow_preferences$ where apex_030200 is the schema name for APEX (could also be called flows_xxxxxx)

Sunday, June 28, 2009

ODTUG Kaleidoscope 2009 Summary



I just got back from ODTUG Kaleidoscope 2009. I met a lot of great people and saw many excellent presentations. My biggest regret was not being able to see everyone's presentations! Here are some highlights from the conference:

Sunday APEX Symposium: Saw some excellent presentations on how APEX was used in other organizations.

- Joel Kallman (Oracle) had a great opening presentation going over the history and future of APEX

- Olivier Dupont (iAdvise): Excellent use of APEX at the airport, even without a mouse or browser access!

- My presentation: Mike Kinahan did a great job filling in for Frank Hoogendoorn on short notice, however my camera man wasn't as good (see picture below). If anyone has some pictures of the presentation can you please let me know?



- Dennis Vanill (PAETEC Software): Using page 0 to cut down on common task for many pages.

- Jan Navratil (CampusIT): Demonstrated that APEX can be used in mission critical applications. Use translation as a configuration technique for each client's definitions.

- Paul Davidson (Cornerstone Brands): APEX used in large scale call center and how he cut down call time.

- Shravan Kumar (Apexor): created the term LAOS (Linux, Apache, Oracle, SQL Developer). Cut down long processes into 4 minutes using APEX!

- David Peake (Oracle): Anounced an APEX development contest for some free tickets to Open World.

Presentations:

- Tom Kyte(Oracle) as always had some great presentation and demo. He stressed (again) use the database for as much as you can since Oracle will do things quicker and faster for you.

- Michael Hichwa (Oracle): APEX 4.0 Demo. I'll write a separate post about this soon since it will take a lot of space (it's just that good)
Edit: 1-Jul-2009. Role Hartman wrote an excellent post for APEX 4.0. Please read it for more info: http://roelhartman.blogspot.com/2009/07/buzz-around-apex-40.html

- Dietmar Aust (Opal Consulting): Free PDF and XLS printing options for APEX. Check his blog for full details

- Scott Spendolini (Sumner Technologies): Managing Multiple APEX applications as one. The full sample application is on his web site here: http://sumnertechnologies.com/framework

- Patrick Wolf (Oracle): Had 2 great presentations. I missed his first one, but was able to attend his second presentation. Besides the content he's an excellent speaker so if you ever have a chance to see him present you should go! Patrick was kind enough to show Dennis and I some more APEX 4.0 features and answer a lot of my questions.

- Francis Mignault (Insum): Multi tenant SaaS APEX applications. I develop SaaS applications as well and it was really nice to see a different development approach.

- Patrick Cimolini (Cayman Island Government): Development Rules and Guidelines Document for APEX. If you're looking for a simple yet effective way to create a APEX standards document I strongly suggest you get a copy of his presentation (I'm going to see if he'll allow me to post a copy here).

- John Scott (Apex Evangelists): Unfortunately I wasn't able to see any of his presentations but I heard they were really good, I'll have to get a copy of his slides and white papers later on.