I am actually trying to create a custom composite table component because h:datatable or p:datatable do not fit my needs. Nevertheless it shall be used like a primefaces datatable. After I found JSF composite component childrens and Expose items of a list while iterating within composite component I saw the finish line, but now I got stuck.
My xhtml:
<h:body>
<sm:datatable mode="columntoggle" id="mytable" value="#{managerBean.objects}" var="object">
<sm:column header="KeyHeader" property="key">
<h:outputText value="#{object.key}"/>
</sm:column>
<sm:column header="ValueHeader" property="value">
<h:outputText value="#{object.value}"/>
</sm:column>
</sm:datatable>
</h:body>
And this is the datatable composite:
<cc:interface>
<cc:attribute name="id" />
<cc:attribute name="mode" />
<cc:attribute name="var" />
<cc:attribute name="value" type="java.util.List"/>
</cc:interface>
<cc:implementation>
<table data-role="table" data-mode="#{cc.attrs.mode}" id="my-table">
<thead>
<tr>
<ui:repeat value="#{component.getCompositeComponentParent(component).children}" var="child">
<th>
<h:outputText value="#{child.attrs.header}"/>
</th>
</ui:repeat>
</tr>
</thead>
<tbody>
<ui:repeat value="#{cc.attrs.value}" var="object">
<tr>
<c:forEach items="#{cc.children}" var="child" varStatus="loop">
<cc:insertChildren/>
</c:forEach>
</tr>
</ui:repeat>
</tbody>
</table>
</cc:implementation>
And that's the column composite
<cc:interface>
<cc:attribute name="header" />
<cc:attribute name="property" />
<cc:facet name="content"/>
</cc:interface>
<cc:implementation>
<td><cc:insertChildren/></td>
</cc:implementation>
thead works standalone
tbody works standalone
Putting them together like above I only get tbody. thead always stays empty Any suggestions? Thanks for your help in Advance!
This is not a bug, it actually works as designed in mojarra. Using cc:insertChildren moves the children to the parent tag of the cc:insertChildren tag. This problem is equivalent to another problem and has the same solution. See my answer to this question.
Basically, you put a <ui:fragment>
around the <cc:insertChildren>
, bind that fragment to a property in a FacesComponent bean.
#{cc.children}
which is equivalent to
#{component.getCompositeComponentParent(component).children}
should both work
but for some reason fail to work in some versions , I guess this part of JSF is still little buggy .
Have you tried
#{cc.getFacets().get('javax.faces.component.COMPOSITE_FACET_NAME').children}
Please refer this thread as well,
In JSF2, how to know if composite component has children?
I was having the same issue. My workaround was to use a renderFacet
, instead of insertChildren
.
To iterate over the inserted elements I have used: #{cc.facets.yourFacetName.children}
and to insert the elements themselves I have used: <composite:renderFacet name="yourFacetName"/>
.
I've found iterating over children and using <composite:insertChildren />
in the same component to be near impossible. At least in the Mojarra 2.2.6 implementation.
The intermediate facet approach did not work for me either.
Eventually, my solution was to:
encodeAll()
in the the faces component corresponding to parentThis question is over a year old. Please share if there's a simpler solution in sight.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With