Thursday, July 7, 2011

What you may need to know about the conditional activation of the task flow embedded in an <af:popup> ?

You can configure the activation of task flow using 'active' property of the taskFlow binding. The details are available in the fusion developers guide - 21.6 Configuring Activation of an ADF Region

I would like to share a couple of points I learned on this topic while working with developers. Its interesting and may save your time as well ;)

While configuring the activation of task flow, you may need to key in value for activation and active flags. Apart from these two, there is one more attribute RefreshCondition which decides the 'life' of task flow.


Common mistakes in using RefreshCondition and active properties

RefreshCondition="#{some.EL.expression}": The ADF region is refreshed when RefreshCondition evaluates true. Please note that you may not really need to use this for lazy initialization of task flow, use active and activation flags instead. In case, if you are using this, please note the RefreshCondition should only evaluate to true when you want the
task flow to start/restart. You may need to make your EL to return false once task flow is active. Failing to do so will cause task flow to reset/restart for each post back. A typical usage of this flag may be, restart the task flow while the region is active. Here you need to ensure the RefreshCondition evaluates to true when you want the task flow to restart and false at all other times.

activation: Though you can specify values like conditional/deferred/active for this flag, in this post I discuss conditional activation. Setting activation=conditional, activates the ADF region if the EL expression set as a value for the task flow binding 'active' property(discussed below) returns true.

active="#{some.EL.expression}": This is the area where you may need to be careful. If the activation is set as conditional, the the EL for active property must evaluate to true for each postback for the region to remain active. This implies that the scope where you keep the active flag should be long enough to survive multiple requests from the client while working on task flow.
Let me explain this with a simple example. Assume that you built a task flow and wanted to display in an af:popup. Apparently you might not want to activate the task flow till user opts to view the pop up dialog. You may end up in using active flag to control the activation of task flow. Consider an EL as shown below for the active flag.

active="#{empty requestScope.activeFlag ? false : requestScope.activeFlag}"

What is wrong with this?

Well, its syntactically valid, however may not help you to achieve the desired functionality. Because whatever you store in requestScope is valid for that specific request. Consider your task flow popup dialog is displayed with the above 'active' settings. All went well so far. Then user does some action which may trigger some server interaction. While posting back to server, run time will evaluate active EL before processing task flow. Whatever you set to the requestScope in the previous request may not be available for the new request and EL will be evaluated to false, and your task flow dialog may appear as frozen.

What is the solution?

You may need to keep the activation flag in higher scopes - pageFlowScope or sessionScope. Better one may be pageFlowScope. (Please note that dialog window may not be able to access view scope of the parent view, so we don't use view scope in this specific context)

active="#{empty pageFlowScope.activeFlag ? false : pageFlowScope.activeFlag}"

Download

You can download the example workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

A glance at the implementation

This example uses employee-task-flow which is displayed inside popup dialog. The activation of the task flow is controlled using active="#{empty pageFlowScope.activeFlag ? false : pageFlowScope.activeFlag}" for <taskFlow> binding. The activeFlag is set true from the popupFetchListener method defined in the MainBean class.




Learn More ...

There are a lot more points like this. If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

4 comments:

Harman Arneja said...

Hello Mr Jobinesh,
I've this problem with popup, where I've dropped a task flow(train) as region in the popup. I've also dropped a show popup behaviour on a command link but the popup doesn't load in the webpage at runtime on clicking at the command link. I've set the trigger type to click and and the popid is also correct... Could you please suggest a solution.
Thanks
Harman

Jobinesh said...

Harman,
See partialSubmit=trueis set for the button which display popup.You may also want to check the server console for any errors. The above steps are enough to make it wolrking

Harman Arneja said...

The Partial submit property is set to true, but still no luck...

Anonymous said...

@"The activeFlag is set true from the popupFetchListener method defined in the MainBean class."

Hi Jobinesh,

what about de-activating af:region (task flow) inside af:popup ? What you missed, is :

1. popupCanceledListener, which sets activeFlag to false (in combination with "ifNeed" Refresh property for the t.f. binding)

OR

2. some kind of serverPopupClosed server method, which responds to the popupClosed af:clientListener

I am right ?

Regards, Cvele