How can I loop through each character in a String using JSTL? - java

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

Related

Comparing BigDecimal to 0 in JSTL

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.

How to use jstl el to call a dynamic nested property

if you wanna call the getter method from a specific bean using a dynamic key you use like that:
${bean[getterName]}
but if you wanna call double nested, or triple nested properties with a dynamic name how does it works, is it possible?
${bean.propertyA.propertyB} WORKS
${bean[propertyA.propertyB]} DOES NOT WORKS
<c:set var="dynamicKey" value="propertyA.propertyB" />
${bean[dynamicKey]} DOES NOT WORKS
UPDATE:
For now we're handling like that:
<c:forTokens items="${property}" delims="." var="item">
<c:set var="value" value="${value[item]}" />
</c:forTokens>
Dot notation vs brackets notation with nested properties:
${bean.propertyA.propertyB}
${bean[propertyA.propertyB]} ==> Not right, instead
${bean["propertyA"]["propertyB"]}
Your example with JSTL:
<c:set var="dynamicKey" value="${bean['propertyA']['propertyB']}" />
<c:out value="${dynamicKey}" />
After 2 years we are leaving like this since it does not seems to have a big impact on performance.
<c:forTokens items="${property}" delims="." var="item">
<c:set var="value" value="${value[item]}" />
</c:forTokens>

Combinate JSTL var with Java method

How can I use the Jstl attribute ${theDetail.id} from a Jstl foreach inside a java function? I have tried a lot, but nothing works.
<c:forEach items="<%= facade.getAllDetails() %>" var="theDetail">
// how to use ${theDetail.id} inside this java function
<c:forEach items="<%= facade.getSomeStuffById(...) %>" vars="theStuff">
${theStuf.name}
</c:forEach>
</c:forEach>
Never use scriptlet expressions inside JSP tags. In fact, never use scriptlets at all. The JSP tags are designed to use the JSP EL expressions. Not scriptlet expressions.
The way to write your code is, assuming facade is an attribute of some scope
<c:forEach items="${facade.allDetails}" var="theDetail">
<c:forEach items="${facade.getSomeStuffById('someHardCodedId')}" var="theStuff">
${theStuff.name}
</c:forEach>
</c:forEach>

How to iterate the jstl loop by using integervalues

Hi here I am using jstl to loop over the content I need to convert the number in status1.noOfPages into integer and i want to use this integer in the begin value of next loop.....could anybody plz help me out....
<c:forEach var="status1" items="${list1}">
<c:set var="wins" ><fmt:parseNumber type="number" value="${status1.noOfPages}" /></c:set>
<c:forEach begin="0" end="wins" varStatus="loop">
Index: ${status1.noOfPages}<br/>
</c:forEach>
</c:forEach>
<fmt:parseNumber type="number" value="${status1.noOfPages}" var="beginningIndex"/>
<c:forEach begin="${beginningIndex}" ...
But you shouldn't have to parse anything in a JSP. Why isn't status.noOfPages an int to begin with? Or why don't you parse it in the controller, and provide the parsed value to the JSP?

JSTL c:set not working as expected

I have a JSTL loop where I'm trying to check to see if a given variable is empty or not with a dynamic variable name. When I use c:set with page scope, the variable is not accessible to the if statement. However, when I set it using <% pageCotnext.setAttribute(...); %>, the variable is available.
<%
pageContext.setAttribute("alphaParA", "test");
pageContext.setAttribute("alphaParF", "test");
int i = 0;
%>
<ul class="alphadex_links">
<c:forEach var="i" begin="0" end="25" step="1" varStatus="status">
<c:set var="currentLetter" scope="page">&#${i+65}</c:set>
<c:set var="currentPar" scope="page">alphaPar${currentLetter}</c:set>
<% pageContext.setAttribute("currentPar", "alphaPar" + (char)('A' + i++)); %>
<li>
<c:choose>
<c:when test="${not empty pageScope[currentPar]}">
The test is always fails when I remove the pageContext.setAttribute block, however it succeeds for A and F as it should when the block is in. I'm very confused and can't find help anywhere.
It fails because HTML doesn't run at the moment JSTL runs. You're effectively passing a Java String &#65 to it instead of the desired character A which would be represented as such based on the HTML entity A when the HTML is retrieved and parsed by the webbrowser after Java/JSP/JSTL has done its job. Please note that your HTML entity is missing the closing semicolon, but this isn't the cause of your concrete problem.
As to the concrete functional requirement, sorry, you're out of luck with EL. It doesn't support char. Your best bet is to deal with strings like this:
<c:forEach items="${fn:split('A,B,C,D,E,F,G,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z', ',')}" var="currentLetter">
<c:set var="currentPar" value="alphaPar${currentLetter}" />
${pageScope[currentPar]}
</c:forEach>
If necessary, just autogenerate the letters as String[] in Java end and set it as application attribute.

Categories