Manipulating Hashtable key is not working - java

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.

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 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?

JSP form select bind with map

I am trying to bind a map element to choosen value from JSP. Elements of select are comming from different map, but keySets are same in both maps.
Part of java code :
private Map<String, List<String>> customCriteriaMap = new HashMap<>();
private Map<String, String> activeCustomCriteria = new HashMap<>();
So for example:
customCriteriaMap have 1 entry:
key: International, value: list contains: true, false
activeCriteriaMap have alsoe 1 entry:
kry: International, value: true
Now after choosing false on select and submiting form i would like to have entry in activeCriteriaMap:
key: International, value: false
Jsp code:
<div class="grid_6 two">
<c:forEach items="${settingsForm.customCriteria}" var="actualCriteriaValues">
<c:set var="actualCriteriaKey" value="${actualCriteriaValues.key}" />
<c:set var="activeCriteria" value="${settingsForm.activeCustomCriteria[actualCriteriaKey]}"/>
<label>Criteria:</label>
<form:select path="activeCustomCriteria[${actualCriteriaKey}]" >
<c:forEach items="${actualCriteriaValues.value}" var="actualCriteriaValue">
<c:set var="optionLabel" value="${actualCriteriaValue}"/>
<c:choose>
<c:when test="${optionLabel eq 'N'}">
<c:set var="optionLabel" value="False"/>
</c:when>
<c:when test="${optionLabel eq 'Y'}">
<c:set var="optionLabel" value="True"/>
</c:when>
</c:choose>
<form:option value="${actualCriteriaValue}" label="${optionLabel}"/>
</c:forEach>
</form:select>
</c:forEach>
</div>
Values in activeCustomCriteria do not change after selecting different value from select and submit. It is always same - default value.
Thanks in advance,
Marek.
Ok,
This peace of code works just fine, problem was in one of Interceptors. Still this code may be trated as example how to use one map to fill select nad other one to bind :)

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>

How to write <c:if> - jstl tag - comparing map key with struts formbean element

I need to retrieve list values from a map of type Map<String,List<HashMap<String, Object>>> in JSP based on a condition. The condition is to compare map key with formbean variable. Rightnow, I am doing multi level iterations. Firstly, I am iterating the map to retrieve key and an inner iterate loop to retrieve list values.
So far, I have like this
<c:forEach items="${addRatingExceptionForm.ratingsMap}" var="entry">
<c:set var="key" value="${entry.key}"/>
<jsp:useBean id="key" type="java.lang.String" />
<c:if test= '<%= key.equalsIgnoreCase(addRatingExceptionForm.getRatingElementDropdown()) %> ' >
<c:forEach items="${entry.value}" var="item">
<li>
<input type="checkbox" id="addRatingException_timeline_earlyAsn" value="${item.RatingInstanceValue}" class="ajaxContentTrigger method_Load_exceptionType ajaxLoadingTrigger|addRatingException_exceptionType clearErrors"/>
<label for="addRatingException_timeline_earlyAsn">${item.RatingInstanceValue}</p></label>
</li>
</c:forEach>
</c:if>
</c:forEach>
But it errors on the <c:if> tag.
You don't need to iterate over the map to compare keys. You just have to use the brace notation [] to get a map value by a dynamic key like so ${map[key]}.
So, this should do:
<c:forEach items="${addRatingExceptionForm.ratingsMap[addRatingExceptionForm.ratingElementDropdown]}" var="item">
<li>
<input type="checkbox" id="addRatingException_timeline_earlyAsn" value="${item.RatingInstanceValue}" class="ajaxContentTrigger method_Load_exceptionType ajaxLoadingTrigger|addRatingException_exceptionType clearErrors" />
<label for="addRatingException_timeline_earlyAsn">${item.RatingInstanceValue}</p></label> <!-- wtf is that </p> doing there? -->
</li>
</c:forEach>

Categories