Increment counter with loop - java

This question is related to my previous question :
Jsp iterate trough object list
I want to insert counter that starts from 0 in my for loop, I've tried several combinations so far :
1.
<c:forEach var="tableEntity" items='${requestScope.tables}'>
<c:forEach var="rowEntity" items='${tableEntity.rows}' varStatus="count">
<c:out value="${count}" />
</c:forEach>
</c:forEach>
2.
<c:set var="count" value="0" scope="page" />
<c:forEach var="tableEntity" items='${requestScope.tables}'>
<c:forEach var="rowEntity" items='${tableEntity.rows}'>
<%=count++%>
<c:out value="${count}" />
</c:forEach>
</c:forEach>
Problem with first approach is that outer loop has 3 items and inner loop has 7 items, so for each outer item the count starts from 0. The second one I get compile error. Here is basically what I want :
counter = 0;
outer for loop
inner for loop
counter++;
//cout/echo/print counter value should start from 0
end inner loop
end outer loop
I'm just not totally familiar with the syntax. thank you

Try the following:
<c:set var="count" value="0" scope="page" />
//in your loops
<c:set var="count" value="${count + 1}" scope="page"/>

The varStatus references to LoopTagStatus which has a getIndex() method.
So:
<c:forEach var="tableEntity" items='${requestScope.tables}' varStatus="outer">
<c:forEach var="rowEntity" items='${tableEntity.rows}' varStatus="inner">
<c:out value="${(outer.index * fn:length(tableEntity.rows)) + inner.index}" />
</c:forEach>
</c:forEach>
See also:
Hidden features of JSP/Servlet

You can use varStatus in your c:forEach loop
In your first example you can get the counter to work properly as follows...
<c:forEach var="tableEntity" items='${requestScope.tables}'>
<c:forEach var="rowEntity" items='${tableEntity.rows}' varStatus="count">
my count is ${count.count}
</c:forEach>
</c:forEach>

what led me to this page is that I set within a page then the inside of an included page I did the increment
and here is the problem
so to solve such a problem, simply use scope="request" when you declare the variable or the increment
//when you set the variale add scope="request"
<c:set var="nFilters" value="${0}" scope="request"/>
//the increment, it can be happened inside an included page
<c:set var="nFilters" value="${nFilters + 1}" scope="request" />
hope this saves your time

Related

JSTL how to get dynamic token position

I have something like this:
22-04-19 20:34:00!Color::blue!Manufacturer::Ford!Seats::4!Climatronic::yes
I want to get the name of the category and its value (category::value).
The problem is that these positions (category::value) can shift places. ForTokens is index is not good here as it can be one or 10 different tokens.
<c:if test="${fn:contains(dataset, 'Color')}">
<c:set var="color1" value="${fn:substringAfter(dataset, 'Color::')}" />
<c:set var="color2" value="${fn:substringBefore(color1, '!')}" />
</c:if>
Something like this will also not work as it will print out the same value until the new one will appear (will fill out all null cells). I'm out of ideas.
You can split the initial string and loop over each item to find the category you need:
<c:set var="string1" value="22-04-19 20:34:00!Color::blue!Manufacturer::Ford!Seats::4!Climatronic::yes" />
<c:set var="categories" value = "${fn:split(string1, '!')}" />
<c:forEach var="category" items="${categories}" varStatus="status" >
<c:if test="${status.index != 0}">
<c:set var="decodedCategory" value="${fn:split(category,'::')}" />
Category: <c:out value="${decodedCategory[0]}" />
Value: <c:out value="${decodedCategory[1]}" />
<br />
</c:if>
</c:foreach>

How do I use an object for setting variable in JSP for loop?

I need to loop through the list, but foreach loop is not acceptable as I want to start from the second element.
<c:forEach var="item" items="${items}">
<c:out value="${item.name}"/>
</c:forEach>
I tried to use standard java code in "<% %>" but I cannot come up how to set it up right. My syntax is just wrong, I need something like this
<% for (int i = 1; i < ${items.size()}; i++) { %>
<c:out value="${item.name}"/>
<%} %>
But, obviously, the code above is not working.
You can use JSTL varStatus property. It might help you.
<c:forEach var="item" items="${items}" varStatus="loop">
<c:if test="${loop.index != 0}">
<c:out value="${item.name}"/>
</c:if>
</c:forEach>

