Reputation: 11
I've read many solutions to the above question, but my specific problem has some complications. I have a select tag whose options are filled 1-20 using a JSTL forEach tag, and I want the option that was previously selected to be automatically selected when the user revisits the page. The select tag is within another forEach for the items within a list type attribute, so the select 1-20 is repeated many times on the page.
The page is for selecting items to add to a cart, and the select 1-20 is for the quantity. I want this quantity to stay consistent when the user revisits the page after submitting its form. I've already accomplished something similar where the checkbox for each item stays checked upon revisit, thanks to an answer to another question that suggested stream() using paramValues.
I tried to use a similar approach for the select 1-20, but it did not work. I thought about using javascript, with which I have very little experience, but this is complicated due to my select name, out of necessity, being a unique ID for each item on the page, assigned using EL.
This is the code as is without a way to keep the previously selected quantity, but successfully keeps previously selected items checked:
<c:forEach var="item" items="${items}">
<c:if test="${item.category == 'Burger'}">
<tr>
<td><input type="checkbox" name="itemID" value="${item.itemID}" ${paramValues.itemID.stream().anyMatch(v->v == item.itemID).get() ? 'checked' : ''}></td>
<td>
<select name="${item.itemID}">
<c:forEach var="i" begin="1" end="20">
<option value="${i}">${i}</option>
</c:forEach>
</select>
</td>
<td>${item.name}</td>
<td><fmt:formatNumber value="${item.price}" type="currency"/></td>
</tr>
</c:if>
</c:forEach>
My unsuccessful attempt to use stream() for the select 1-20:
<c:forEach var="i" begin="1" end="20">
<option value="${i}" ${paramValues.item.itemID.stream().anyMatch(v->v == i).get() ? 'selected' : ''}>${i}</option>
</c:forEach>
The above solution was taken from How can I retain HTML form field values in JSP after submitting form to Servlet? where the given example code from an answer:
<select name="boo" multiple>
<option value="a" ${paramValues.boo.stream().anyMatch(v->v == 'a').get() ? 'selected' : ''}>label a</option>
<option value="b" ${paramValues.boo.stream().anyMatch(v->v == 'b').get() ? 'selected' : ''}>label b</option>
<option value="c" ${paramValues.boo.stream().anyMatch(v->v == 'c').get() ? 'selected' : ''}>label c</option>
</select>
didn't even work when I tried shoving it in my code just to test, and it doesn't even have the complication of being with a forEach, etc. I'm not sure why, as the same solution worked for my checkbox, as seen in my first block of code.
Thank you very much for any help.
Upvotes: 1
Views: 1713
Reputation: 1108842
It's because you used a dynamic name for the HTML element:
<select name="${item.itemID}">
and you're using a hardcoded name while inspecting the parameter values:
${paramValues.item.itemID}
This basically looks for the request parameter values with the literal name "item", and then attempts to treat it as a javabean in order to grab the literal property name "itemID". Under the covers, it has the same effect as request.getParameterValues("item").getItemID()
. This is not correct. You need to look for request parameter values with the dynamic name ${item.itemID}
instead. You basically want to end up with the same effect as request.getParameterValues(item.getItemID())
.
${paramValues[item.itemID]}
In other words, this must work for you:
<option value="${i}" ${paramValues[item.itemID].stream().anyMatch(v->v == i).get() ? 'selected' : ''}>${i}</option>
Upvotes: 1