I have a servlet which loads a properties file and contains a list of 100 test case names into an ArrayList object. After loading the servlet forwards to a JSP which displays the list in a table. The list is long so I would like some elegant way to display it in a table so that it breaks up into, for example, three or four columns on the JSP.
What I do now is break up the list into three sublists in the servlet:
//load properties
Properties props = new Properties();
ArrayList<String> tests = new ArrayList<String>();
props.load(getServletContext().getResourceAsStream("/WEB-INF/sailcertifier.properties"));
Pattern pattern = Pattern.compile("[A-Z]{3}-[0-9]{2}");
for (Enumeration<Object> e = props.keys(); e.hasMoreElements();) {
String key = (String) e.nextElement();
Matcher m = pattern.matcher(key);
if (m.find())
tests.add(key);
}
Collections.sort(tests, new TestOrderComparator());
confBean.setPossibleTests(tests.toArray(new String[tests.size()]));
int third = tests.size() / 3;
List<String> testSubset1 = tests.subList(0, third);
List<String> testSubset2 = tests.subList(third, third * 2);
List<String> testSubset3 = tests.subList(third * 2, tests.size());
//store the bean as a request attribute
request.setAttribute("testSet1", testSubset1.toArray(new String[testSubset1.size()]));
request.setAttribute("testSet2", testSubset2.toArray(new String[testSubset2.size()]));
request.setAttribute("testSet3", testSubset3.toArray(new String[testSubset3.size()]));
request.setAttribute("testsConf", confBean);
request.setAttribute("certProps", props);
//forward to tests selection page
String url = "/sailcertifier/jsp/testsSelection.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
response.setContentType("application/javascript");
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
}
In the JSP I iterate through the sublists like so (adding some html elements for each case):
<table>
<tr>
<td style="width: 33%">
<table>
<tr>
<td>
<c:forEach var="testName" items="${testSet1}">
<tr>
<td><label for="${testName}" id=${testName}Label>${testName}</label></td>
<td><input id=${testName} type="checkbox" value=${testName} name="selTest"></input></td>
<td><input id=${testName}Run type="button" value="Run Test" name="runButtons" /></td>
<td><input id=${testName}ManPass type="button" value="Manual Pass" name="manPassButtons"/></td>
<td><div id=${testName}Status style="width:100px"></td>
<td></td>
<td></td>
</tr>
</c:forEach>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</td>
</tr>
</table>
</td>
<td style="width: 33%">
<table>
<tr>
<td>
<c:forEach var="testName" items="${testSet2}">
<tr>
<td><label for="${testName}" id=${testName}Label>${testName}</label></td>
<td><input id=${testName} type="checkbox" value=${testName} name="selTest"></input></td>
<td><input id=${testName}Run type="button" value="Run Test" name="runButtons" /></td>
<td><input id=${testName}ManPass type="button" value="Manual Pass" name="manPassButtons"/></td>
<td><div id=${testName}Status style="width:100px"></td>
<td></td>
<td></td>
</tr>
</c:forEach>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</td>
</tr>
</table>
</td>
<td style="width: 33%">
<table>
<tr>
<td>
<c:forEach var="testName" items="${testSet3}">
<tr>
<td><label for="${testName}" id=${testName}Label>${testName}</label></td>
<td><input id=${testName} type="checkbox" value=${testName} name="selTest"></input></td>
<td><input id=${testName}Run type="button" value="Run Test" name="runButtons" /></td>
<td><input id=${testName}ManPass type="button" value="Manual Pass" name="manPassButtons"/></td>
<td><div id=${testName}Status style="width:100px"></td>
<td></td>
</tr>
</c:forEach>
</td>
</tr>
</table>
</td>
</tr>
</table>
I admit using three JSTL for loops is kind of ugly (haven't figured out use the full original list yet). Is there a cleaner way to handle this, by using some jquery plugin (like jquery grid plugin) or other library (displaytag?) to handle the breaking up into rows evenly for me?
i'm not sure i've understood your request but suppose you have your 100 elements array and you want 3 columns to display them, so you can exploit "float" property to achieve that: just make a div of the width you want and iterate over the arrays making inner divs of width/3:
Print a
<tr>
, then loop over the array list, then print each item in a<td>
and print a</tr><tr>
every n items, then end the loop over the array list and finally print a</tr>
afterwards.E.g. a new row every 3rd item:
The
${loop.index}
returns the index of the current iteration round. The% 3
would only return0
if it is dividable by 3 without a remainder (thus, when the index is 0, 3, 6, 9, 12, etc).