Given this datatable (naturally working):
HEA
The <my:mycolumn>
element must be an instance of UIColumn
as that's the only valid child of a UIData
component during the render response phase. All other UIComponent
types will be ignored, thus not rendered. A composite component is implicitly a UINamingContaner
component, which isn't a UIColumn
and therefore ignored.
A PrimeFaces <p:dataTable>
with a backing component that extends UIColumn
also won't work due to the wrong lifecycle of a composite component. The column has to be created during the view build time, while the composite component's body is created during view render time.
The solution is to create a tag file instead, which means an extra .taglib.xml
file, yet it works flawlessly.
/WEB-INF/tags/column.xhtml
:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich">
<rich:column>
<f:facet name="header">HEADER</f:facet>
<h:outputText value="#{val}" />
</rich:column>
</ui:composition>
/WEB-INF/my.taglib.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>column</tag-name>
<source>tags/column.xhtml</source>
<attribute>
<description>Column value</description>
<name>val</name>
</attribute>
</tag>
</facelet-taglib>
Note: The <attribute>
entries are not mandatory, but are nice for documentation purposes, such as generated docs and IDE autocomplete.
/WEB-INF/web.xml
:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
Usage:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:my="http://example.com/my">
<rich:dataTable value="#{values}" var="value">
<my:column val="#{value}" />
</rich:dataTable>
</ui:composition>
I ran into the same question (primefaces), my compromise: exclude the column tag from the composite
<rich:dataTable var="var" value="#{values}">
<rich:column rendered=#{yesOrNo}">
<my:mycolumn val="#{var}">
.. with child nodes if you want ...
</my:mycolumn>
</rich:column>
</rich:dataTable>