jamesT
jamesT

Reputation: 349

Unable to bind spring form checkbox

I am trying to display full name, along with checkboxes for supervisor and manager. These two checkboxes are checked if the person has values for these to be true.

What i am trying to do is display users with full name and supervior and manager columns having checkboxes and these are checked or unchecked, and when the form is submitted the changes are binded as well. I tried model attribute but don't have any luck.

Here's what i have so far.

Controller

@Controller
@RequestMapping("/person.html")
public class PersonsController {

    @Autowired
    private PersonService personService;

    @RequestMapping(method = RequestMethod.GET)
    public String initForm(@ModelAttribute("personView")PersonView personView, BindingResult result, Model model) {


        List<Person>  persons= personService.getPersonList();

        PersonView personData = new PersonView();
        personView.setPersonList(persons);


        model.addAttribute("personView", personData);   

        return "member";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String submitForm(Model model, PersonView personView, BindingResult result) {
        System.out.println("Controller runs");
        model.addAttribute("persons", personView);
        return "successMember";
    }

}

View

public class PersonView {

    private boolean isSupervisor;
    private boolean isManager;
    private List<Person> personList;


    public boolean isSupervisor() {
        return isSupervisor;
    }

    public void setSupervisor(boolean isSupervisor) {
        this.isSupervisor = isSupervisor;
    }

    public boolean isManager() {
        return isManager;
    }

    public void setManager(boolean isManager) {
        this.isManager = isManager;
    }

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }

}

Domain

public class Person {

  private String fullName; 
  private Boolean isSupervisor;
  private Boolean isManager;

public String getFullName() {
    return fullName;
}

public void setFullName(String fullName) {
    this.fullName = fullName;
}

public Boolean getIsSupervisor() {
    return isSupervisor;
}

public void setIsSupervisor(Boolean isSupervisor) {
    this.isSupervisor = isSupervisor;
}

public Boolean getIsManager() {
    return isManager;
}

public void setIsManager(Boolean isManager) {
    this.isManager = isManager;
}

}

JSP

        <html>
        <title>Persons Information</title>
        </head>

        <body>

            <form:form method="POST" modelAttribute="personView">
                <table>
                    <tr>
                        <th>Full Name</th>
                        <th>Supervisor</th>
                        <th>Manager</th>
                    </tr>

                    <c:forEach var="person" items="${personView.personList}"
                        varStatus="row">
                        <tr>
                            <td>{person.fullName}</td>
                            <td><form:checkbox path="isSupervisor"
                                    value="${person.isSupervisor}" /></td>
                            <td><form:checkbox path="isManager"
                                    value="${person.isManager}" /></td>
                        </tr>
                    </c:forEach>


                    <tr>
                        <td><input type="submit" name="submit" value="Submit">
                        </td>
                    </tr>
                    <tr>
                </table>
            </form:form>

        </body>
        </html>

Any Suggestion

Upvotes: 2

Views: 2513

Answers (1)

Alan Hay
Alan Hay

Reputation: 23226

The problem here is that you need to bind the parameters to the corresponding person in the list. If you look at the generated HTML as it is you will see that name attributes of the checkboxes are the same for all i.e. on form submit there is no way of determining which parameter applies to which Person.

As you cannot bind to a raw list so you need to keep the wrapper: however it just needs to be as below:

public class PersonView {

    private List<Person> personList;

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }
}

Person with some minor adjustments:

public class Person {

    private String fullName; 
    private Boolean isSupervisor;
    private Boolean isManager;

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public Boolean isSupervisor() {
        return isSupervisor;
    }

    public void setSupervisor(Boolean isSupervisor) {
        this.isSupervisor = isSupervisor;
    }

    public Boolean isManager() {
        return isManager;
    }

    public void setManager(Boolean isManager) {
        this.isManager = isManager;
    }
}

Your JSP loop needs to be as below:

<c:forEach var="person" items="${personView.personList}" varStatus="row">
    <tr>
        <td>{person.fullName}</td>
        <td><form:checkbox path="personList[row.index].supervisor"
                value="true" /></td>
        <td><form:checkbox path="personList[row.index].manager"
                value="true" /></td>
    </tr>
</c:forEach>

Your Controller:

@Controller
@RequestMapping("/person.html")
public class PersonsController {

    @Autowired
    private PersonService personService;

    @RequestMapping(method = RequestMethod.GET)
    public String initForm() {
        return "member";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String submitForm(@ModelAttribute PersonView personView) {
        model.addAttribute("persons", personView);
        return "successMember";
    }

    @ModelAttribute
    public PersonView getPersonView(){
        List<Person>  persons= personService.getPersonList();
        PersonView pv = new PersonView();
        pv.setPersonList(persons);

        return pv;
    }
}

**All this depends on the order of the list in the form handler being the same as that which was loaded for rendering the form and no people having been added in the mean time.

Upvotes: 1

Related Questions