<c:when test> evaluates always false
Asked Answered
I

1

5

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 :-)

Irrelevant answered 11/11, 2013 at 13:54 Comment(1)
Why did you initially use [jsp] tag on the question while you're clearly using its successor Facelets? (as indicated by <ui:param> and #{cc.attrs.xxx})Secondbest
S
9

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.

Secondbest answered 11/11, 2013 at 14:11 Comment(2)
This works. Now i'll take some time why and how it works ;-) thanks for the additional information. very helpfull!Irrelevant
You're welcome. This answer may help in getting a better understanding: #3343484Secondbest

© 2022 - 2024 — McMap. All rights reserved.