Why is some code evaluated when it is in a tag that is "rendered=false"
Background
With my team, we are working on a pretty big application in JSF where some people have more experience in front-end (JSF) and some in the back-end side (web service client).
One of them got a problem that some JSF was evaluated inside a "rendered=false" tag. That setup is working some other places and didn't see why it was not working here.
The cause
The problem was that, inside the tag that was not supposed to be evaluated, there was an <ui:include>.
The origin of this is that ui:include runs at view build time and redered attribute is evaluated in the render response phase (that is the last phase of the lifecycle). This means that the ui:include is evaluated before rendered attribute.
The (broken) code
<h:panelgroup rendered="#{backingBean.shouldShow}">
<ui:include src="pageA.xhtml"/>
</h:panelgroup>
<h:panelgroup rendered="#{!backingBean.shouldShow}">
<ui:include src="pageB.xhtml"/>
</h:panelgroup>
The solution
There are 2 ways to go around this problem:
1. You could replace the ui:include with the code within the target page. This is probably not the best way as you might duplicate some code or make it more difficult to read.
2. You can use c:if or c:choose instead of the rendered attribute
The (working) code
<c:choose>
<c:when test="#{backingBean.shouldShow}">
<ui:include src="pageA.xhtml"/>
</c:when>
<c:otherwise">
<ui:include src="pageB.xhtml"/>
</c:otherwise>
</c:choose>
For more information
You can contact us at OSnode.