Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<c:when test> evaluates always false

This is called 3 times, for each row once. (example table has 3 rows)

....
<ui:param name="rowIndex"   value="#{cc.attrs.rowIndex}" />
<ui:param name="rowActive"  value="#{cc.attrs.activeRow}" />
<c:set var="index"          value="#{rowIndex}"  type="java.lang.Long"/>
<c:set var="activeRowIndex" value="#{rowActive}" type="java.lang.Long"/>

<c:choose>
    <c:when test="${index == 2}">
        ACTIVE
    </c:when>
    <c:when test="${index != activeRowIndex}">
       ${index} - ${activeRowIndex} - INACTIVE
    </c:when>
    <c:otherwise>
       NONE
    </c:otherwise>
</c:choose> 
....

Result:

0 - 1 - INACTIVE

1 - 1 - INACTIVE

2 - 1 - INACTIVE

I would have expected:

0 - 1 - INACTIVE

NONE

ACTIVE

I'm quite clueless why the result is so different from what i expected. So i hope you can help me :-)

like image 831
W vd L Avatar asked Nov 11 '13 13:11

W vd L


1 Answers

The variable names used suggests that you're using the composite inside a repeating component, such as <h:dataTable> or <ui:repeat>.

JSTL tags are executed during view build time, that moment when the JSF component tree is built based on XHTML source code. However, the var attribute of a repeating component is only available during view render time, that moment when the HTML output is produced based on JSF component tree.

In effects, at least the #{cc.attrs.rowIndex} is always null when JSTL runs.

When you're dependent on conditions which are only available during view render time, then you should be using the rendered attribute of a JSF component instead of JSTL <c:choose>/<c:if>.

E.g.

<c:set var="active" value="#{cc.attrs.rowIndex == 2}" />
<c:set var="inactive" value="#{not active and cc.attrs.rowIndex != cc.attrs.activeRow}" />
<c:set var="none" value="#{not active and not inactive}" />

<h:outputText value="ACTIVE" rendered="#{active}" />
<h:outputText value="#{index} - #{activeRowIndex} - INACTIVE" rendered="#{inactive}" />
<h:outputText value="NONE" rendered="#{none}" />

Note that this problem doesn't affect the <c:set>. It merely creates a EL variable mapping (an "alias"), it doesn't immediately evaluate the EL expression and store its result somewhere (as long as scope isn't definied). Also note that ${} and #{} behave exactly the same when Facelets is used instead of JSP. As the ${} is basically a heritage of legacy JSP, you should prefer exclusively using #{} to avoid confusion by yourself and your future maintainers.

like image 126
BalusC Avatar answered Oct 04 '22 02:10

BalusC