Search code examples
jsfconditional-rendering

Value expressions still evaluated despite ui:fragment rendered="false"


I have bean:

class Property{
 private String type;
 private Date value;
 //getters and setters
}

also have block of code on page:

<ui:fragment rendered="#{property.type eq 'checkbox'}">
    <ui:include src="checkbox.xhtml">
        <ui:param name="property" value="#{property}"/>
    </ui:include>
</ui:fragment>

checkbox.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <body>
        <ui:composition>
            <h:selectBooleanCheckbox value="#{property.value}"/>
        </ui:composition>
    </body>
</html>

The condition #{property.type eq 'checkbox'} = false

But I get next exception:

javax.servlet.ServletException: checkBox.xhtml value="#{property.value}": Cannot convert 01.11.02 0:00 of type class java.util.Date to class java.lang.Boolean

I expect if the attribute rendered=false in ui:include, then this block will not be processed.


Solution

  • <ui:fragment rendered> prevents it from rendering the HTML output, but it doesn't prevent it from ending up in JSF component tree and being eligible for state saving.

    Use <c:if test> instead. It runs during view build time instead of view render time and thus the whole bunch won't end up in JSF component tree at all.

    Or, if you have this all inside an <ui:repeat var="property">, and you are using Mojarra, then upgrade to at least 2.1.29 or 2.2.7 wherein this state saving bug was fixed.

    See also: