To set the focus on an UIComponent in a dynamic Region can be hard because this id of the component is not always the same. It depends which Task Flow you open first ( sometimes it is region1:1:input1 or region1:2:input1 ) . And the second problem you have that you need to use some javascript to set the focus.
The solution is to lookup the region UIComponent and try to find the UIComponent from there, get the clientId and use this value.
Here are some screenshot of the possible scenarios.
Set the focus on the Label 2 item, this is in the ADF page.
Same page but now I set the focus on the DepartmentName in the Department Dynamic Region.
New page but with a static Employee Region.
Example page with the af:document and initialFocusId property set on a managed bean
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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="Second" initialFocusId="#{Focus.focus}"> | |
<af:form id="f1"> | |
<af:panelStretchLayout id="psl1"> | |
<f:facet name="center"> | |
<af:region value="#{bindings.employee1.regionModel}" id="r1"/> | |
<!-- id="af_one_column_stretched" --> | |
</f:facet> | |
<f:facet name="top"> | |
<af:toolbar id="t1"> | |
<af:commandToolbarButton text="start Page" id="second" | |
action="start"/> | |
</af:toolbar> | |
</f:facet> | |
</af:panelStretchLayout> | |
</af:form> | |
</af:document> | |
</f:view> | |
</jsp:root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.whitehorses.adf.demo.beans; | |
import javax.el.ELContext; | |
import javax.el.ExpressionFactory; | |
import javax.el.ValueExpression; | |
import javax.faces.component.UIComponent; | |
import javax.faces.context.FacesContext; | |
import oracle.adf.controller.TaskFlowId; | |
import oracle.adf.share.ADFContext; | |
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService; | |
import org.apache.myfaces.trinidad.util.Service; | |
public class Focus { | |
// to make this work the UIComponent must have clientComponent="true" | |
public String getFocus() { | |
FacesContext facesContext = FacesContext.getCurrentInstance(); | |
String clientId = null; | |
// only for the secondPage, this page contains no dynamic regions | |
if ("/secondView".equals(facesContext.getViewRoot().getViewId())){ | |
clientId = "r1:0:it3"; | |
} | |
// only for the startPage | |
if ("/startView".equals(facesContext.getViewRoot().getViewId())){ | |
// what is the current Task Flow | |
TaskFlowId taskFlow = | |
(TaskFlowId)this.getExpression("DynamicRegion.dynamicTaskFlowId"); | |
// in the region we need to find the component | |
UIComponent region = facesContext.getViewRoot().findComponent("r1"); | |
UIComponent focus = null; | |
// department TF | |
if ( "/WEB-INF/department.xml#department".equals(taskFlow.getFullyQualifiedName()) ){ | |
// find the Focus UIComponent in the department TF | |
// and get its clientId | |
focus = region.findComponent("it1"); | |
// employee TF | |
} else if ( "/WEB-INF/employee.xml#employee".equals(taskFlow.getFullyQualifiedName())) { | |
// find the Focus UIComponent in the employee TF | |
// and get its clientId | |
focus = region.findComponent("it3"); | |
} | |
if ( focus != null ) { | |
// found so use javascript to set the focus | |
clientId = focus.getClientId(facesContext); | |
ExtendedRenderKitService service = | |
Service.getRenderKitService(facesContext, | |
ExtendedRenderKitService.class); | |
service.addScript(facesContext, | |
" var b = AdfPage.PAGE.findComponent('"+clientId+"'); b.focus();" | |
); | |
} else { | |
// nothing found then set the startPage focus | |
clientId = null; | |
} | |
// nothing found then set the startPage focus, this | |
// can be handled without javascript | |
if ( clientId == null ) | |
clientId = "it2"; | |
System.out.println(new java.util.Date()+" focus on "+clientId); | |
} | |
return clientId; | |
} | |
private Object getExpression(String param) { | |
ADFContext adfCtx = ADFContext.getCurrent(); | |
ELContext elContext2 = adfCtx.getELContext(); | |
ExpressionFactory elFactory2 = adfCtx.getExpressionFactory(); | |
ValueExpression valueExp2 = | |
elFactory2.createValueExpression(elContext2, | |
"#{"+param+"}",Object.class); | |
return valueExp2.getValue(elContext2); | |
} | |
} |
Hi Biemond this post was very useful, it works for region with multiple pagefragments also.
ReplyDeleteWe have an issue, If an pagefragment is partially submited by a LOV, the focus goes to the first field in the page controlled by initialfocusid. How could we avoid the change of focus during partialsubmit.
with Thanks,
Raaj
Thanks Edwin for the nice article.But if a component present inside the af:iterator then i don't see the clientId.Is there any other way to get the clientId if the component present inside the af:iterator.
ReplyDeleteThanks,
Naga
Thanks Edwin for the nice article.But if a component present inside the af:iterator then i don't see the clientId.Is there any other way to get the clientId if the component present inside the af:iterator.
ReplyDeleteThanks,
Naga