Search code examples
jsfjsf-2lifecyclecomposite-component

JSF 2 Composite Component rendering problem


My composite component (cc) creates an inputText-Field. The important part is, that it is rendered depending on the models property "visible". The model is given to the component via parm "name".

<cc:interface>
  <cc:attribute name="name" required="true"/>
</cc:interface>
<cc:implementation componentType="ch.sbi.pt.components.PMSInputText">
      <h:inputText value="#{cc.attrs.name.value}" rendered="#{cc.attrs.name.visible}"/>
</cc:implementation>

In the view i have a panelGrid with 2 cells/row: the first row has a label and my cc, the second is not important. The label renders itself with the same model-property as my cc does.

<h:panelGrid columns="2">  
   <h:outputText value="Name" rendered="#{person.name.visible}"/>
   <sbic:pmsInputText name="#{person.name}"/> 
   <h:outputText value="Next Label"/>
   <sbic:pmsInputText name="#{something.name}"/>
</h:panelGrid>

The result (and problem) is the following, if "visible"-property returns "false": None of the components are rendered (perfect!) BUT the cc resulting HTML leaves an empty cell (e.g. <td></td>) which results in a ugly layouted HTML-Table (offset one cell):

<table>
<tbody>
<tr>
<td></td>
<td>Next Label</td>
</tr>
....

As far as I understand this has to do with the lifecycle (jstl vs. jsf): my cc renders before the <h:outputText../> but how can i get rid of the empty cell (e.g. <td></td>)? Am i missing something here?

Thanx for your help, experts! Marc


Solution

  • This is fully expected. The composite component is rendered. Only its children are not. You need to move the rendered attribute to the composite component instead.

    <sbic:pmsInputText name="#{person.name}" rendered="#{person.name.visible}" />