Wednesday, February 22, 2006

Page 0 Branches

What? There's no way to put a Branch on Page 0 of an ApEx application! Or is there...

Technically, no - page 0 does not support branches. But how many times do you wish it did?

This scenario recently came up: I wanted to put a "Search" box on every page in my application, so no matter where a user is, they can search the site. Currently, it has 10 or so pages, but this will grow to closer to 50 by production.

So, thought #1 was to put an text item on Page 0, call it search, and then ensure that each and every page had some sort of Branch to run the search. Not so fun, as this was a tedious task, even for just 10 pages. And each time a new page was added to the application - by myself or anyone else - the search branch would have to be added to the page. Clearly not a scalable solution.

With a little bit of help from Raj from the ApEx team, I came up with this solution:
  • Create Page 0, if you haven't already
  • On page 0, create an item of type "Text Field (Always submits when enter pressed)" - this will let the user type in a search term and press return and fire off the search, as opposed to having to rely on a button being clicked
  • Create an Application Process (Shared Components > Application Processes)
  • Give it an unusually high Sequence number, such as 999999, as you want it to fire after ALL other page-level processes in your application
  • For the source, enter the following, making sure to use the page number that you want your search to branch to:
htp.init;
owa_util.redirect_url('f?p=&APP_ID.:710:&SESSION.');
htmldb_application.g_unrecoverable_error := true;

  • Put a condition on the Process to only fire when the REQUEST = P0_SEARCH, where P0_SEARCH is the name of your Search text item on Page 0
  • Run your application and test it out
Ideally, you will have some sort of Report on your Search page which is filtered by :P0_SEARCH, but you can really have that page do anything you want. You can also put more logic in the Application Process.

For example, I am using this method to first determine what level of access a user has. If they have Access Level A, then they branch to page 1; otherwise, they branch to page 10. Sure, I could accomplish this at the page level with two branches, but I need this functionality to be available application-wide. Thus, this solution saves me countless hours and some of my sanity.

14 comments:

Chet Justice said...

I had just figured out how to do something similar with buttons on page 0. Did I really have to add branching to each and every page?

I just created an application process that fired on Submit when the Request = BUY. Very cool.

Arie said...

Hi Scott,

I'm trying to understand your logic behind the very high sequence number. If a user using the search box, it usually means that he/she is not interesting in the page specific logic. As the search process is conditioned, I would expect it to receive a very low sequence number, so in case it is fired, it will be executed prior to any other page processes.

Also, what is the purpose of the htmldb_application.g_unrecoverable_error statement?

Thanks,
Arie.

Scott said...

I'm trying to understand your logic behind the very high sequence number. If a user using the search box, it usually means that he/she is not interesting in the page specific logic. As the search process is conditioned, I would expect it to receive a very low sequence number, so in case it is fired, it will be executed prior to any other page processes.

The reason that I recommend a high sequence number is that this Application Process should function as a branch. If you look at the order of operations when a page is submitted:

Validations > Computations > Processes > Branches

Putting it a high sequence number inserts it as close to the branch portion of the processing as possible.

Based on your needs, you can sequence it how you like, of course.

Also, what is the purpose of the htmldb_application.g_unrecoverable_error statement?

This stops all other HTML DB processing & branching. Thus, the owa_util.redirect_url procedure sucessfully fires, and any preceeding branch at the page level is ignored.

Thanks,

- Scott -

Denes Kubicek said...

Hello Scott,

this is funny. Some half a year ago I implemented 99% the same solution in one of my application. The idea was, I can search on different numbers wherever I am - project number, order number, quote etc. It works as you described. The only difference I have is that:

1. the application process fires only if I enter a value to search upon,
2. only if the value matches a required content (numbers only, only numbers in a specific reange),
3. I didn't care about the sequence number

Arie said...

Hi Scott,

I can see your point now, but just to be sure I'm getting the whole picture, is it right to say that application processes will always be evaluated – and fire when necessary – prior to any other page processes, regardless of their higher sequence? (hence the use of the htmldb_application.g_unrecoverable_error statement?


Thanks a lot for your time, patient and the will to share,
Arie.

Scott said...

this is funny. Some half a year ago I implemented 99% the same solution in one of my application. The idea was, I can search on different numbers wherever I am - project number, order number, quote etc. It works as you described. The only difference I have is that:

Yes, you need to have a condition on the Process (REQUEST = Value works well). This way, you will only fire the process when a certain item is clicked/submitted.

- Scott -

Scott said...

I can see your point now, but just to be sure I'm getting the whole picture, is it right to say that application processes will always be evaluated – and fire when necessary – prior to any other page processes, regardless of their higher sequence? (hence the use of the htmldb_application.g_unrecoverable_error statement?

No - the way that I have it set up is that the Application Process will only fire when the REQUEST = Value, where the value is the name of the Search Box (P0_SEARCH in my case). It will, however, fire after all other page processes, as it has a high sequence number. Your needs may be different and require a lower sequence number - all depends on what you want to accomplish.

- Scott -

Anonymous said...

Not exactly related to branches but just Page 0.

I needed some Javascript functions available on almost all pages in my application. I created a Before Header HTML region with No Template and put the SCRIPT in there. Works like a charm!

tylermuth said...

Nice trick that I just used. Never would have thought of this one.

getyour411 said...

After several hours of Google breadcrumb trails and playing with page 0 // Dynamic Actions, I found your Blog post describing the very thing I wanted; thank you so much for posting this.

I see the post came from 2006, is this still the best way in Apex 4.x?

Scott said...

Believe it or not, it's still applicable today, as there is no such thing as a Page 0 Branch, even in APEX 4.0.

- Scott -

Anonymous said...

Scott,

But this doesn't work if you want to redirect to a page that's setup with No URL Access

I am trying to create a common process/branch to redirect to a page(with no url access) based on request.

Cheers

Scott said...

That's correct - No URL Access pages will prevent this solution from working.

When that option is selected, you will need to use a branch to get to that type of page, so off of the top of my head, I can't think of a global solution that would work for that. If I do, I'll post another comment here.

Thanks,

- Scott -

Anonymous said...

Only option I can think of is adding possibility of adding a branch on page 0. :)