1
votes

I'm trying to create a nested JSF composite control wrapped in a Primefaces Accordion control. However when the tab components are placed within the nested component they are not rendered at all.

outerComponent.xhtml

<composite:interface/>
<composite:implementation>
    <p:accordionPanel>
        <composite:insertChildren/>
    </p:accordionPanel>
</composite:implementation>

innerComponent.xhtml

<composite:interface>
    <composite:attribute name="title" type="java.lang.String"/>
</composite:interface>
<composite:implementation>
    <p:tab id="#{cc.attrs.title}" title="#{cc.attrs.title}">
        Some content
    </p:tab>
</composite:implementation>

testPage.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:w="http://java.sun.com/jsf/composite/wizard"
     xmlns:p="http://primefaces.org/ui">

   <h:head>

   </h:head>
   <h:body>

      <w:outerComponent>
         <w:innerComponent title="tab1"/>
      </w:outerComponent>

   </h:body>
</html>

HTML output:

<html xmlns="http://www.w3.org/1999/xhtml"><head><link type="text/css" 
rel="stylesheet" href="/iip/javax.faces.resource/theme.css.xhtml?ln=primefaces-
aristo-custom" /><link type="text/css" rel="stylesheet" href="/iip/
javax.faces.resource/primefaces.css.xhtml?ln=primefaces" /><script type="text/
javascript" src="/iip/javax.faces.resource/jquery/jquery.js.xhtml?
ln=primefaces"></script><script type="text/javascript" src="/iip/
javax.faces.resource/primefaces.js.xhtml?ln=primefaces"></script></head>

<body>

<div id="j_idt7:j_idt10" class="ui-accordion ui-widget ui-helper-reset ui-hidden-
container" role="tablist"><input type="hidden" id="j_idt7:j_idt10_active" 
name="j_idt7:j_idt10_active" value="0" /></div>

<script id="j_idt7:j_idt10_s" type="text/
javascript">PrimeFaces.cw('AccordionPanel','widget_j_idt7_j_idt10',
{id:'j_idt7:j_idt10'});</script>

</body</html>

When it runs there are no errors and while the Accordion divs are rendered, the tabs are not. However if I move the <p:tab> tags into the outerComponent.xhtml file then they are rendered correctly, but that is not what I require.

Any suggestions?

2

2 Answers

3
votes

Iterating components like <p:dataTable>, <p:tabView>, <p:accordionPanel>, etc cannot have composites as direct children. They should have fullworthy <p:column> or <p:tab> components as direct children. While iterating during view render time, they loop over children and do an instanceof UIColumn or instanceof Tab check on them before rendering. If it fails (the composite is NamingContainer), then it would be plain ignored. This is "by design".

Your best bet is using a tag file instead of a composite component as child of an iterating component.

Note that this isn't specfic to PrimeFaces. Standard <h:dataTable> has exactly the same problem.

See also:

0
votes

Did you try to do this without composite - I mean put it all together in the testPage.xhtml. I haven't tried this specific combination but I've had problems with both tab and accordion in combination with other components. To check if the problem lies in the composite or in the combination of components.

It seems that there are some javascript that is "not compatible" with one another.

If you still have the problem, you could try to encapsulate the tab. I tried different combinations and it seems that some are working depending on which components are causing the problem. I'd try with a <div id="tabContainer"> around the tab first and eventually go to p:panel if it doesn't work.