This question already has answers here:
c:choose not working in JSF
(2 answers)
Closed 8 years ago.
I'm trying to create a table, where when the "key" is equal to "name", the value is a link to another page otherwise it should print the value as text.I have the following keys: [name, category, schema]. It's an ArrayList
<c:when test='#{(results.keys.get(loopVal.index)).equals("name")}'>
In my table the column "name" should have values as a link. But it doesn't work, as if the c:when returns false. But i checked "results.keys.get(loopVal.index)" and it prints the keys correctly.
I have tried comparing with equals(), with ==, and eq. I also have the correct jstl library xmlns:c="http://java.sun.com/jsp/jstl/core"
I can't find the problem, maybe it has something to do with comparing a list element? or am I overlooking something really obvious?
Here is a larger snippet of my code:
<ui:repeat value="#{results.keys}" var="key" varStatus="loopVal">
<td id="#{results.keys.get(loopVal.index)}_#{instance.getId()}" class="view">
<c:choose>
<c:when test='#{(results.keys.get(loopVal.index)).equals("name")}'>
<h:link value="#{values.get(loopVal.index)}" outcome="search">
<f:param name="type" value="#{values.get(loopVal.index)}" />
</h:link>
</c:when>
<c:otherwise>
#{values.get(loopVal.index)}
</c:otherwise>
</c:choose>
</td>
</ui:repeat>
You should use c:forEach instead of ui:repeat:
<c:forEach items="#{results.keys}" var="key" varStatus="loopVal">
...
</c:forEach>
Have a look at this post by BalusC about the difference between tag handlers (like c:forEach) and normal JSF components (like ui:repeat).
Related
Excuse the basic question, I'm crash-coursing myself on Java/JSTL to fix an issue for a client and have not been able to quickly find the answer to something I'm dealing with....
I have a JSP page which uses the <c:if> tag to compare a variable to the constant value of 0. This is always returning False for me. I.e.
<c:set var="total" value="0" />
<c:forEach items="${parentItem.children}" var="child">
<c:set var="total" value="${total+child.revenue}" />
<c:if test="${total == 0}">
It is zero.
</c:if>
</c:forEach>
From my understanding, I have to explicitly compare like-types, however when attempting to do something like this, I get an error:
<c:if test="${total.compareTo(BigDecimal.ZERO) == 0}">
-
</c:if>
The error is: The function compareTo must be used with a prefix when a default namespace is not specified.
I'm using JSTL 1.2.
This question already has an answer here:
Struts 2 - The usage of %{ } notation
(1 answer)
Closed 6 years ago.
I am running into an interesting problem and I can't really figure out what it is.
I have a a struts iterator that display a textfield. Defined like so:
<s:form action="AddSubmit" method="post" theme="simple">
<s:iterator status="rowStatus" value="otherList">
<div>
<span>Input Value:</span>
<s:textfield theme="simple"
name="valueMap[%{#rowStatus.index} + '-custom'].inputValue"/>
</div>
</s:iterator>
<s:submit value="Save" theme="simple" />
</s:form>
When I submit, the iterator value %{#rowStatus.index} does not evaluate to anything and the value is never set, but when I hardcode a key like 0, it works. Any idea on what is going on?
This should work:
name="%{'valueMap[\\'' + #rowStatus.index + '-custom\\'].inputValue'}"
%{ OGNL expression } is used to force OGNL evaluation of an attribute that would normally be interpreted as a String literal.
I was wondering if there is a way to register default renderer for a particular class in JSP/JSTL.
I am on my page displaying a tabular report where each table row arrives as generic List<Object>. Since I don't know the type of particular item in advance I am outputting the value with <c:out ...>. This does toString() as far as I know.
Now I want to change the format based on the class of the item e.g. change the format of decimal numbers. Of course I can't use <fmt:formatXXX ...> because I don't know the type in advance.
I believe this is possible in JSF. But is there a way how to achieve this in JSP?
My best shot sofar would be to convert the List<Object> to List<String> and applying the formatting in my controller class but this is slightly less elegant than register a renederer IMHO.
JSP has no notion of "renderers", it's not a component based MVC framework. But you could create a custom tag for this.
Alternatively, you can do something like this with plain JSTL, it's possible to figure the class of an EL object by just checking Object#getClass():
<c:choose>
<c:when test="${item['class'].name == 'java.lang.Integer'}">
<fmt:formatNumber value="${item}" type="number" />
</c:when>
<c:when test="${item['class'].name == 'java.math.BigDecimal'}">
<fmt:formatNumber value="${item}" type="currency" />
</c:when>
<c:when test="${item['class'].name == 'java.util.Date'}">
<fmt:formatDate value="${item}" type="date" />
</c:when>
<c:otherwise>
<c:out value="${item}" />
</c:otherwise>
</c:choose>
This question already has answers here:
instanceof check in EL expression language
(7 answers)
Closed 2 years ago.
I'm using JSTL and want to check whether an object is a String or a Collection.
fn:length returns results on both types (stringsize or number of elements in the collection).
<c:if test="${fn:length(item)>1}">
<c:out value="${fn:length(item)} " />
</c:if>
How can I determine which one I've got?
You could look at the class name. For example:
<c:if test="${item.class.simpleName == 'String'}">
<!-- it's a String! -->
</c:if>
item.class lead to errors when using with tomcat 7.
For me this works (although it's dirtier):
${item.link.getClass().simpleName == 'String'}
If you need to distinguish whether something is a Collection or not, you can use iteration to find out if it's a Collection, and set a var. This worked for me:
<c:set var="collection" value="false" />
<c:forEach var="item" items="${yourObjectWhichMayBeCollection}" varStatus="row">
<c:if test="${row.index > 0}">
<c:set var="collection" value="true" />
</c:if>
</c:forEach>
<!--Now you can examine ${collection} & decide e.g. Collection vs. String -->
How can I loop through each character in a String using JSTL?
Tricky use of fn:substring() would do
<c:forEach var="i" begin="0" end="${fn:length(str)}" step="1">
<c:out value="${fn:substring(str, i, i + 1)}" />
</c:forEach>
Late to the party, but EL 2.2 allows for instance method calls (more on that here: https://stackoverflow.com/a/7122669/2047962). This means that you could shorten Jigar Joshi's answer by a few characters:
<c:forEach var="i" begin="0" end="${fn:length(str)}" step="1">
<c:out value="${str.charAt(i)}" />
</c:forEach>
I only suggest this because it is a little more obvious what your code is doing.
i think you can't do that with JSTL's forEach. You need to write your own tag or an EL function. Here is a sample code how you write your custom tags:
http://www.java2s.com/Tutorial/Java/0360__JSP/CustomTagSupport.htm