I am creating a drop down list of all languages. The default language selection for the list will be determined by information added by the user:
<select>
<c:forEach items="${languages}" var="lang">
<c:choose>
<c:when test="${lang}.equals(${pageLang})">
<option value="${lang}" selected>${lang}</option>
</c:when>
<c:otherwise>
<option value="${lang}">${lang}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
.equals doesn't appear to exist in EL. Having had a look here it's suggested I write my own function and then import and use that. As this is a one off tiny thing just for this page I don't want to have to start creating libraries etc just for this. Nor do I want to start creating specialist objects for the servlet to return with this extra info in them.
Only thing I can think to do is to return the actual html for the whole option line from the servlet rather than just the language string, but that strikes me as ugly so I'm hoping there's a more elegant solution.
What is the best plan for a quick fix to comparing two strings in EL?
The J2EE 1.4 Tutorial
In Expression Language you can just use the == or eq operator to compare object values. Behind the scenes they will actually use the Object#equals(). This way is done so, because until with the current EL 2.1 version you cannot invoke methods with other signatures than standard getter (and setter) methods (in the upcoming EL 2.2 it would be possible).
And you need to make sure that the entire expression is placed inside the same ${...} scope. Anything outside that is not interpreted as part of an EL expression.
So the particular line
<c:when test="${lang}.equals(${pageLang})">
should be written as (note that the whole expression is inside the { and })
<c:when test="${lang == pageLang}">
or, equivalently
<c:when test="${lang eq pageLang}">
Both are behind the scenes roughly interpreted as
jspContext.findAttribute("lang").equals(jspContext.findAttribute("pageLang"))
If you want to compare constant String values, then you need to quote it
<c:when test="${lang == 'en'}">
or, equivalently
<c:when test="${lang eq 'en'}">
which is behind the scenes roughly interpreted as
jspContext.findAttribute("lang").equals("en")
Not sure if I get you right, but the simplest way would be something like:
<c:if test="${languageBean.locale == 'en'">
<f:selectItems value="#{customerBean.selectableCommands_limited_en}" />
</c:if>
Just a quick copy and paste from an app of mine...
HTH
Related
Does someone know a alternative to <c:if> for view render time, or even if that is possible. For what I have search until now it doesn't exist, or the alternative would be using the rendered attribute, but for me doesn't really work.
<af:listView value="#{bindings.date.collectionModel}" var="item" id="lv1">
<af:listItem id="li2">
<af:iterator id="i1" value="#{bindings.list.collectionModel}" var="row">
<c:if test="#{item.bindings.attrid.inputValue eq row.attrid}">
<ui:param name="varUI" value="true" />
<c:set var="varC" value="true" />
</c:if>
</af:iterator>
<af:outputText value="#{varUI}" id="otqaswq"/>
<!--<af:outputText value="#{varC}" id="otqawq"/>-->
<af:selectBooleanCheckbox text="Activated" id="sbc2" value="#{varUI}"/>
</af:listItem>
</af:listView>
So in the code above I know that c: they run in different time, view build time and not on the render time.
What I needed was that the af:selectBooleanCheckbox would appear true or false depending if there are values with the same value.
My question is, someone know a alternative way of doing this?
rendered should 100% work, your expression may be incorrect.
Switching to another alternative where you will use exactly the same expression will lead you in the very same place.
You cannot use an <af:iterator> to conditionally set a value using <ui:param> or <c:set>, because they are both tag handlers which are evaluated before <af:iterator>. You might use <c:forEach> instead, but that requires some collection to iterate over. A javax.faces.model.DataModel like #{bindings.list.collectionModel} will most likely not work.
But to be honest, you should implement some Java method which will give you the desired value (true or false) instead of trying to implement this logic in terms of JSF tags.
I have a set of data in array list form that I would like to display each food based on the menu category, but I cannot check with the logical operator eq in ELParser, please help me out of this
<ui:repeat var="menu" value="#{eventBean.menuList}">
<li><ol><h5>#{menu}</h5></ol></li>
<ui:repeat var="food" value="#{eventBean.projectDetail.foodList}">
<li>
<ui:fragment ></ui:fragment>
<ol><h:outputText rendered="#{food.menu eq menu}">#{food.name}</h:outputText></ol>
</li>
</ui:repeat>
</ui:repeat>
the menu can be display but the inner loop are not displaying any food. I had tried #{food.menu eq #{menu}} but will get exception on ELParser
EDIT 1:
I just realized that <h:outputText>#{food.name}</h:outputText> are basically cannot display the value, I must do <h:outputText value="#{food.name}"></h:outputText> in order to display value, my mistake.
Now I am searching for if condition to filter
I had tried JSTL c:if to make condition checking but didn't work out as expected, then I search through stack overflow this link has helped me out by implementing:
<ui:fragment rendered="#{food.menu eq menu}">#{food.name}</ui:fragment>
Depending on how complex your filtering needs to be I would go with basic jsf tags or a custom function
For a couple of options only :
<c:if test="#{condition}">do stuff</c:if>
For a limited number of options :
<c:choose>
<c:when test="#{condition1}">do stuff</c:when>
<c:when test="#{condition2}">do other stuff</c:when>
<c:otherwise>do something else</c:otherwise>
</c:choose>
for N Options look at the sollution here where you could use a custom EL function to do anything that a java function can do:
https://stackoverflow.com/a/7080174/2045820
I am creating a drop down list of all languages. The default language selection for the list will be determined by information added by the user:
<select>
<c:forEach items="${languages}" var="lang">
<c:choose>
<c:when test="${lang}.equals(${pageLang})">
<option value="${lang}" selected>${lang}</option>
</c:when>
<c:otherwise>
<option value="${lang}">${lang}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
.equals doesn't appear to exist in EL. Having had a look here it's suggested I write my own function and then import and use that. As this is a one off tiny thing just for this page I don't want to have to start creating libraries etc just for this. Nor do I want to start creating specialist objects for the servlet to return with this extra info in them.
Only thing I can think to do is to return the actual html for the whole option line from the servlet rather than just the language string, but that strikes me as ugly so I'm hoping there's a more elegant solution.
What is the best plan for a quick fix to comparing two strings in EL?
The J2EE 1.4 Tutorial
In Expression Language you can just use the == or eq operator to compare object values. Behind the scenes they will actually use the Object#equals(). This way is done so, because until with the current EL 2.1 version you cannot invoke methods with other signatures than standard getter (and setter) methods (in the upcoming EL 2.2 it would be possible).
And you need to make sure that the entire expression is placed inside the same ${...} scope. Anything outside that is not interpreted as part of an EL expression.
So the particular line
<c:when test="${lang}.equals(${pageLang})">
should be written as (note that the whole expression is inside the { and })
<c:when test="${lang == pageLang}">
or, equivalently
<c:when test="${lang eq pageLang}">
Both are behind the scenes roughly interpreted as
jspContext.findAttribute("lang").equals(jspContext.findAttribute("pageLang"))
If you want to compare constant String values, then you need to quote it
<c:when test="${lang == 'en'}">
or, equivalently
<c:when test="${lang eq 'en'}">
which is behind the scenes roughly interpreted as
jspContext.findAttribute("lang").equals("en")
Not sure if I get you right, but the simplest way would be something like:
<c:if test="${languageBean.locale == 'en'">
<f:selectItems value="#{customerBean.selectableCommands_limited_en}" />
</c:if>
Just a quick copy and paste from an app of mine...
HTH
I'm trying something (JSF2) like this:
<p>#{projectPageBean.availableMethods}</p>
<c:choose>
<c:when test="${projectPageBean.availableMethods == true}">
<p>Abc</p>
</c:when>
<c:otherwise>
<p>Xyz</p>
</c:otherwise>
</c:choose>
But this doesn't seem to work, although the EL expression in the top paragraph changes from false to true, the next paragraph always shows Xyz?
I also tried to change the test to:
${projectPageBean.availableMethods}
But still the same problem!
First and foremost: JSTL tags runs during view build time, not during view render time.
Your concrete problem suggests that #{projectPageBean} is been set during view render time, such as would happen when definied as <ui:repeat var>, <h:dataTable var>, <p:tabView var>, etc. It's thus null during view build time.
In that case, you should not be using a view build time tag to conditionally render HTML. You should instead use a view render time component to conditionally render HTML. As first choice, use <ui:fragment>:
<p>#{projectPageBean.availableMethods}</p>
<ui:fragment rendered="#{projectPageBean.availableMethods}">
<p>Abc</p>
</ui:fragment>
<ui:fragment rendered="#{not projectPageBean.availableMethods}">
<p>Xyz</p>
</ui:fragment>
By the way, there's in Facelets no need to switch between #{} and ${}. In contrary to JSP, in Facelets the ${} behaves exactly the same as #{}. To avoid potential confusion and maintenance trouble, I recommend to stick to #{} all the time.
See also:
Conditional rendering of non-JSF components (plain vanilla HTML and template text)
This is a follow-up to question Using <c:when> with an enumeration
After following the suggestion from the accepted answer, I encountered another problem. The real image path (my code was example code) is partially generated using a library function to get a themed image path. Please understand that I'm not allowed to disclose real code, so I have to cut lots of pieces when I post here.
The first problem is that h:graphicImage automatically generates an absolute image path for the img tag using the current portlet's path. Example: I need http://myserver/mytheme/portlet/image.gif but if I use <h:graphicsImage value="#{myNs:getThemePath()}image.gif" /> it gets rendered as http://myserver/myportlet/mytheme/portlet/image.gif; instead, using <img src="#{myNs:getThemePath()}image.gif" /> works perfectly.
As specified in the other question, I need to switch between images basing on a condition of an iterating item in an ICEFaces table, AND I also need (for accessibility reasons) to place a correct alt attribute with a localized resource.
Briefly, my code resembles the following (ice:dataTable omitted)
<h:column>
<f:facet name="header">
<ice:outputText value="#{myNs:getLocale('state')}" />
</f:facet>
<img alt="[[TODO]]" src="#{myNs:getThemePath()}#{item.state == 'COMPLETED' ? 'ok' : 'ko'}.gif"
</h:column>
The src part works, but now come the problems.
If I use alt="#myNs:getLocale('prefix.#{item.state = 'COMPLETED' ? 'completed' : 'canceled'}')} I can't nest expressions (it doesn't get evaluated)
If I create two <h:graphicsImage tags for the two cases (no need to use complex expressions in alt) and use the rendered attribute as described in the other question's accepted answer, I don't get the image URL rendered correctly.
I also can't use the <c:when tag because, as explained in the other question, it gets always evaluated to false.
What can I do to meet both requirements? How can I use two <img tags and switch their rendering according to my condition?
Thanks
[add] Fortunately, I got the following exception message on Tomcat logs when combining expression . Can somebody help me learn EL expressions better? I'm totally new to JSF
Caused by: org.apache.el.parser.ParseException: Encountered "#" at line 1, column 32.
Was expecting one of:
<INTEGER_LITERAL> ...
<FLOATING_POINT_LITERAL> ...
<STRING_LITERAL> ...
"true" ...
"false" ...
"null" ...
"(" ...
"!" ...
"not" ...
"empty" ...
"-" ...
<IDENTIFIER> ...
<FUNCTION_CALL> ...
To answer the concrete question of the ability to render plain vanilla HTML conditionally; just wrap them in a JSF component which supports the rendered attribute but does by itself output nothing.
<h:panelGroup rendered="#{item.state == 'COMPLETED'}">
<img src="ok.gif" />
</h:panelGroup>
<h:panelGroup rendered="#{item.state == 'CANCELLED'}">
<img src="ko.gif" />
</h:panelGroup>
You can also use <ui:fragment> instead when you're using Facelets. It has a bit less overhead.
Looks like I solved it by myself in 10 minutes. Let me share how.
A combined expression is feasible, but simply needs no #{} again!!!! What a dumb (did I say I'm a total beginner?)
#{item.state = 'COMPLETED' ? myNs:getLocale('prefix.completed') myNs:getLocale('prefix.canceled')}
works