For this blogpost I made an Example with one JSPX page and this page contains two Regions. The first is the Top TF and the second is a dynamic Region with Center 1 & 2 TF. Start is part of the JSPX page and can call the Center 1 & 2 methods directly in the dynamic region bean.
For showing the Center Task Flows from the Top Task Flow you can use the Parent Action activity.
Here is the code of the main JSPX page with in the start facet ,the two buttons which can call the backingbean methods.
<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"> <jsp:directive.page contentType="text/html;charset=UTF-8"/> <f:view> <af:document id="d1" title="Example"> <af:form id="f1"> <af:panelStretchLayout id="psl1" startWidth="239px" topHeight="95px"> <f:facet name="center"> <af:region value="#{bindings.dynamicRegion1.regionModel}" id="centerRegion"/> </f:facet> <f:facet name="start"> <af:panelHeader text="Start" id="ph1" inlineStyle="width:239px; height:423px;"> <f:facet name="toolbar"> <af:toolbar id="t1"> <af:commandToolbarButton text="Center1" id="ctb1" action="#{backingBeanScope.MainRegionHandler.showCenter1TF}"/> <af:commandToolbarButton text="Center2" id="ctb2" action="#{backingBeanScope.MainRegionHandler.showCenter2TF}"/> </af:toolbar> </f:facet> </af:panelHeader> </f:facet> <f:facet name="top"> <af:region value="#{bindings.top1.regionModel}" id="centerTop"/> </f:facet> </af:panelStretchLayout> </af:form> </af:document> </f:view> </jsp:root>The dynamic region bean with the showCenter1TF and showCenter2TF methods.
package nl.whitehorses.adf.tf.view.beans; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import oracle.adf.controller.TaskFlowId; import oracle.adf.view.rich.context.AdfFacesContext; public class MainRegionHandler { private String taskFlowIdCenter1 = "/WEB-INF/center1.xml#center1"; private String taskFlowIdCenter2 = "/WEB-INF/center2.xml#center2"; private String taskFlowId = taskFlowIdCenter1; public MainRegionHandler() { } public TaskFlowId getDynamicTaskFlowId() { return TaskFlowId.parse(taskFlowId); } public String showCenter1TF() { taskFlowId = taskFlowIdCenter1; AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("centerRegion")); return null; } public String showCenter2TF() { taskFlowId = taskFlowIdCenter2; AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("centerRegion")); return null; } private UIComponent getUIComponent(String name) { FacesContext facesCtx = FacesContext.getCurrentInstance(); return facesCtx.getViewRoot().findComponent(name); } }From the Start facet on the main page it is easy to show the right Center Task Flow. From the Top Task Flow you need to do more. First you need to change the parent Task Flow. ( this works in a bounded or unbounded Task Flow ). Add two Method Call activities and a Wildcard Control Flow Rule.
You will later call the goCenter1 and goCenter2 Control Flow cases from the Top Task Flow. This will activate the method call which call the right method in the dynamic region bean. After a successful invocation, it will use the return Control Flow case to return to the page.
The property window of the showCenter1TF Method Call activity looks like this. Here you need to provide the Method value and provide the Fixed Outcome.
Next step is to change the Top Task Flow where you also need to add a Wildcard Control Flow Rule together with two Parent Action activities.
The Parent Action property window looks like this. Here you need to provide the Parent Outcome , this must match with the Control Flow Case of the parent Task Flow and here is the Outcome also return.
And at last the Top fragment with the two buttons which calls the right Control Flow Case.
<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich" xmlns:f="http://java.sun.com/jsf/core"> <af:panelHeader text="Top TF" id="ph1" inlineStyle="width:995px; height:84px;"> <f:facet name="toolbar"> <af:toolbar id="t1"> <af:commandToolbarButton text="Center1" id="ctb1" action="showCenter1TF"/> <af:commandToolbarButton text="Center2" id="ctb2" action="showCenter2TF"/> </af:toolbar> </f:facet> </af:panelHeader> </jsp:root>That's all and here is the example workspace.
Thanks for this mate. I'm bookmarking this site now. This site is awesome and this will help me in my java training.
ReplyDeleteI am using UI shell template. in it i have activity that shows in a tab. i cant call another activity using the launcher method because i get a NullPointerError. It cant see the activity under WEB-INF/Flows. How do i over come this?
ReplyDeleteHi
ReplyDeleteCan you give me more information what you are doing ( in detail )
thanks Edwin
Hello Edwin, I found your post and example workspace very helpful, thank you. I'm also trying to enhance the functionality of your example by nesting a left hand menu inside tabs, but I'm having some hard time trying to get it right. I was wondering if you could help me understand a little bit more on what I could be doing wrong. The desired layout would look something like this:
ReplyDelete----------------------
| Tab 1 | Tab 2
----------------------
| Option 1 | *Content*
| Option 2 |
The way I try to achieve this is by using a region at the top for tabs, which updates a dynamic region used for left hand side menu (which is another region) and another dynamic region for the content of the application. I'm also using different beans, one for the tabs, and one bean for each menu that resides inside the tabs. I have doubts about the task flow architecture I'm using, and would like some guidance on that front.
This comment is getting long and not sure if I'm getting the point across. If you could help me please let me know if I should carry on, or if I should provide an email address so you can contact me in order for me to send you more details. Would be easier to explain with some other way of showing info rather than just plain text, in any case thank you for your time.
Hi,
ReplyDeleteyou can use the dynamic regions for tab to menu and one for the menu to content
you dont need parent action unless you want to switch tab from the menu
make sure that the dynamic regions have sessionscope instead of backingbean scope.
else you in the menu you will reset the screen.
thanks
Hi Edwin,
ReplyDeleteOnce again a very helpful example. It works great for me in JDeveloper (11.1.1.2 and 11.1.1.3) but once I try to deploy it on the weblogic server (10.3) it does not refresh the task flow region anymore. I even tried to deploy it from the console of the embedded WLC but still does not work. Did you notice that also. Any work around.
Thanks
Laurent
Hi,
ReplyDeleteIt should work perfectly.
Did you deploy it from the application menu and the wls needs to have the adf runtime /webcenter or soa suite add on. And at last you need to enable the jrf option in the wls domain.
Hi Edwin,
ReplyDeleteMy WLS server has all the modules you mentioned installed and jrf option enabled.
I tested it on the integrated WLS server that comes with JDev (the same one that startup from within JDeveloper).
I close JDeveloper, I go to a command line window, type C:\JDeveloper\system11.1.1.2.36.55.36\DefaultDomain\bin\startWebLogic.cmd to start the
integrated WLS server. I go to the console window for the integrated server : http://localhost:7101/console and
deploy your application (prior to this in JDeveloper I deployed you app as a .ear file from the application menu).
When I run the page it will not refresh the region when I click on the button the way it does when I start the application from within JDeveloper.
Strange!
I can send you the .ear file that gets created so you can try if you wish.
Thanks a lot.
Laurent
Hi,
ReplyDeleteVery strange, what can be is that your war deployment profile needs to include more ADF jars.
The generated ear/war is not the same when you run it on the embedded wls.
Dont you get any error in the server logs.
hope this helps.
Hi Edwin,
ReplyDeleteI tried to add more jar files etc... but still get the same problem. I check the server and did not get any errors in the log.
In what way the ear/war are differents?
Thanks for your time.
Laurent
Hi,
ReplyDeleteOk send me your project and I will take a look at it.
send it to biemond at gmail dot com
thanks
Hi Edwin,
ReplyDeleteThanks for looking at my project. Everything was fine but as you recommended calling main instead of main.jspx made all the difference. It is working great that way with no changes.
Thanks a lot and I love your blogs.
Laurent
Hi Edwin,
ReplyDeleteYour post is very helpful! I follow your example and almost get what I want to achieve. What I'm trying to do is: I have a parent jsff (in the parentTF). In this jsff, there are two tabs: tab1 and tab2. In tab2, I use a task flow (childTF) as region. I want to click a button in the jsff in the childTF to go back to tab1 and close tab2. I follow your example to have a parent action in the childTF, whose parent outcome points to a method call in the parentTF. In the method call I get the binding of tab1 and tab2, and set their disclosed property. I check that these are properties are successfully set when I click the button in the jsff in the childTF, but I can only see the change to take effect after I refresh the page. Usually we can set the partial trigger to resolve this problem. However that seems doesn't apply to this case, because the tab ui component and the button are in two different jsff. Could you advice how to resolve this problem? Thanks in advance. I appreciate your help!
-Sa
Hi,
ReplyDeleteyou should find all the UIcomponents from a managed bean (main page) and lookup the regions, from there you can lookup the other ui components.
Then with ADFFacesContect fires some ppr. This will work.
Hi Edwin,
ReplyDeleteI am using jdeveloper 11.1.2.0.0
We are using UI shell template. We have an managed bean and we will using
{
TabContext tabContext = TabContext.getCurrentInstance();
try
{
tabContext.setMainContent("/WEB-INF/Taskflowxml#task_flow");
}
catch (TabContext.TabContentAreaDirtyException toe)
{
// TODO: warn user TabContext api needed for this use case.
}
In the template we are having two command link in which we are having action listener and we writing as above. In the first taskflow we are showing one jsff . From there we are navigation to Another region of different task flow.
When i am clicking the one command link in template from second region of another task flow . It is not redirecting to first page.
I debug the code .Control coming in the action listener of that method as above .From there it went to correct jsff and stopped there.Very weird behavior.
Plese suggest how to resolve.
Hi,
DeleteDon't know exactly what your problem is , Do you add the Tabcontext as parameter on the Task Flows.
and can you catch the error, maybe add some logging to this catch.
thanks.