JSP form select bind with map - java

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 :)

Related

Accesssing model attribute in JPA doesn't work

I am having problems accessing a model attribute in my controller, using Spring.
When adding to the model, I write the status code as a key and the enumeration name as a value. The status code is e.g. AVAILABLE, NOTAVAILABLE, etc.:
String code = status.getCode();
String enumerationName = enumerationService.getEnumerationName(status, currentLocale);
model.addAttribute(code, enumerationName);
On my JPA page, I am trying to access the corresponding value using the key (status code, e.g. AVAILABLE):
<div data-availability>
<c:forEach items="${StockLevelDeliveryStatus.values()}" var="status">
<c:set var="textStyle" value="text-success" />
<c:if test="${status.code.toLowerCase() == 'notavailable'}">
<c:set var="textStyle" value="" />
</c:if>
<div class="d-none display-22 pb-2 ${textStyle}" data-availability-item data-${status.code.toLowerCase()}>
${status}
</div>
</c:forEach>
</div>
For example, the value of status is AVAILABLE and this is what is output in ${status}. However, I want the value AVAILABLE to be used as a key to return me the correct value that I set in the model above. If I change the ${status} statement to, say, ${AVAILABLE} instead, which is the concrete key, the appropriate value from the model is returned:
<div class="d-none display-22 pb-2 ${textStyle}" data-availability-item data-${status.code.toLowerCase()}>
${AVAILABLE}
</div>
If I understand it correctly, then instead of passing the enum value as a key, I need to somehow teach Spring to search in the model for the appropriate key.
As recommended in one of the replies, I also tried writing the Map<StockLevelDeliveryStatus, String> directly into the model:
Map<StockLevelDeliveryStatus, String> statusMap = new HashMap<StockLevelDeliveryStatus, String>();
for (StockLevelDeliveryStatus status : StockLevelDeliveryStatus.values()) {
statusMap.put(status, enumerationService.getEnumerationName(status, currentLocale));
}
model.addAttribute("statusMap", statusMap);
And the JSP accordingly:
<div data-availability>
<c:forEach items="${StockLevelDeliveryStatus.values()}" var="status">
<c:set var="textStyle" value="text-success" />
<c:if test="${status.code.toLowerCase() == 'notavailable'}">
<c:set var="textStyle" value="" />
</c:if>
<div class="d-none display-22 pb-2 ${textStyle}" data-availability-item data-${status.code.toLowerCase()}>
${statusMap[status]}
</div>
</c:forEach>
</div>
Here it already fails when accessing the model, because with this approach I do not get any output on the JSP.
Does anyone have any ideas on how to make this work?
Why not simply put a Map<StockLevelDeliveryStatus, String> into the model? You could then simply use ${statusMap[status]}.

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.

Set value of bean attribute on Drop Down selection: Spring

I am using JSTL to populate drop down items, where country is an item having { id, name, code } attributes.
My need is to get name and code for selected country.
for example:
Country{c_id, c_name, c_code} is structure of country bean. when user selects this item I need to retrieve two values c_name, c_code.
What I did yet:
As I know, only one value can be assigned to itemValue either c_name or c_code.
I tried to populate all country and match selected country and then set to another path variable, but this also not working.
My code is as
<form:select path="selectedCountry" id="ddlCountryId">
<c:forEach items="${countries}" var="country">
<option value="${country.countryName}" ${country.countryName == selectedCountry ? 'selected' : ''}>${country.countryName}</option>
</c:forEach>
</form:select>
<input class="login_submit" type="submit" value="Login" id="btnSubmitId">
<!-- Read country code of selected country -->
<c:forEach var="country" items="${countries}">
<c:out value="country"></c:out>
<c:choose>
<c:when test="${country.countryName==loginCreadetials.selectedCountry}">
<input name="countryCode" type="hidden" value="${country.countryCode}"/>
</c:when>
</c:choose>
</c:forEach>
How can I do this?
Set the value of your option tag to a String that you can easily parse, for instance
value="${country.countryName}:${country.countryName}"
In your controller, you can then split the string on the ':' character to retrieve your two values.

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