Differences between revisions 7 and 8
Revision 7 as of 2009-02-21 16:12:39
Size: 4865
Editor: EdBurns
Comment:
Revision 8 as of 2009-09-20 23:01:42
Size: 4867
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
''update: Composite Components in JSF 2.0'' This feature is well supported in JSF 2.0, please see [http://blogs.sun.com/enterprisetechtips/entry/true_abstraction_composite_ui_components/| Ed Burns blog entry on this topic]. ''update: Composite Components in JSF 2.0'' This feature is well supported in JSF 2.0, please see [[http://blogs.sun.com/enterprisetechtips/entry/true_abstraction_composite_ui_components/||Ed Burns blog entry on this topic]].

Overview

update: Composite Components in JSF 2.0 This feature is well supported in JSF 2.0, please see http://blogs.sun.com/enterprisetechtips/entry/true_abstraction_composite_ui_components/.

There are several ways to create composite components

  1. Programmically create a set of controls as a new component in java code.
  2. Use Tomahawk t:aliasBean and a jsp include to represent your composite control.
  3. Use facelets ui:include and ui:composition to represent your composite control.
  4. Use the Shale/Clay library.

The resulting code for t:aliasBean and ui:include are very similar, and converting from t:aliasBean to ui:include is trivial in most cases. The reverse is also trivial provided only one backing bean parameter is specified.

Programmically

Programmically creating a set of controls as a new component in java code is the hardest, most involved, and most fragile way to do it. Note that you want to do parent.getChildren().add(child) rather than setParent(parent) to attach children.

It's often useful to add an empty h:panelGroup component to your page, bind the panelGroup to your backing bean that's building the component, and create the component as child of the panelGroup.

private UIComponent panelGroup;
public void setPanelGroup(UIComponent panelGroup) { this.panelGroup = panelGroup; }
public UIComponent getPanelGroup() { return this.panelGroup; }

public createComponent() {
    UIOutput label = new UIOutput();
    label.setValue("Username:");

    UIInput username = new UIInput();
    username.setId("username");
    username.setValueBinding("value", ...);

    panelGroup.getChildren().add(label);
    panelGroup.getChildren().add(username);
}

Tomahawk t:aliasBean and a jsp include

Using a t:aliasBean and a jsp include is easy and requires only a dependency on t:aliasBean. There may be some issues with nesting t:aliasBean controls, however.

<t:aliasBean alias="#{localBackingBean}" value="#{thisInstanceBackingBean}">
    <f:subview>
        <jsp:include page="/pages/BooleanRelationshipDataTable.jsp"/>
    </f:subview>
</t:aliasBean>

<!-- /pages/BooleanRelationshipDataTable.jsp -->
<t:dataTable value="#{localBackingBean}" ... >

If you need to pass multiple variables to the included components, use t:aliasBeansScope instead:

<t:aliasBeansScope>
    <t:aliasBean alias="#{localBackingBean}" value="#{thisInstanceBackingBean}"/>
    <t:aliasBean alias="#{aLiteralString}" value="literalValue"/>
    <f:subview>
        <jsp:include page="/pages/BooleanRelationshipDataTable.jsp"/>
    </f:subview>
</t:aliasBeansScope>

Note that the f:subview is recommended but not required. It ensures that any explicit component ids in the included page won't conflict with explicit component ids in the including page (because an f:subview is a NamingContainer). However because JSF lacks support for the equivalent of a filesystem ".." step, a component in a subview can never reference a component in an ancestor naming container by id; components such as t:dataScroller that have a "for" attribute must therefore not be nested within an f:subview. When f:subview is used, it is safe to include the referenced page multiple times from an including page; when omitting the subview, this is only valid when all components in the included page have automatically-assigned ids.

Note also that component binding is not supported via "aliased" names. Therefore the included page cannot include any component with a "binding" attribute.

facelets ui:include and ui:composition

Using a facelets ui:include and ui:composition is also easy and requires a dependency on the facelets library.

<ui:include src="/WEB-INF/siteNav.xhtml">
    <ui:param name="user" value="#{currentUser}"/>
    <ui:param name="page" value="home"/>
</ui:include>

<!-- /WEB-INF/siteNav.xhtml-->
<ui:composition>
    <h:outputText value="#{page}"/>
    <h:outputText value="#{user}"/>
</ui:composition>

Shale Clay

[TBA]

Other examples

Credits

This topic was compiled from posts by

  • Jacob Hookom
  • Mike Kienenberger
  • Craig McClanahan

  • Werner Punz
  • Gary VanMatre

Creating_Composite_Components (last edited 2009-09-20 23:01:42 by localhost)