tags:

views:

251

answers:

1

I'm trying to put an outputLink inside a dataTable when the state is finished.

    <h:dataTable value="#{bean.items}" var="item" width="80%" >
    <h:column>
            <f:facet name="header">
                <h:outputText value="State" />
            </f:facet>

            <c:if test="#{item.state!= 'Finish'}">
                <h:outputText value="Missing value" />
            </c:if>
            <c:if test="#{item.state== 'Finish'}">
                <h:outputLink value="myLink">
                  <h:outputText value="Value = #{item.state}" />
                </h:outputLink>
            </c:if>
        </h:column>
    </h:dataTable>

But this does not work, why is that and how can I fix it?

+4  A: 

JSTL tags are evaluated during building of the view, not during rendering of the view. You can visualize it as follows: Whenever a view tree get created for the first time, all JSTL tags are executed and the result is a view with only JSF tags. Whenever a view tree get rendered, all JSF tags get executed and the result is HTML. So: JSF+JSTL doesn't run in sync as you'd expect from the coding. JSTL runs from top to bottom first, hands the result to JSF and then it's JSF's turn to run from top to bottom again. This may lead to unexpected results in JSF iterating components like UIData because the row data (in this case #{item}) isn't available while JSTL runs.

In a nut: Use JSTL to control flow of JSF result. Use JSF to control flow of HTML result.

You want to use the rendered attribute here.

<h:outputText value="Missing value" rendered="#{item.state != 'Finish'}" />
<h:outputLink value="myLink" rendered="#{item.state == 'Finish'}">
    <h:outputText value="Value = #{item.state}" />
</h:outputLink>
BalusC