spring-mvcarraylistdata-bindingjstl

Getting null values from checkboxes


I am working on a simple Spring MVC project. I am having trouble getting values from checkboxes. What I mean is when a user checks 2 boxes out of 3, all 3 are binded to a list with non-checked values as null. That's wrong. I just want values that are checked. Those that didn't get checked should not come to list at all. This is a snippet of my code: POJO:

public class Student{
private List<StudentCourses> sc;
//getters and setters
}

public class StudentCourses{
private int courseID;
private String courseName;
private Character grade;
private String semesterID;
//getters and setters
} 

This is what I send from my controller:

@RequestMapping(value = "/selectclasses", method = RequestMethod.POST)
public String selectClasses(Model m) {
Student s = new Student();
List<StudentCourses> coursesList = new ArrayList<StudentCourses>();
coursesList.add(new StudentCourses("Eng 101", '-', "SP 16"));
coursesList.add(new StudentCourses("Math 140", '-', "SP 16"));
coursesList.add(new StudentCourses("CS 442", '-', "SP 16"));
m.addAttribute("coursesList", coursesList);
m.addAttribute("student", s);
return "selectclasses";
}

This is what I have in my selectclasses.jsp:

    <form:form modelAttribute="student" method="post" action="/success">
        <table>
            <c:forEach items="${coursesList}" var="r" begin="0" varStatus="status">
                <form:checkbox path="sc[${status.index }].courseName" value="${r.courseName}" label="${r.courseName}" />
            </c:forEach>
        </table>
        <input type="submit" id="submit" name="submit" value="Submit" />
    </form:form>

I don't know why null is passed to the "sc.courseName" when it's not checked. What am I doing wrong? Or is there a work around it?

Please help Thanks.


Solution

  • I found two ways to solve it. This is the solution using Spring tags:

    <form:checkboxes path="sc" items="${coursesList}" itemValue="courseName" itemLabel="courseName" />
    

    itemValue and itemLabel are the main tags. itemValue and itemLabel simply refer to bean properties of an object inside items attribute ("${coursesList}"). In a nutshell, if you need to use a list of your custom beans as the items attribute you also need to use the itemValue and itemLabel attributes. This bold part of paragraph is taken from: https://stackoverflow.com/a/15529281/4828463 by @Carlos Gavidia

    And now the solution using JSTL core tags:

        <c:forEach items="${coursesList}" var="courses">
            <tr>
                <td><form:checkbox path="sc" value="${courses.courseName}" label="${courses.courseName}"/></td>
            </tr>
        </c:forEach>
    

    Again the value and label attributes are important.