I have three values and I want one component to be rendered in the case of first two values and another component for the third value
Below, I have my page :
<ui:repeat value=#{bean.value} var="data">
<c:choose>
<c:when test="#{data.thirdValue == 'content'}">
<h:outputText value="Wrong value"/>
</c:when>
<c:otherwise>
Correct!
</c:otherwise>
</c:choose>
</ui:repeat>
This is how my page is defined. I have also added the following namespace : xmlns:c="http://java.sun.com/jsp/jstl/core
.
I tested whether, the value defined inside test for <c:when>
returns "true" or "false" and it does.
My problem is that the <c:when>
is never evaluated. The <c:otherwise>
value is always rendered. Am I missing something? Is it because of the the conditional rendering being inside <ui:repeat>
that the when is not evaluated?
Any help will be most appreciated. Thanks in advance
You need to remove the c:choose, because as @Jens stated on the comments, they are processed in different phases. You can use JSTL in tandem with JSF, but have to respect the order they are resolved. read the fine answers by BalusC, he rocks.
As for your needs, you can use the rendered attribute, to conditionally output your text:
<ui:repeat value="#{bean.value}" var="data">
<h:outputText rendered="#{data.thirdValue == 'content'}" value="Wrong value"/>
<h:outputText rendered="#{data.thirdValue != 'content'}" value="Correct!"/>
</ui:repeat>
Just to add to Mindwin's answer, you need to understand that <c:choose>
is a tag handler, when <ui:repeat>
is a UI component. The former is evaluated while component tree is being built, and the latter - while the view is being rendered, i.e. at a later time. In this light, depenence upon var
of <ui:repeat>
is what is wrong with your code, as it hasn't been evaluated when <c:choose>
comes into play.
There are two things to be remembered here.
Use an iterative tag handler, <c:forEach>
, with your contents:
<c:forEach items=#{bean.values} var="data">
<c:choose>
<c:when test="#{data.thirdValue == 'content'}">
<h:outputText value="Wrong value"/>
</c:when>
<c:otherwise>
Correct!
</c:otherwise>
</c:choose>
</c:forEach>
With this approach both tags run at the same time (view is being built), so the conflicts won't occur. Just remember that in case your bean is view scoped it will be recreated upon every request.
Use UI component with rendered
attribute:
<ui:repeat value=#{bean.values} var="data">
<h:outputText rendered="#{data.thirdValue == 'content'}" value="Wrong value"/>
<ui:fragment rendered="#{data.thirdValue != 'content'}">
<h1>Correct</h1>
</ui:fragment>
</ui:repeat>
In this case everything runs as well at the same time (view is being rendered). Note that you can render a whole bunch of HTML with, for example, <ui:fragment>
, as well as some certain JSF tags like <h:outputText>
, by using a rendered
attribute.
Ultimately, go ahead with the classic post: JSTL in JSF2 Facelets… makes sense?, to get a full understanding of relationship between tag handlers and UI components.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With