Clear Cache for all Pages within a Page Group
Most client sites I have been on tend to love wizards that hold the users hand through often complex business process / workflows.
As a general rule, if I have a 10 step wizard (I generally use 1 page per step) I like to ensure that all 10 pages have their cache cleared as the user enters the wizard to ensure no values from a previous attempt to complete the process are hanging around. This is typically done by enter a comma delimited string of all the page numbers you wish to clear the cache of upon branching from page to page.
In an ideal world, what I wanted to do was take advantage of the fact that I had taken to time to put all 10 pages into a page group and clear the cache of ALL pages contained within. Furthermore, using this logic, pages can come and go from the page group without the need to worry about how this effect my clearing of session state. Pretty cool huh, but wait, "APEX only allows you to enter page numbers and not page group names into the clear cache text box" I hear you say.
Not a problem. This can be achieved very simply by using an Application Item, A Single Application Process and Page Groups. Here is how:
Solution.
1. Create a Page Group with a name the logically describes the functional area it servers. In this example I will use the name: "CREDIT_CARD_APPLICATION".
2. Edit the definition of all pages (10 in my case) and them to this newly created group.
3. Create an Application Item called the same name as your group created in step 1 i.e. my Application Item was named: "CREDIT_CARD_APPLICATION".
4. Create an Application Process called: "Get CRETID_CARD_APPLICATION_PAGES" and of Process Type: "On New Instance (new session)" and add the following code to the Process Text region:
BEGIN
select LISTAGG(page_id,',') WITHIN GROUP (ORDER BY page_id)
into :CREDIT_CARD_APPLICATION_PAGES
from apex_application_pages where application_id = :APP_ID
and page_group = 'CREDIT_CARD_APPLICATION';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
:CREDIT_CARD_APPLICATION_PAGES := NULL;
WHEN OTHERS
THEN
RAISE;
END;
5. Finally, in the branch that you want to clear the cache for all pages within the page group, simply place a substitution string reference to &CREDIT_CARD_APPLICATION_PAGES. in the clear cache text box and viola!!!
Explanation.
This very simply queries the APEX Data Dictionary to work out all the pages within your names Page Group.
It then uses the XMLAGG aggregation function native to 11gR2 (I blogged about this here) to build a comma delimited string of all these pages and assigns the output to your application item. (Not is done once per session for performance reasons).
Now that you have a list of all the pages in your page group as a value in session, you can substitute this into any branch using the standard substitution syntax. Simple really but ideally, it would be nice if Oracle provided this out of the tin. Until then, this seems to be a pretty good workaround.
As a general rule, if I have a 10 step wizard (I generally use 1 page per step) I like to ensure that all 10 pages have their cache cleared as the user enters the wizard to ensure no values from a previous attempt to complete the process are hanging around. This is typically done by enter a comma delimited string of all the page numbers you wish to clear the cache of upon branching from page to page.
In an ideal world, what I wanted to do was take advantage of the fact that I had taken to time to put all 10 pages into a page group and clear the cache of ALL pages contained within. Furthermore, using this logic, pages can come and go from the page group without the need to worry about how this effect my clearing of session state. Pretty cool huh, but wait, "APEX only allows you to enter page numbers and not page group names into the clear cache text box" I hear you say.
Not a problem. This can be achieved very simply by using an Application Item, A Single Application Process and Page Groups. Here is how:
Solution.
1. Create a Page Group with a name the logically describes the functional area it servers. In this example I will use the name: "CREDIT_CARD_APPLICATION".
2. Edit the definition of all pages (10 in my case) and them to this newly created group.
3. Create an Application Item called the same name as your group created in step 1 i.e. my Application Item was named: "CREDIT_CARD_APPLICATION".
4. Create an Application Process called: "Get CRETID_CARD_APPLICATION_PAGES" and of Process Type: "On New Instance (new session)" and add the following code to the Process Text region:
BEGIN
select LISTAGG(page_id,',') WITHIN GROUP (ORDER BY page_id)
into :CREDIT_CARD_APPLICATION_PAGES
from apex_application_pages where application_id = :APP_ID
and page_group = 'CREDIT_CARD_APPLICATION';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
:CREDIT_CARD_APPLICATION_PAGES := NULL;
WHEN OTHERS
THEN
RAISE;
END;
5. Finally, in the branch that you want to clear the cache for all pages within the page group, simply place a substitution string reference to &CREDIT_CARD_APPLICATION_PAGES. in the clear cache text box and viola!!!
Explanation.
This very simply queries the APEX Data Dictionary to work out all the pages within your names Page Group.
It then uses the XMLAGG aggregation function native to 11gR2 (I blogged about this here) to build a comma delimited string of all these pages and assigns the output to your application item. (Not is done once per session for performance reasons).
Now that you have a list of all the pages in your page group as a value in session, you can substitute this into any branch using the standard substitution syntax. Simple really but ideally, it would be nice if Oracle provided this out of the tin. Until then, this seems to be a pretty good workaround.
Comments
I like your workaround for what could be a neat little feature if expanded upon in a more general sense: the ability to declaratively reference page groups.
This could be used in various places in APEX. As a target for clearing cache as you said, but for other things too, like component conditions. Rather than use "Current Page Is Contained Within Expression 1 (comma delimited list of pages)", you could just select "Current Page Is Within Page Group" and then somehow specify the page group. Very cool indeed.
I recommend you post this to the new feature request application for APEX: https://apex.oracle.com/pls/apex/f?p=55447
Then leave a note here about which key it is so others that like it can vote for it.
Regards,
Dan
It makes total sense to have declarative access as you mentioned so let's hope this simple request makes the cut.
Duncs
Actually, I didn't add it - I didn't want to steal your thunder ;)
I was just suggesting that you do so. Having said that I'd be more than happy to add this if you like.
Regards,
Dan
Request added as Row Key: ABOD
https://apex.oracle.com/pls/apex/f?p=55447:1