JSTL c:if tag always test false inside JSF facelet ui:repeat tag 

Joined:
08/13/2009
Posts:
164

November 14, 2011 20:50:51    Last update: November 22, 2011 09:06:10
This facelet fragment will never print anything:
<ui:repeat var="person" value="#{myBean.theJTeam}">
	<c:if test="#{person != null}">
	    JSTL: #{person}<br/>
	</c:if>
</ui:repeat>

because the test condition always returns false, even though the person var is not null.

The same happens even when I define another variable with ui:param:
<ui:repeat var="person" value="#{myBean.theJTeam}">
	<ui:param name="aperson" value="#{person}"/>
	<c:if test="#{aperson != null}">
	    JSTL: #{aperson}<br/>
	</c:if>
</ui:repeat>


What's happening? The c:if test condition is evaluated before the ui:repeat tag had a chance to set the value! Both facelet ui tags and JSTL c tags are evaluated at the Render Response phase of the JSF lifecycle. But within the Render Response cycle, there are two sub-phases (so to speak): the first builds the UI element tree, the second renders the UI tree. The JSTL c:if tag is evaluated when the tree is built, but the facelet ui:repeat tag is evaluated when the UI tree is rendered. Bad design indeed. Why should a tag user know the implementation details in order to use the tags correctly?

The solution? Use ui:fragment if you can:
<ui:repeat var="person" value="#{myBean.theJTeam}">
	<ui:fragment rendered="#{person != null}">
	    UI Fragment: #{aperson}<br/>
	</ui:fragment>
</ui:repeat>


Or use c:forEach for the loop instead of ui:repeat.
Share |
| Comment  | Tags