Search code examples
spring-mvcspring-bootthymeleaf

Map checkboxes to List using Sprint Boot and Thymeleaf


I have a Spring Boot 1.3.0 app that uses Thymeleaf. I have a form on a page that allows a user to upload a file. I would like to add some checkboxes also return back to my controller.

I have not found a good example how to do checkboxes this way. I think I have to define a list in my model, and let Thymeleaf display all the check boxes, but I have not been able to make it work.

Here is my controller:

@Controller
public class CustomerDataController {

    private static final String SEARCH_TYPES = "searchTypes";

    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public String displayUpload(Model model) {
        initModel( model );
        return "upload";
    }

    private void initModel(Model model) {
        model.addAttribute( UPLOAD, null );
        // the values to display as check box title & values
        model.addAttribute(SEARCH_TYPES, Arrays.asList("Search A", "Search B"));
        // list to store what the user checks on the UI 
        model.addAttribute("searchValue", new ArrayList<>());
        model.addAttribute( customerResults );
    }

    @Transactional
    @RequestMapping(value = "/userFile", method = RequestMethod.POST)
    public String handleFileUpload(@RequestParam("myFile") MultipartFile file, Model model, Authentication authentication) {

    // looking to get searchValue list, but not sure this is right
    }
}

And here the important bits of my html:

<form onsubmit="return validate(this)" action="userFile"
      th:action="@{/userFile}" method="post" enctype="multipart/form-data">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    <ul>
        <li th:each="search : ${searchTypes}">
            <input type="checkbox" th:field="*{searchValue}" th:value="${search}"/>
            <label th:text="#{${search}}"></label>
        </li>
    </ul>
    <p><input type="file" name="myFile" id="myFile"/></p>
    <p><input type="submit" class="btn btn-success" value="Submit Customer Data"/></p>
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

The list of checkboxes build properly, but when I select any of them, no values show up in the model of my controller.

Can someone please point me in the right direction to return a list of selected checkboxes to my controller?


Solution

  • I have fixed your code.

    Controller

    I use initValues() method to populate model with values.

    Also I added @RequestParam List<String> searchValues parameter to handleFileUpload() method.

    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.util.Arrays;
    import java.util.List;
    
    @Controller
    public class CustomerDataController {
    
        private static final String SEARCH_TYPES = "searchTypes";
    
        @ModelAttribute
        public void initValues(Model model) {
            model.addAttribute(SEARCH_TYPES, Arrays.asList("Search A", "Search B"));
        }
    
        @RequestMapping(value = "/upload", method = RequestMethod.GET)
        public String displayUpload() {
            return "upload";
        }
    
        @RequestMapping(value = "/userFile", method = RequestMethod.POST)
        public String handleFileUpload(@RequestParam("myFile") MultipartFile file,
                                       @RequestParam List<String> searchValues) {
    
            // here you can use searchValues and file
            return "result";
        }
    }
    

    upload.html

    I fixed <label th:text="#{${search}}"></label> to <label th:text="${search}"></label>.

    Also I fixed <form> and <input type="checkbox"> tags.

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
          lang="en"
          xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8"/>
        <title>Upload</title>
    </head>
    <body>
    
    <form th:action="@{/userFile}" method="post" enctype="multipart/form-data">
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
        <ul>
            <li th:each="search : ${searchTypes}">
                <input type="checkbox" name="searchValues" th:value="${search}"/>
                <label th:text="${search}"></label>
            </li>
        </ul>
        <p><input type="file" name="myFile" id="myFile"/></p>
        <p><input type="submit" class="btn btn-success" value="Submit Customer Data"/></p>
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    </form>
    
    </body>
    </html>