Here some pics of the example I made. In the mainpage I have two buttons with these buttons I pass a event to the region so it goes to the next pagefragment. When this happens the regionNavigationListener is fired and the new displayed view is passed on the mainpage so I can disable the right button.
The bounded Task Flow I use for this example with two pages and some control flow cases between these two fragments
Here is the mainpage jsf page code with the regionNavigationListener on the af:region component.
<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=windows-1252"/>
<f:view>
<af:document>
<af:form>
<af:panelHeader text="Main page">
<f:facet name="context">
<af:panelGroupLayout layout="horizontal">
<af:outputLabel value="Old view"/>
<af:outputText value="#{Main.oldRegionView}"
id="old"/>
<af:spacer width="50" height="1"/>
<af:outputLabel value="New view"/>
<af:outputText value="#{Main.newRegionView}"
id="new"/>
</af:panelGroupLayout>
</f:facet>
<f:facet name="legend">
<af:toolbar>
<af:commandToolbarButton text="Page1"
id="buttonPage1"
actionListener="#{Main.pageOneActionListener}"
disabled="#{Main.newRegionView eq '/region-task-flow/page1'}"/>
<af:commandToolbarButton text="Page2"
id="buttonPage2"
actionListener="#{Main.pageTwoActionListener}"
disabled="#{Main.newRegionView eq '/region-task-flow/page2'}"/>
</af:toolbar>
</f:facet>
<af:panelBox text="Task Flow Region" showDisclosure="false">
<f:facet name="toolbar"/>
<af:region value="#{bindings.regiontaskflow1.regionModel}"
id="regio1"
binding="#{Main.region}"
regionNavigationListener="#{Main.navigationListener}"/>
</af:panelBox>
</af:panelHeader>
</af:form>
</af:document>
</f:view>
</jsp:root>
and here is backing bean code where I pass a queueActionEventInRegion event so it navigates to the other page fragment.
package nl.whitehorses.tf.region.view.backing;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;
import oracle.adf.view.rich.component.rich.fragment.RichRegion;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.event.RegionNavigationEvent;
public class MainPage {
private RichRegion region;
private String OldRegionView;
private String NewRegionView;
private String outcome;
public MainPage() {
}
public void pageOneActionListener(ActionEvent actionEvent) {
outcome = "to1";
region.queueActionEventInRegion(getMethodExpression("#{Main.getOutcomeExpression}"),
null, null, false, -1, -1,
PhaseId.ANY_PHASE);
}
public void pageTwoActionListener(ActionEvent actionEvent) {
outcome = "to2";
region.queueActionEventInRegion(getMethodExpression("#{Main.getOutcomeExpression}"),
null, null, false, -1, -1,
PhaseId.ANY_PHASE);
}
private MethodExpression getMethodExpression(String name) {
FacesContext facesCtx = FacesContext.getCurrentInstance();
Application app = facesCtx.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesCtx.getELContext();
return elFactory.createMethodExpression(elContext, name, String.class, new Class[] { });
}
public String getOutcomeExpression() {
return outcome;
}
public void navigationListener(RegionNavigationEvent event) {
NewRegionView = event.getNewViewId();
OldRegionView = event.getOldViewId();
AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("old"));
AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("new"));
AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("buttonPage1"));
AdfFacesContext.getCurrentInstance().addPartialTarget(getUIComponent("buttonPage2"));
}
private UIComponent getUIComponent(String name) {
FacesContext facesCtx = FacesContext.getCurrentInstance();
return facesCtx.getViewRoot().findComponent(name);
}
public void setRegion(RichRegion region) {
this.region = region;
}
public RichRegion getRegion() {
return region;
}
public String getOldRegionView() {
return OldRegionView;
}
public String getNewRegionView() {
return NewRegionView;
}
}
Here is the example workspace.
Hi Edwin,
ReplyDeleteI try to use queueActionEventInRegion as you describe and it works!
Then, i try to use queueActionEvent to navigate to a methodCall in my region
(i call "next" in this image :
http://www.cijoint.fr/cj200904/cij1toWBKG.jpg )
The methodCall call "myBeanMethod" located in a Bean (scope : pageFlow) :
public String myBeanMethod() { System.out.println(BindingContext.getCurrent().getCurrentBindingsEntry());
//display null
}
The problem is that i can't access to the binding : BindingContext.getCurrent().getCurrentBindingsEntry(), return null!
When i call this method from a button in my region (so, without using queueActionEvent) : BindingContext.getCurrent().getCurrentBindingsEntry() is not null.
How can i access to the binding of my jsff using queueActionEvent?
Thanks for your help
Clément
Hi,
ReplyDeletemaybe you can do this. get the binding of the mainpage and get the taskflow region in the pagedef.
get the executablesList and the get right JUFormBinding. this is the same as the bindingContainer.
# // main jsf page
# DCBindingContainer dc = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
# // taskflow binding
# DCTaskFlowBinding tf = (DCTaskFlowBinding)dc.findExecutableBinding("dynamicRegion1");
# // pagedef of a page fragment
# JUFormBinding form = (JUFormBinding) tf.findExecutableBinding("regions_employee_regionPageDef");
# // handle to binding container of the region.
# DCBindingContainer dcRegion = form;
thanks Edwin
Hi Edwin,
ReplyDeleteThe solution you gave me works : but, i would like to call a method in the task flow bean, et not a method in the main page.
Your solution : JSP->button->JSPBean->method in JSP call a executable in JSF
What i would like : JSPT->button->QueueAction->Method in JSF call a executable in JSF
The reason is that i would like to reuse the task flow, and the method : not to rewrite the method all the time i reuse the task flow.
Thanks for your works
Hi,
ReplyDeleteI saw your picture. can you make a control flow case between the view and the router and call thisn from the main page
thanks
Hi Edwin,
ReplyDeleteI can call a control flow case to a router from the main page using the queueActionEvent :
http://www.cijoint.fr/cj200905/cij7UByFyl.jpg
It works.But, i don't understand what you are thinking about.
Thanks
Ok , nice.
ReplyDeleteCan you explain this a little further
What i would like : JSPT->button->QueueAction->Method in JSF call a executable in JSF
Hi Edwin,
ReplyDeleteTo be more clear, i made a picture : A picture is worth a thousand words : http://www.cijoint.fr/cj200905/cijw3N69KI.jpg
1.My JSPX call a method on the action button.
2.This method, which is in the bean of my jspx, use queueActionEvent to call a navigation in the region (the task Flow).
3.This navigation go to a methodCall, which call a method in the bean of the taskFlow.
4.This method execute a methodAction in the binding of a JSFF.
5.This method return the next navigation of my taskFlow.
Today, i can't do the point4 :
BindingContext.getCurrent().getCurrentBindingsEntry() return null.
I hope it's more clear.
Thanks for your help
Clément
Ok, Now I know your problem.
ReplyDeleteWhen you start the action with a button in the taskflow is then currentBindingC. not null.
I think that the queueaction does something special.
Do you have a testcase.
Hi Edwin,
ReplyDeleteI've set up something similar to the above (I'm using links instead of buttons in my version), you can see my task flow at http://img222.imageshack.us/my.php?image=layoutx.jpg. I'm having trouble with this line:
MethodExpression me = ef.createMethodExpression(elc, "#{backingBeanScope.backing_index.getOutcomeExpression}", String.class, new Class[] { });
If I click any of my links it changes the region to the 'view' fragment and then doesn't respond to any more link clicks. If I modify the above to:
MethodExpression me = ef.createMethodExpression(elc, outcome, String.class, new Class[] { });
...Then it works as expected (although I can go from the template to view and welcome fragments when I shouldn't be able to should I?) - do you know what might be wrong with the "#{backingBeanScope.backing_index.getOutcomeExpression}" part?
Thanks
Hi
ReplyDeleteCan you change the backingBeanScope to pageFlowScope or Session and then see what happens.
thanks Edwin
Hi Clément,
ReplyDeleteI am now looking at your case and a methodcall in a taskflow does not a bindingcontainer unless you give this methodcall a pagedef. So you can't use BindingContext.getCurrent().getCurrentBindingsEntry() when you don't have pagedef. and the methodcall is running in its own area and in the scope of the fragment so you can't get this bindingcontainer with getCurrentBindingsEntry
use findBindingContainer to lookup the right bindingcontext.
Now I am looking for a solution.
thanks Edwin
Hi Clement.
ReplyDeleteI won't use a java class for the methodcall in TF. First generate an ADF datacontrol on it and drop this in the Task Flow . when your method needs data then add parameters to this method then you can use ${data.xxxPageDef.xxxIterator.currentRow}} to get the data of the page and do your thing.
thanks Edwin
Hi Edwin,
ReplyDeleteI try to use findBindingContainer to lookup the right bindingcontext, and it works :
BindingContext bc = BindingContext.getCurrent();
DCBindingContainer container= bc.findBindingContainer(pIdPageDefInDataBinding);
The second solution (methodCall for a method exposed in dataControl) is good too!
Thanks for your help!
I made a scheme for "taskFlow communications in region" :
http://www.cijoint.fr/cj200905/cijXwDvPdD.jpg
Clément
Edwin,
ReplyDeleteIs there any way I can interact with the bound region to move through the task flow without refreshing the whole JSP parent page? I have a control on the parent page that doesn't like being re-initialised.
Thank-you,
Adam
Hi
ReplyDeleteDo you have a testcase.
thanks