Sometimes we get a good amount of data from database, web services or backend and its tough to fit in a gridview or a table in the front end. Today I will demonstrate a procedure that I do quite often, wrapping data in expand/collapse mode. Its easy to user to find details of entries that they want to see rather than going through details of all entries. I used jQuery with Spring Framework, however it can be done with any framework. Previously while working with PHPRum Framework, I achieved the same thing. I will put on the front end code so it will be easier to anyone without using any framework.
Getting Data from Backend
Actually it does not matter from where you are grabbing data and it’s OK as long you have it the page where the data will be view-able. If you are using a MVC Framework, the controller should send the data to the view. The controller might/should retrieve the data using model. Over here, I’m skipping the code of model part. In this tutorial, I’m grabbing the data from MSSQL database table named ‘users’. Provided below is the structure of the users table.
Controller part which send the data to the view:
// this handles the mapping from browser when /users is invoked @RequestMapping(value="users") @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public String getUserList(Map<String, Object> model,HttpServletRequest request) { // Getting the menu for the application. Also added a menu item named Administrative - Users in menuservice.java Map<String, String> nav = MenuService.getMenu(request); Map<Integer, Object> map = userService.getAllUsers(); //Assigning the menu that will be used in view. model.put("nav", nav); model.put("users",map); CustomAuthenticaionDetails details = (CustomAuthenticaionDetails) SecurityContextHolder.getContext().getAuthentication().getDetails(); Map<String, Object> userDetails = (Map<String, Object> ) details.getUserDetails(); model.put("userDetails", userDetails); // add the file users.jsp in web-inf/jsp folder return "users"; }
Model part retrieving data from the database:
/* * Function to retrieve all users from database * Params: none * Returns: Map containing userid and user details. */ public Map<Integer, Object> getAllUsers() { ResultSet rs = null; // Map which will containing user id and details Map<Integer, Object> map = new HashMap<Integer, Object>(); try { if(dBService == null) { try{ dBService.setDefaultConnection(); }catch(Exception ex){ logging.publish(UsersService.class.getName(), Level.SEVERE, ex); } } // creating query String userSQL= new String("SELECT * FROM Users AS u INNER JOIN UserGroup AS g ON g.UserGroupID = u.UserGroupID"); // getting resultset of the database query rs= dBService.ProcessSQL(userSQL); // invalid resultset return handler if (rs == null || rs.getClass().getName().equals("com.foundpages.dss.service.EmptyResultSet")) { // TODO: Handle null dataset } else { // loop through untill all the items found while (rs.next()) { // getting the resultset column values Integer userID = new Integer(rs.getInt("UserID")); Map<String, String> details = new HashMap<String, String>(); details.put("userName",rs.getString("Username")); details.put("fullName",rs.getString("Name")+" "+((rs.getString("FamilyName")== null)? "":rs.getString("FamilyName"))); details.put("userGroup",rs.getString("UserGroupName")); details.put("name",rs.getString("Name")); details.put("familyName",rs.getString("FamilyName")); details.put("userGroup",rs.getString("UserGroupName")); details.put("groupRole",rs.getString("GroupRole")); details.put("password",((rs.getString("Password")==null)?"(blank)":rs.getString("Password"))); details.put("active",((rs.getString("Active").trim().equals(new String("Y")) )?"Yes" : "No")); try{ String updated = rs.getString("Updated"); Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(updated); String updateDate = new SimpleDateFormat("MMMM d, y").format(date)+" at " + new SimpleDateFormat("h:mma").format(date); details.put("updated",updateDate); }catch(ParseException ex){ logging.publish(UsersService.class.getName()+" getAllUsers() ", Level.SEVERE, ex); } map.put(userID, details); } } } catch(SQLException ex) { logging.publish(UsersService.class.getName()+" getAllUsers() ", Level.SEVERE, ex); } return map; }
Front end Code:
JavaScript Code
<script type="text/javascript"> var user_list = {}; var index=0; user_list.show_data = function (context) { <c:forEach var="userDetails" items="${users}" > context.find('tr').eq(index).closest('tr').after('<tr class="details collapsed">\n\ <td></td>\n\ <td colspan="5"> <div style="display:none;"><fieldset style="border:0px;"><dl>'+ '<dt>Group:</dt><dd>${userDetails.value.userGroup}</dd>'+ '<dt>Role:</dt><dd>${userDetails.value.groupRole}</dd>'+ '<dt>Last updated:</dt><dd>${userDetails.value.updated}</dd>'+ '</fieldset></div></td></tr>'); index+=2; </c:forEach> $('.expand').click(function() { $(this).closest('tr').next().find('div').slideToggle(500); $(this).closest('tr').next().toggleClass('expanded collapsed'); $(this).toggleClass('expand collapse'); $(this).closest('tr').toggleClass('bluerow'); }); $(".show").click(function(){ //alert($(this).next().html()); $(this).hide(); $(this).next().show(); }); }; $(document).ready(function() { user_list.show_data($('#tbody_users')); }); </script>
Gridview Table:
<table class="gridview"> <thead> <tr> <th ></th> <th >User Name</th> <th >First Name</th> <th >Last Name</th> <th >Active</th> <th ></th> </tr> </thead> <tbody id="tbody_users"> <c:forEach var="userDetails" items="${users}" varStatus="i" > <tr <c:choose> <c:when test="${i.count %2 == 1}"> class ="odd" </c:when> <c:otherwise> class ="even" </c:otherwise> </c:choose> > <td class="expand"> </td> <td> <c:out value="${userDetails.value.userName}"/> </td> <td> <c:out value="${userDetails.value.name}"/> </td> <td> <c:out value="${userDetails.value.familyName}"/> </td> <td> <c:choose > <c:when test="${userDetails.value.active == 'Yes'}"> <img src="<%= request.getContextPath()%>/decorators/images/active-yes.png" /> </c:when> <c:otherwise> <img src="<%= request.getContextPath()%>/decorators/images/active-no.png" /> </c:otherwise> </c:choose > </td> <td><a class="edit button" title="Edit" href="edit-user?id=${userDetails.key}"/></td> </tr> </c:forEach> </tbody> </table
Here is the end result: