In this post, you can
see how to check a component in the component tree by using the UIComponent.visitTree,
declared as follows:
public
boolean visitTree(VisitContext context,VisitCallback callback)
First we write a class,
named FindByIdVisitCallback,
as below:
public class FindByIdVisitCallback implements
VisitCallback {
private
final String id; //can be null
private
final String clientId; //can be null
public
FindByIdVisitCallback(String clientId, String id) {
this.clientId = clientId;
this.id = id;
}
@Override
public
VisitResult visit(VisitContext context, UIComponent target) {
if
((id == null) && (clientId == null)) {
return VisitResult.REJECT;
}
if
(target.getId().equals(id) ||
target.getClientId(context.getFacesContext()).equals(clientId)) {
return VisitResult.COMPLETE;
}
return
VisitResult.ACCEPT;
}
Now, when we want to use
it we follow two simple steps:
·
create an instance of FindByIdVisitCallback class and pass
the id/clientId of the component to check
·
call the visitTree() method and capture the boolean
result
Note If
the result returned by the visitTree() is false, then the checked
component doesn't exist, and if it returns true, then the component exist in the indicated tree/sub-tree.
This method DOES NOT return an UIComponent
instance, this is why I have avoided the term "find component" and prefer "check component". Can be used just for check if a component
exist or not in the indicated tree/sub-tree. So, you can check by manually typing the id/clientId, or use something like: myComponent.getId()/myComponent.getClientId(). Nevertheless, you can find the component instance by declaring outside the visitTree(), an UIComponent foundComponent;, and, when it is found by the passed id/clientId set it as foundComponent=target.
Examples:
JSF page
snippet
...
<h:body>
<h:graphicImage id="myImageId"
url="http://1.bp.blogspot.com/-
gtjrtr50mMY/VL0IcD0hbrI/AAAAAAAAA-I/8fmOugRBkvU/s1600/omniutil.png"/>
<h:form id="myFormId">
<h:panelGrid
id="panelId">
Some
text
<h:outputText id="myOutputId"
value="..." />
<h:panelGroup id="myDivId"
layout="block">
<h:inputText id="myInputId"
value="..."/>
</h:panelGroup>
<h:commandButton id="myButtonId"
value="Click me!" />
</h:panelGrid>
</h:form>
</h:body>
...
·
search from UIViewRoot the component
with clientId myImageId
FindByIdVisitCallback
findByIdVisitCallback = new FindByIdVisitCallback(null, "myImageId");
//or
FindByIdVisitCallback
findByIdVisitCallback = new FindByIdVisitCallback("myImageId", null);
boolean
result = UIViewRoot.visitTree(VisitContext.createVisitContext(FacesContext), findByIdVisitCallback);
·
search from UIViewRoot the component
with id, myInputId /
clientId, myFormId:myInputId
FindByIdVisitCallback
findByIdVisitCallback = new FindByIdVisitCallback(null, "myInputId");
//or - this
will perform faster
FindByIdVisitCallback
findByIdVisitCallback = new FindByIdVisitCallback("myFormId:myInputId",
null);
boolean
result = UIViewRoot.visitTree(VisitContext.createVisitContext(FacesContext), findByIdVisitCallback);
Note Whenever you can, is better to use clientIds instead of ids, because the search perform faster.
Note The Visit Tree API has the big advantage that inputs in iterating
components (UIData/UIRepeat)
will be consulted on a per-iteration basis (otherwise, are consulted only once).
Niciun comentariu :
Trimiteți un comentariu