Manipulating Hashtable key is not working

I am trying to access a Hashtables value based on its key, which is a number as String in JSTL.
But if I increment/decrement the keys value, it does not work anymore.
I iterate the sorted list of keys in a for loop. I use this item to access Hashtable.
<c:forEach items="${helper:getSortedList(hashtableObj)}" var="lineNumber" varStatus="loop">
<c:if test="${param.lineNbr eq lineNumber}">
<c:if test="${lineNumber>1}">
<fmt:parseNumber var="prevLineNumberKey" type="number" value="${lineNumber-1}" />
<c:out value="PREV ${hashtableObj[prevLineNumberKey]}" escapeXml="false"/><br/>
</c:if>
<c:out value="Current :${lineNumber}" /><br/>
<c:if test="${lineNumber<fn:length(hashtableObj)-1}">
<fmt:parseNumber var="nextLineNumberKey" type="number" value="${lineNumber+1}" />
<c:out value="NEXT ${hashtableObj[nextLineNumberKey+1]}" escapeXml="false"/><br/>
</c:if>
</c:if>
</c:forEach>
The output is
PREV Current :51 NEXT
But what I expected is
PREV 50 Current :51 NEXT 52
Any pointers are appreciated.
If keys in your Map is String than to get an element you must query it with String value. Your current solution queries a Map with Long value.
You can convert number to String and then query a Map like this:
<c:set var="numberAsString">${50 - 1}</c:set>
<c:out value="value: ${hashtableObj[numberAsString]}"/>
Try replacing:
<fmt:parseNumber var="prevLineNumberKey" type="number" value="${lineNumber-1}" />
With:
<c:set var="prevLineNumberKey">${lineNumber-1}</c:set>
And replace:
<fmt:parseNumber var="nextLineNumberKey" type="number" value="${lineNumber+1}" />
<c:out value="NEXT ${hashtableObj[nextLineNumberKey+1]}" escapeXml="false"/><br/>
With:
<c:set var="nextLineNumberKey">${lineNumber+1}</c:set>
<c:out value="NEXT ${hashtableObj[nextLineNumberKey]}" escapeXml="false"/><br/>
Couple of questions though:
1) Is hashtableObj really a hashtable or is it a hashmap?
2) Is the value of the hashtableObj, really a number that is equal to the key? In other words you are expecting:
PREV 50
... that means you are expecting the value of the hashtable/map to be 50 AND the key is also 50?
I found a workaround.
<fmt:parseNumber var="prevLineNumberKey" type="number" value="${lineNumber-1}" />
<c:out value="Previous ${hashtableObj[sortedList[prevLineNumberKey-1]]}" escapeXml="false"/><br/>
I used the list element as a key for Hashtable and it works. Thanks to all answers.

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?

How to use the index variable of a JSTL forEach loop to access a map entry?

With a forEach loop I'd like to create table cells (for a row) whereas each cell contains an input field of a form. The number of table cells is always fixed (12). That is actually no problem. However, here comes the challenge: the forEach should also enter a variable number of default values into the input fields that have to be obtained from a Map(Long, Double).
This is my (simplified) attempt:
<c:forEach var="number" begin="1" end="12" >
<td>
<input type="text" value="${requestScope.aMapWithData[number]}" />
</td>
</c:forEach>
But this doesn't show any value from the Map in the input fields. I guess the problem is that "number" is of type String and not Long. So I wonder if this problem can be solved without using scriptlets.
What number do you want to show? Is it index number of each map entry?
<c:forEach items="${aMapWithData}" var="item" varStatus="status">
<td>
<c:out value="${status.count}."/>
<input type="text" name="${item.key}" value="${item.value}" />
</td>
</c:forEach>
Try this
<c:forEach items="${aMapWithData}" var="mapEntry">
<c:set var="mapKey" value="${mapEntry.key}"></c:set>
<c:set var="mapValue" value="${mapEntry.value}"></c:set>
</c:forEach>

Categories