I am building a custom UIComponent
and adding elements (and other stock UIComponents) inside it. The component renders ok, however it cannot be found from the ViewRoot
.
Let's say I have:
ResponseWriter writer;
@Override
public void encodeBegin(FacesContext context) throws IOException {
writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeText("testing", null);
writer.writeAttribute("id", getClientId(context) + ":testDiv", null);
}
@Override
public void encodeEnd(FacesContext context) throws IOException {
writer.endElement("div");
}
Adding that as:
<x:myUiComponent id="myComponent" />
This renders ok, however I cannot find the component or it's child div from the ViewRoot:
context.getViewRoot().findComponent("myComponent"); // returns null
context.getViewRoot().findComponent("myComponent:testDiv"); // returns null
findComponent("myComponent:testDiv"); // called within the custom component, throws java.lang.IllegalArgumentException?
The same problem applies when I try to add other UIComponents as my custom component's children - they render succesfully, however cannot be found from the component tree as my custom component itself doesn't reside there.
What's the trick here to get the components into the component tree?
Edit: Adjusted the title to better reflect the question.
I am not sure that getClientId(context)
will return myComponent
. Indeed, if your component is nested in a NamingContainer
component, such as a <h:form>
, his ID will be prefixed with the ID of this container.
For example, if you have the following XHTML page:
<h:form id="myForm">
<x:myUiComponent id="myComponent" />
then you will have to retrieve your component using:
context.getViewRoot().findComponent("myForm:myComponent");
Regarding the context.getViewRoot().findComponent("myComponent:testDiv");
(or context.getViewRoot().findComponent("myForm:myComponent:testDiv");
, it will return null
because there is no such element in the JSF components tree on server side. The code:
writer.writeAttribute("id", getClientId(context) + ":testDiv", null);
will only set the ID
attribute on the HTML generated component, ie you will have a <div id="myForm:myComponent:testDiv">
in your HTML page sent to the browser. This <div>
component has no existence in your JSF component tree and thus cannot be retrieved on the Java side.