Specify conditional rendering of element inside ? The does not seem to work

Not with JSTL tags, no. They run during view build time, not during view render time. You can visualize it as follows: when JSF builds the view, JSTL tags run from top to bottom first and the result is a pure JSF component tree. Then when JSF renders the view, JSF components run from top to bottom and the result is a bunch of HTML. So, JSTL and JSF don’t run in sync as you’d expect from the coding. At the moment your <c:if> JSTL tag tag runs, the #{topicId} variable which is set by <ui:repeat> JSF component isn’t available in the scope.

Instead of using <c:if>, you need to specify the condition in the rendered attribute of the JSF component of interest. As you’ve actually none, you could wrap it in a <ui:fragment>.

<ul>      
    <ui:repeat value="#{topics.list}" var="topicId" >
        <li>#{topicId}</li>
        <ui:fragment rendered="#{topicId eq -1}"><br/></ui:fragment>
    </ui:repeat>
</ul>

Alternatives are <h:panelGroup>

<h:panelGroup rendered="#{topicId eq -1}"><br/></h:panelGroup>

or in your specific case <h:outputText escape="false">

<h:outputText value="&lt;br/&gt;" escape="false" rendered="#{topicId eq -1}" />

as both also emits nothing else to the HTML output when no client side attributes are specified.

See also:


Unrelated to the concrete problem, that’s the wrong place for a <br/>. It would be ignored by any webbrowser respecting the HTML specification. Don’t you mean it to be inside the <li>? Or better, give it a class and let CSS give it a margin-bottom.

Leave a Comment