How to compare a string with JSTL? [duplicate] - string

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

JSF EL expression equals always false [duplicate]

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

Alternative c:if in JSF

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.

JSF logical operator in nested ui:repeat

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

h:outputText need style for particular text

I'm using Primefaces 5.1. In my student I need style particular style in particular text.Below code I try It will show error(The value of attribute "value" must not contain the '<' character). So I replace < to &< and &&gt for > that time I faces error(The entity name must immediately follow the '&' in the entity reference)
<p:outputPanel>
<h:outputText styleClass="noWrap" escape="false"
value="#{common.ConfirmMessage1} <b style='color:red'>'
#{student.numberOfUserFound}'</b>"/>
</p:outputPanel>
My doubt is separate text is solution or any other way?
Just don't use <h:outputText>. It has no technical necessity in this specific case.
<p:outputPanel>
<span class="noWrap">
#{common.ConfirmMessage1}
<b style='color:red'>'#{student.numberOfUserFound}'</b>
</span>
</p:outputPanel>
See also:
Is it suggested to use h:outputText for everything?
That being said, I suggest to take a step back from JSF and start learning some basic HTML first. JSF will then be easier to understand. In the context of this question, JSF is just a HTML code generator.

JSF switching image

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

Resources