Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating checkboxes in JSP page with data from a JavaBean

I have a JSP page with checkboxes inside an HTML form as below

enter image description here

Now while editing user Skill I want to take the comma separated values from the table and populate the checkboxes in JSP. The following code brings the CSV Skills from the database table.

      List<UserDetails> Skills = new ArrayList<UserDetails>();

      pstmt = (PreparedStatement) conn.prepareStatement(strSQL);
      rs    = pstmt.executeQuery();       
      String strSkills = rs.getString("Skills");

      List<String> items = Arrays.asList(strSkills.split("\\s*,\\s*"));

      objUserDetails.setSkills(items.toArray(new String[0]));

      Skills.add(objUserDetails);

      return Skills;

Now I need to populate the checkboxes in JSP with the respective Skills checked. I used the Request getAttribute() method and I am passing to JSP as below

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{
   dbUtil objdbUtil     = new dbUtil();
   List<UserDetails> Skills = objdbUtil.getSkills();

   request.setAttribute("arrSkills", Skills);
   RequestDispatcher rqst = request.getRequestDispatcher("Skills.jsp");
   rqst.forward(request, response);
}

How to use the Skills which I got in arrSkills array and populate the check boxes. I tried using

<c:forEach var="account" items="${arrUsersList}">
    <input type="checkbox" name="chkSkills" id="chkPHP" value="PHP"/>PHP
    <input type="checkbox" name="chkSkills" id="chkJava" value="Java"/>Java
    <input type="checkbox" name="chkSkills" id="chkMySQL" value="MySQL"/>MySQL
    <input type="checkbox" name="chkSkills" id="chkJavascript" value="Javascript"/>Javascript
    <input type="checkbox" name="chkSkills" id="chkJQuery" value="JQuery"/>JQuery
    <input type="checkbox" name="chkSkills" id="chkNode" value="Node"/>Node Js
</c:forEach>

But I am sure this is not the right way to use it.

like image 956
Java Beginner Avatar asked Feb 13 '13 09:02

Java Beginner


1 Answers

Examining your example, here are some notes.

1) Related to your Skills variable.
In Java local variables, instance variables, and class variables by convention are written in CamelCase with lowercase first letter.

Read Wikipedia article for Java naming conventions.
Also see chapter 9 about Naming conventions from the Code Conventions for the Java™ Programming Language.

So this would be better:

List<UserDetails> skills = new ArrayList<UserDetails>();

2) Again related to your Skills variable.
You named it skills, although from your code it is clear that skills is just one of the properties of the UserDetails object. I am making an assumption, but is the UserDetails class only about user skills? If yes, then it would be better to somehow reflect this in the class name, like UserSkills, for example. Otherwise, if the skills is just one of the user details, then something like this would be better:

List<UserDetails> userDetailsList = new ArrayList<UserDetails>();

Again, it is highly recommended to use meaningful variable names. Read the Naming conventions above.

3) You don't need to cast to PreparedStatement when calling Connection.prepareStatement() method because it already returns PreparedStatement object. So just do:

pstmt = conn.prepareStatement(strSQL); 

As an answer to your question, yes, of course you can use <c:forLoop> from the JSTL, for example to iterate thru the list of all users and output the related details for each user. It is a common practice.

It was not very clear from your question, but let me guess.
In your example, you have only the finite list of skills, I mean only PHP, Java, MySQL, JavaScript, jQuery, Node.js, and for each user you want the related check boxes to be checked if the user has the appropriate skill.

If the above assumption is correct then here is one of the possible solutions.


Set an attribute containing the array or a list of all the skills you need.

Considering the fact that the list is limited to just the predefined values, you can store that list in ServletContext, so that it would be available to the whole application. It is better to set such global objects in the class that implements ServletContextListener.

Example: AppContextListener.java:

package com.example.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        String[] skills = {"PHP", "Java", "MySQL", "JavaScript", "jQuery", "Node.js"};
        event.getServletContext().setAttribute("skills", skills);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {

    }
} 

