I am developing an employee scheduler Java web applicatyion where an employee can specify days they will be out of the office for things such as vacation, business travel, etc…I have a simple mechanism for adding/editing/deleting these records. But I am struggling with the JSTL and which collector I should be passing to the jsp for the forEach looping.
Ultimately I need to display a table on a jsp page that looks omething like this:
October 2010 Employee Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu ... 1 2 3 4 5 6 7 ... Abate * * * * * [E] Adams * * * * * [E] [E] Benson * * * * * [E] [E]
Where [E] would be a list of items or events against that employee for that particular day
And this is a sample list of events from a sql call:
EVENT_ID BADGE EVENT_TYPE_ID EVENT_TYPE_NAME EVENT_S_DATE 1 134311 5610 Business Travel 2010-10-08 2 101379 7646 Floating Holiday 2010-10-11 3 005396 3600 Vacation 2010-10-12 4 134311 1318 Military 2010-10-12 5 134311 0575 Sick Time 2010-10-12 6 101379 6652 Unpaid 2010-10-18 7 111243 0575 Sick Time 2010-10-29
My first approach was to use nested hashmaps and key it with the day but I had difficulty reference the value in the map using JSTL because of the issues with using numbers for keys (My key was the cell number offset by the start day, October starts on day 5 or Friday).
EL access a map value by Integer key
I foresee me making a bunch of loops in the servlet that populates some type of container to accomplish this.
I’m looking for at least something like “Oh, nest a List in a Map and stuff that in another map” to get me started.
Advertisement
Answer
Ok, I finally figured out the nested collection and loop myself, so I’ll answer my own question. Both the servlet and view code probably could use some improving, but it works.
Servlet:
ArrayList eventListPerDayPerBadge = new ArrayList(); ArrayList eventListPerDay = new ArrayList(); HashMap eventMapByDay = new HashMap(); HashMap eventMapByDayByBadge = new HashMap(); int lastDay = 0; int eventDay = 1; String lastBadge = "0"; String currentBadge = "currentBadge"; Event event = null; Iterator eventList = employeeEvents.iterator(); while (eventList.hasNext()) { event = (Event) eventList.next(); eventDay = DateUtil.toCalendar(event.getEvent_s_date()).get(Calendar.DATE); currentBadge = event.getBadge(); if (eventDay == lastDay) { eventListPerDay.add(event); if (currentBadge.equals(lastBadge)) { eventListPerDayPerBadge.add(event); } else { HashMap tempMap = new HashMap(); if (eventMapByDayByBadge.get(lastBadge) != null) { tempMap = (HashMap) eventMapByDayByBadge.get(lastBadge); } tempMap.put(new Long(eventDay), eventListPerDayPerBadge); eventMapByDayByBadge.put(lastBadge, tempMap); eventListPerDayPerBadge = new ArrayList(); eventListPerDayPerBadge.add(event); } eventMapByDay.put(new Long(eventDay), eventListPerDay); } else { if (!"0".equals(lastBadge)) { HashMap tempMap = new HashMap(); if (eventMapByDayByBadge.get(lastBadge) != null) { tempMap = (HashMap) eventMapByDayByBadge.get(lastBadge); } tempMap.put(new Long(lastDay), eventListPerDayPerBadge); eventMapByDayByBadge.put(lastBadge, tempMap); eventMapByDay.put(new Long(lastDay), eventListPerDay); } eventListPerDayPerBadge = new ArrayList(); eventListPerDayPerBadge.add(event); eventListPerDay = new ArrayList(); eventListPerDay.add (event); } lastDay = eventDay; lastBadge = currentBadge; } // Get the last record into the maps HashMap tempMap = new HashMap(); if (eventMapByDayByBadge.get(lastBadge) != null) { tempMap = (HashMap) eventMapByDayByBadge.get(lastBadge); } tempMap.put(new Long(eventDay), eventListPerDayPerBadge); eventMapByDayByBadge.put(lastBadge, tempMap); eventMapByDay.put(new Long(eventDay), eventListPerDay); request.setAttribute("eventMapByDayByBadge", eventMapByDayByBadge); request.setAttribute("eventMapByDay", eventMapByDay);
View (not all Attributes used in the view are shown in the servlet):
<table align="center" border="1" cellpadding="3" cellspacing="0" width="100%"> <tbody> <!-- Header ROW --> <tr> <th>Employee</th> <c:forEach var="week" begin="1" end="${iTotalweeks}" varStatus="status"> <th class="optionYellow">Sun</th> <th>Mon</th> <th>Tue</th> <th>Wed</th> <th>Thu</th> <th>Fri</th> <th class="optionYellow">Sat</th> </c:forEach> </tr> <!-- Week Day Number ROW --> <tr> <td align="center" height="35" class="dsb">* </td> <c:forEach var="week" begin="1" end="${iTotalweeks}" varStatus="status"> <c:forEach var="cell" begin="${1+7*(week-1)}" end="${7+7*(week-1)}" step="1" varStatus="status"> <c:set var="dayNo" value="${cell-weekStartDay+1}" /> <c:choose> <c:when test="${weekStartDay>cell || (cell-weekStartDay+1)>days}"> <td align="center" height="35" class="<c:out value="${weekendCellMap[cell]}" />">* </td> </c:when> <c:otherwise> <td class="<c:out value="${holidayColorMap[dayNo]}" />"><span class="calDayNo"> <c:out value="${dayNo}" /></span> <span class="calDayName"> <c:out value="${holidayNameMap[dayNo]}" /></span> </td> </c:otherwise> </c:choose> </c:forEach> </c:forEach> </tr> <!-- Employee ROW --> <c:forEach var="employee" items="${employeeList}"> <c:set var="map" value="${eventMapByDayByBadge[employee.badge]}" /> <tr> <td align="center" height="35" NOWRAP><c:out value="${employee.lname}" />, <c:out value="${employee.firstName}" /><br> (<c:out value="${employee.badge}" />) </td> <c:forEach var="week" begin="1" end="${iTotalweeks}" varStatus="status"> <c:forEach var="cell" begin="${1+7*(week-1)}" end="${7+7*(week-1)}" step="1" varStatus="status"> <c:set var="dayNo" value="${cell-weekStartDay+1}" /> <c:choose> <c:when test="${weekStartDay>cell || (cell-weekStartDay+1)>days}"> <td align="center" height="35" class="<c:out value="${weekendCellMap[cell]}" />">* </td> </c:when> <c:otherwise> <td align="center" height="35" class="<c:out value="${holidayColorMap[dayNo]}" />"><span> <c:forEach var="event" items="${map[dayNo]}"> <c:out value="${event.event_type_name}" /> </c:forEach></span></td> </c:otherwise> </c:choose> </c:forEach> </c:forEach> </tr> </c:forEach> </tbody> </table>
Example output from the view