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.