Custom Facelets-Tag with multiple Child-Components in h:panelGrid
I have written a custom tag extending UIComponentBase
.
UIComponent
) during the encodeBegin
method.
For layouting purposes, I'd like to nest this Child-Components in a h:panelGrid
,
ExampleTag.java
private ExampleTag extends UIComponentBase {
public void encodeBegin(FacesContext context) throws IOException {
getChildren().add(new HtmlLabel());
getChildren().add(new HtmlOutputText();
}
}
ExampleOutput.xhtml
<html>
<h:panelGrid columns="2">
<foo:exampleTag />
<foo:exampleTag />
</h:panelGrid>
</html>
The generated output would have the HtmlLabel
and HtmlOutput
components in the same cell,
h:panelGrid
only controls the layout of its own children (and not the children of its children)- each
<foo:exampleTag />
creates one composite control (with its own children)
If you want to add multiple controls to a h:panelGrid
, use one of the other template mechanisms.
For example, this h:panelGrid
uses a ui:include
:
<h:panelGrid columns="2">
<ui:include src="gridme.xhtml">
<ui:param name="foo" value="Hello,"/>
<ui:param name="bar" value="World!"/>
</ui:include>
<ui:include src="gridme.xhtml">
<ui:param name="foo" value="Hello,"/>
<ui:param name="bar" value="Nurse!"/>
</ui:include>
</h:panelGrid>
The included composition file:
<!-- gridme.xhtml -->
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:outputText value="#{foo}" />
<h:outputText value="#{bar}" />
</ui:composition>
A subset of the view output:
<table>
<tbody>
<tr>
<td>Hello,</td>
<td>World!</td>
</tr>
<tr>
<td>Hello,</td>
<td>Nurse!</td>
</tr>
</tbody>
</table>
Take care with the above implementation - you cannot set IDs explicitly on anything in gridme.xhtml
as there is no composite control and therefore no NamespaceContainer
to ensure children are namespaced uniquely.
A component is not a tag.
public void encodeBegin(FacesContext context) throws IOException {
getChildren().add(new HtmlLabel());
getChildren().add(new HtmlOutputText();
}
This is not an acceptable way to build a composite control. If you do this, new controls will be added to the component every time it is rendered. You should also not do this in the constructor; that would lead to problems too. There is no good way to add child controls within a control; it should be done externally by the view (see above) or a tag.
精彩评论