开发者

Custom Facelets-Tag with multiple Child-Components in h:panelGrid

开发者 https://www.devze.com 2023-03-05 02:13 出处:网络
I have written a custom tag extending UIComponentBase. It adds multiple Child-Components (UIComponent) during the encodeBegin method.

I have written a custom tag extending UIComponentBase.

It adds multiple Child-Components (UIComponent) during the encodeBegin method.

For layouting purposes, I'd like to nest this Child-Components in a h:panelGrid,

but the tag gets in the way her开发者_运维技巧e.

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,

but I'd like to have them in one row, i.e. two cells.


  1. h:panelGrid only controls the layout of its own children (and not the children of its children)
  2. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号