Thursday, August 12, 2010

Refresh the parent view when a taskflow displayed in a popup returns

This post discusses an interesting use case on refreshing the parent view when an in-line popup taskflow returns. There are two taskflows, both work with separate transaction contexts(Transaction attribute is set as new-transaction). Second taskflow is invoked from the first one as a dialog. The requirement here is to refresh the 'executables' of calling page(from first taskflow) when the second taskflow returns. This scenario usually arises when the second task flow updates tables used by the first one from a different transaction context.

To learn more on taskflow, please refer Part III Creating ADF Task Flows in Fusion Middleware Fusion Developer's Guide for Oracle ADF.

Cool, now back to the use case. One possible solution for the above scenario is to define a returnListener for secondary window on the command button (which invokes second taskflow as dialog) and add the custom logic to refresh the underlying IteratorBindings used by the parent page. Last step is to manually refresh the parent view by adding it as PartialTarget - RequestContext.getCurrentInstance().addPartialTarget(returnEvent.getComponent().getParent().getParent());
That's it, job is done. I'm copying the relevant code snippet below for your reference.
<af:commandMenuItem text="Create" id="cmi1" action="create"
useWindow="true"
windowEmbedStyle="inlineDocument"
windowModalityType="applicationModal"
returnListener="#{viewScope.RefreshBean.dialogReturnListener}"
windowHeight="250" windowWidth="500"/>
public void dialogReturnListener(ReturnEvent returnEvent) {
  BindingContext bc = BindingContext.getCurrent();
  DCBindingContainer dcb =
    (DCBindingContainer)bc.getCurrentBindingsEntry();
  DCIteratorBinding iter =
    dcb.findIteratorBinding("DepartmentsView1Iterator");
  iter.executeQuery();
  RequestContext.getCurrentInstance().addPartialTarget(returnEvent.getComponent().getParent().getParent());

}

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS2 + HR Schema]

How to run this sample?

Run the main.jspx. This page contains 'outer-task-flow-definition' which displays Departments details on a table. Select the 'create' menu item from the toolbar, which opens up 'inner-task-flow-definition' in a popup. Key in the new department details and click on Save. This action closes the popup and then refreshes the parent view to display new record.


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

18 comments:

Anonymous said...

Thanks for posting this, however there is one problem with this, you see a blank page for 1-2 seconds and then it loads the view

May be its a ADF bug?

Thanks,
Harry

Anonymous said...

to be specific, second taskflow running as a Dialog with inline-popup it launches and shows blank view till pageDef executed with all data to display.

Harry

Jobinesh said...

Harry,
This seems to be the delay in loading the task flow( server round trip + execution + loading). btw, thanks for pointing out, will try to see whether this can be optimized/fine tuned further.

Anonymous said...

Is there a way to avoid user interaction during the 1-2 sec delay during the page refresh?

Thanks,
Suneetha

Jobinesh said...

Suneetha
You can take a look at this post
http://jobinesh.blogspot.com/2010/10/preventing-user-input-on-fusion-web.html
Please see whether this helps you here

sunil ravinder said...
This comment has been removed by the author.
sunil ravinder said...
This comment has been removed by the author.
sunil ravinder said...

Hi jobinesh,

I have a scenario where the second taskflow is not shown in a popup, but is part of the parent page itself.

If my parent page has a table, how do I refresh the table (as i don't want whole page refresh) when I am doing a save in the second taskflow..

Any ideas ?

Thanks

Jobinesh said...

Sunil,
One possibility is to use Contextual Events. Details can be found here-
http://download.oracle.com/docs/cd/E15523_01/web.1111/b31974/web_adv.htm#CACJBFGI

Daniel said...

Jobinesh,

I am using a inline popup to solve my specific scenario. By default, it already comes with an "x" button that closes the popup. If I add the code you published in some kind of "Close" our "Save" button like you did, if the user decides to close de window by the native X button, it won't refresh the parent page. What would you suggest me do?

Jobinesh said...

Daneil,
One possibility is to embed the taskflow in your own popup and add a popupCanceledListener. Another option may be( not a gr8 solution) hide the close icon using skinning

Daniel said...

Jobinesh,

Thanks for the quick answer! I'm sorry, but i'm still a newbie to ADF. What do you mean when you say "embed the taskflow in my own popup"?
Currently, I have a bounded taskflow for my inline popup (with a close function that calls a taskFlowReturn), and my home page calls this taskflow from a menu option.
I'm gonna do some research on the listener you suggested, thanks!

Jobinesh said...

Daniel,
Please see this link -http://www.oracle.com/technetwork/developer-tools/adf/popupregionpattern-394585.pdf

Anooj said...

Hi Jobinesh,

In my scenario, I am calling the second taskflow as inline popup.

The main issue that I face is to return multiple values from second taskflow to the first taskflow.

Is there a way I can pass and receive multiple values from taskflow.

Jobinesh said...

Anooj
You can return mulitple values out of the box. Another option is wrap them in a an ArrayList and return

Anooj said...
This comment has been removed by the author.
Anooj said...

Hi Jobinesh,

I am able to return multiple parameters using ArrayList.

Can you still update me on how to return multiple values out of the box.

garg said...

If I open 2nd taskflow as a default i.e Run as Dialog=false and Display Type external window then returnListener function never called. Any idea?

Thanks in Advance.