I have a form with sequentially named fields (field1, field2, etc) that I need to output in the same order for computation purposes. JSTL doesn’t seem to sort in alphabetic order by default. Is there a way to do so?
Here is the code:
<c:if test="${param.submitted}">
<c:set var="hits" value="1" />
<c:set var="damage" value="0" />
<table border="1">
<tr>
<th>Attack</th>
<th>Damage (Orig)</th>
<th>Damage (Scaled)</th>
<th>Total</th>
</tr>
<!-- Loop through form fields -->
<c:forEach var="information" items="${paramValues}" varStatus="field">
<!-- Loop through fields' values -->
<tr>
<c:forEach var="currentField" items="${information.value}">
<c:if test="${!empty currentField}">
<c:if test="${fn:contains(currentField, '|')}">
<c:set var="currentAttack" value="${fn:substringAfter(currentField, '|')}" />
<td><c:out value="${hits}" />: <c:out value="${fn:substringBefore(currentField, '|')}" /></td>
<td><c:out value="${fn:substringAfter(currentField, '|')}" /></td>
<td>
<c:choose>
<c:when test="${hits < 3}">
<c:out value="${currentAttack}" />
<c:set var="damage" value="${damage + currentAttack}" />
</c:when>
<c:when test="${hits == 3}">
<c:out value="${currentAttack * 0.8}" />
<c:set var="damage" value="${damage + (currentAttack * 0.8)}" />
</c:when>
<c:when test="${hits == 4}">
<c:out value="${currentAttack * 0.7}" />
<c:set var="damage" value="${damage + (currentAttack * 0.7)}" />
</c:when>
<c:when test="${hits == 5}">
<c:out value="${currentAttack * 0.6}" />
<c:set var="damage" value="${damage + (currentAttack * 0.6)}" />
</c:when>
<c:when test="${hits == 6}">
<c:out value="${currentAttack * 0.5}" />
<c:set var="damage" value="${damage + (currentAttack * 0.5)}" />
</c:when>
<c:when test="${hits == 7}">
<c:out value="${currentAttack * 0.4}" />
<c:set var="damage" value="${damage + (currentAttack * 0.4)}" />
</c:when>
<c:when test="${hits == 8}">
<c:out value="${currentAttack * 0.3}" />
<c:set var="damage" value="${damage + (currentAttack * 0.3)}" />
</c:when>
<c:when test="${hits == 9}">
<c:out value="${currentAttack * 0.2}" />
<c:set var="damage" value="${damage + (currentAttack * 0.2)}" />
</c:when>
<c:otherwise>
<c:out value="${currentAttack * 0.1}" />
<c:set var="damage" value="${damage + (currentAttack * 0.1)}" />
</c:otherwise>
</c:choose>
</td>
<td><c:out value="${damage}" /></td>
<c:set var="hits" value="${hits + 1}" />
</c:if>
</c:if>
</c:forEach>
</tr>
</c:forEach>
</table>
</c:if>
<form action="foo.jsp" method="post">
<input type="hidden" name="submitted" value="true" />
<c:forEach var="rows" begin="1" end="5" varStatus="stat">
<p> ${stat.count}:
<select name="move${stat.count}">
<option value="">-Select-</option>
<c:forEach var="row" items="${result.rows}">
<option value="${row.attack}|${row.damage}">${row.attack}</option>
</c:forEach>
</select></p>
</c:forEach>
<input type="submit" name="submit" value="Go" />
</form>
JSTL doesn’t change the sort order or something and has also no facilities at all to sort collections. It just allows you to control the flow of HTML generation in JSP and thus displays whatever you told it to display.
Your problem is caused elsewhere. Most likely you’re using a
HashMapinstead ofLinkedHashMapto hold the fields. AHashMapis by nature unordered while aLinkedHashMapis ordered by insertion order exactly like as aList.Update you’re iterating over the implicit EL variable
${paramValues}which refers theServletRequest#getParameterMap()which indeed returns an unorderedHashMap. If you need to retain the order of the request parameters, you’d have to solve the problem differently. For example, by using fixed and indexed parameter names so that you can refer them directly, or by just using a MVC framework.