Child pages
  • Create a non NamingContainer Composite Component

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In theory, a "non explicit" requeriment for a composite component class is it should implement NamingContainer interface. Note I said
"non explicit", because in practice there is nothing on JSF 2.0 spec that enforces that.

...

The previous code works in both MyFaces and Mojarra. This is valid from facelets 1.1.x. The idea is as long as there is no component with
"id" set, the previous code will work. Combinations of c:if and ui:include could be possible, but this work well only on MyFaces 2.0.x
and upper and facelets 1.1.x. In Mojarra 2.0.x some changes were done that makes such cases not work correctly (but in my opinion c:if is
something evil, because it causes a lot of nightmares).

...

Why somebody could want to do this trick? Because NamingContainer has its effects, specially with UIComponent.findComponent. Suppose you
want to create a component that works as a panel. You can imagine something like this:

...

The user wants that the final clientId be "field1", but instead he/she has "generated id:field1", and the worst part is if you need some
call to invokeOnComponent or findComponent, you have to set the id of your composite component and take into account the internals of such
cc to get the component instance.

I found There is an easy solution that works with both MyFaces and Mojarra. The idea is just wrap everything inside cc:implementation with f:subview, which creates a NamingContainer component:

...

Works great, because the internal markup uses the naming container, but the composite component base is not a naming container, so its
children or facets will not be affected. Obviously, if you use cc:insertChildren and cc:insertFacet the components will be relocated
and affected by the NamingContainer.

...