How to pass checkbox values to the controller in S

2019-08-15 22:43发布

问题:

I have a jsp page with list of functions. Here in controller I get this list from database and pass it to jsp.

@RequestMapping(value = "/functionlist", method = RequestMethod.GET)
    public ModelAndView functionList(Model model) throws Exception {
        ModelAndView mv = new ModelAndView("functionList");
        mv.addObject("functionList", getFunctionsFromDB());
        return mv;
    }

In my jsp page I create table using this list of functions

<table id="table">
    <thead>
    <tr>
        <th></th>
        <th>Name</th>
        <th>Action</th>
    </tr>
    </thead>
    <tbody>
    <c:choose>
        <c:when test="${not empty functionList}">
            <c:forEach var="function" items="${functionList}">
                <tr>
                    <td><input name="id" value="${function.id}" hidden></td>
                    <td>${function.name}</td>
                    <td>
                        <input type="checkbox" id="${function.id}" value="${function.action}"></td>
                </tr>
            </c:forEach>
        </c:when>
    </c:choose>
    </tbody>
</table>
<button type="submit" name="save">Save</button>

I also give function id to checkbox id.

My Function entity is the following

public class Function {

    private Integer id;
    private String name;
    private Boolean action;
...
}

I want to press button Save and get in controller "/functionlist/save" my list of checkbox values.

回答1:

Try to add form like this to your jsp page

  <form:form id="yourForm" action="/functionlist/save" method="POST" modelAttribute="functionList">

        <c:forEach items="${functionList}" varStatus="status" var="function">

            <tr>
                <td>${function.name}</td>
                <td>
                    <form:checkbox path="functionList[${status.index}].action"/>
                </td>
            </tr>
        </c:forEach>

        <input type="submit" value="submit" />
    </form:form>

and in Controller you should have a method like this

  @RequestMapping(value = { "/functionlist/save" }, method = RequestMethod.POST)
    public String savePerson(@ModelAttribute("functionList")List<Function> functionList) {
        // process your list
    }

If this does not work, you can try to wrap you list.

public class FunctionListWrapper {
    private List<Function> functionList;

    public FunctionListWrapper() {
        this.functionList = new ArrayList<Function>();
    }

    public List<Function> getFunctionList() {
        return functionList;
    }

    public void setFunctionList(List<Function> functionList) {
        this.functionList = functionList;
    }

    public void add(Function function) {
        this.functionList.add(function);
    }
}

in controller instead of passing list, pass wrapper

  FunctionListWrapper functionListWrapper=new FunctionListWrapper();
        functionListWrapper.setFunctionList(userService.getFunctionList());
        mv.addObject("functionListWrapper", functionListWrapper);

For more details please take a look at this questions: question 1 and question 2



回答2:

First you need to add name attribute to your checkbox inputs.You can get these in an array on controller with same name as your name attribute.eg-

    @RequestMapping(value = "/functionlist", method = RequestMethod.GET)
        public ModelAndView functionList(Model model,@RequestParam("checkboxname")String[] checkboxvalues) throws Exception {
        ModelAndView mv = new ModelAndView("functionList");
        mv.addObject("functionList", getFunctionsFromDB());
       return mv;
}


回答3:

few things. First you should think about a form object, which is the exchange entity between the view and the controller. The form entity will be something similar to the followng:

public class Form {
private List<Function> functions;
//getters & setters
}

secondly, since you are using Spring MVC, you should leverage the <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> library. Consequently, your form will be:

<form:form  commandName="form"  action="/your/url">
<c:forEach items="${form.functions }" var="function" varStatus="status">
    <tr>
        <td><form:hidden path="functions[${status.index }].id"></td>
        <td>${function.name}</td>
        <td>
            <form:checkbox path="functions[${status.index }].action" id="${function.id}" value="${function.action}"/>
        </td>
    </tr>
</c:forEach>
</form:form>

and finally the controller will be something like

@RequestMapping(value="/your/url", method=RequestMethod.POST)
public String postForm(@ModelAttribute("form") FormForm form)
{
    //cool stuff here
}

please note that the proper HTTP method is POST, not GET. Yup, I know things work also with GET it's definitely a deprecated strategy. In addition, figure out how I referred the list of Function in the Form. I used the variable function in the foreach statement when I had to display data, I referred the list when I had to bind the Form object for transferring data to the controller. Last but not least, I haven't tried the code. I wrote it on the fly just to give you hints about how to do it properly. One last thing. Since you pass the Form to the JSP, you don't need anymore to fill the Model with the attribute you used. Just fill the form with your data and use it to diaplay them in the view. Just like this ${form.stuff.you.want}