NB! In order to receive these notification events (contextInitialized, contextDestroyed), the implementation class must be either declared in the deployment descriptor of the web application, annotated with WebListener, or registered via one of the addListener methods defined on ServletContext. Here I used @WebListener annotation.

I don't have time to deepen into architectural details, but for this example I assume there is a class User, that contains user related info. Among others it contains property skills implemented as a Map<String, Boolean>. It has getters and setters (like public Map<String, Boolean> getSkills() and public void setSkills(Map<String, Boolean> skills)).

Example: User.java

package com.example.model;

import java.util.Date;
import java.util.Map;

public class User {

    private String fisrtName;
    private String lastName;
    private Date birthday;
    ...
    private Map<Sting, Boolean> skills;

    // getters and setters here
}


And somewhere, in one of your servlets that processes data submitted thru some HTML form in the doPost() method, you populate the user skills and other details. Something like this (simplified example):

User user = new User();
// set the user related data like first name or something like that
...
// get the list of available skills from ServletContext
String[] skills = (String[]) getServletContext().getAttribute("skills");
Map<String, Boolean> userSkills = new HashMap<String, Boolean>();

// Set the appropriate skills
for (String skill: skills) {
    if (request.getParameter(skill) != null) {
        userSkills.put(skill, true);
    } else {
        userSkills.put(skill, false);
    }
}

...
// Set user skills
user.setSkills(userSkills);
...

This way you don't hard code the skills' names, otherwise you could do like this:

...
Map<String, Boolean> userSkills = new HashMap<String, Boolean>();
if (request.getParameter("PHP") != null) {
    userSkills.put("PHP", true);
} else {
    userSkills.put("PHP", false);
}
// the same way for Java, MySQL and others
...


Now in some servlet, get all the users as, for example, a List<User> users, set an attribute in the request scope, like request.setAttribute("users", users) to store the users list and forward to some view (JSP page) that will output the data related to all users.

Simple example of JSP page that outputs the user related data: users.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
    <title>Test Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <%-- We iterate thru all the users --%>
    <c:forEach items="${users}" var="user">
        <!-- Outputting different user related data -->
        ...
        <!-- Now outputting the user skills -->
        <h3>User skills</h3>
        <%-- In the inside loop, we iterate thru all the available skills, stored in the ServletContext --%>
        <c:forEach items="${skills}" var="skill">
            <c:choose>
                <%-- If the user has the appropriate skill, the related checkbox will be checked. Otherwise unchecked. --%>
                <%-- Note: using skill as a key in the map of user skills --%>
                <c:when test="${user.skills[skill] == true}">
                    <input type="checkbox" name="chkSkills" value="${skill}" checked="checked">${skill}&nbsp;
                </c:when>
                <c:otherwise>
                    <input type="checkbox" name="chkSkills" value="${skill}">${skill}&nbsp;
                </c:otherwise>
            </c:choose>
        </c:forEach>
    </c:forEach>
</body>
</html>

Or more compact variant using <c:if> tag: users.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
    <title>Test Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <c:forEach items="${users}" var="user">
        ...
        <h3>User skills</h3>
        <c:forEach items="${skills}" var="skill">
            <%-- Note: here <c:if> tag is used right inside <input> tag --%>
            <input type="checkbox" name="chkSkills" value="${skill}" <c:if test="${user.skills[skill]}">checked="checked"</c:if>>${skill}&nbsp;
        </c:forEach>
    </c:forEach>
</body>
</html>

NOTE:
to comment JSP specific parts of code inside JSP, better use JSP comments in the form of
<%-- Some comment --%>. Unlike HTML comments (in the form of <!-- Some comment -->), JSP comments will not be visible in the resulting page that will be send to a client.


Hope this will help you and give some useful ideas.

like image 157
informatik01 Avatar answered Sep 28 '22 01:09

informatik01