I have a JSP that I am displaying a list of items on. The list of items will be placed into vertical columns. Each row should have (length of list)/(total number of rows), rounding up if there is a remainder. Right now we are doing two columns, but we want the freedom to change the number of columns.
My work doesn't like scriptlets, so what is the best way to divide a list into equal columns using JSTL?
I will give you a similar answer to the one from Evgeny but a bit more accurate. But I need to make the following assumptions:
First of all, since you can not use any scriptlet, you will need the following taglib declarations:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Now, to build your grid of items you will write something similar to this:
<table>
<c:forEach begin="0" end="${numRows - 1}" varStatus="i">
<c:set var="rowStart" value="${i.index * numColumns}" />
<tr>
<fmt:formatNumber var="numColumns" value="${fn:length(values) / numRows}"
maxFractionDigits="0" />
<c:forEach begin="0" end="${numColumns - 1}" varStatus="j">
<c:set var="index" value="${rowStart + j.index}"/>
<td>
<c:choose>
<c:when test="${index lt fn:length(values)}">
<%-- Replace following code with the one needed to display your item --%>
<c:out value="${values[index]}" />
</c:when>
<c:otherwise> </c:otherwise>
</c:choose>
</td>
</c:forEach>
</tr>
</c:forEach>
</table>
In this example I am first rounding the value of the division to calculate the number of rows to render (see answer How do I round a number in JSTL?). Then the iteration through items to generate rows and columns start almost exactly as Evgeny did. The main difference resides in that you will need to perform an index check before accessing your list and in case your index is out of bounds, just render a "non breaking space" so your table will be "HTML correct".