1

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?

Sean
  • 1,416
  • 19
  • 51

2 Answers2

3

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:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the explanation. I assumed the ´insertChildren´ would happen first and then the render, but clearly not. I had a look at your other posts and your suggestion. I don't think that will work in the scenario I am trying to create. I want to put the outerComponent wrapper in my actual page and then specify the children within that. I don't see any way of "injecting" the children into the outerComponent without using ´insertChildren´ even if those children are defined in a taglib file the end result is still the same. I can post my updated source if that isn't clear. – Sean Dec 14 '12 at 12:28
  • You can use `` to insert children in tag file. – BalusC Dec 14 '12 at 12:29
  • Scratch that - it works perfectly - I ran the wrong source. Thank you very much. – Sean Dec 14 '12 at 12:33
0

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.

grekier
  • 2,322
  • 1
  • 16
  • 23
  • Thanks @grekier I tried both your suggestions without luck. If I move the `` tags out of the inner component and place them directly around the `` in the outer component then it does work, but that is a poor design for what I am trying to achieve and it also creates other issues. – Sean Dec 14 '12 at 09:42
  • I've come up a couple of times in problems like that and the only possibility I found was encapsulating the inner component. The problem is that not all combination works. Did you try to debug Javascript in firebug or something like that? – grekier Dec 14 '12 at 10:08
  • @greker I added the output. As you can see the tab itself is not rendered at all. – Sean Dec 14 '12 at 10:20