title: Submit checkboxes in JSP form submission to Spring controller
body: <p>I am trying to create a 'to-do list' type web app using Spring and JSP. My <code>tasks.jsp</code> page displays a list of tasks from a database. Some JSON is passed to the view and used to create the HTML table, via a JS function in <code>tasks.js</code>. Resulting in below view:</p>
  
  <p><a href="https://i.stack.imgur.com/fIpNW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fIpNW.png" alt="enter image description here"></a></p>
  
  <p>I now want to be able to select tasks via checkboxes (seen to the right of each row) and delete those chosen rows. The tasks table is a form and the 'Delete Selected' button is used to submit the form.</p>
  
  <p>I'm using a field from the tasks JSON (an ID) passed into the view as the value for each checkbox, so each one has a unique value associated with a particular row.</p>
  
  <p>When I click 'Delete Selected' I can verify that a checkbox value is submitted to my controller as I print out that value in <code>taskDelete()</code>.</p>
  
  <p>My problem is, only one value is ever printed even if I check multiple boxes. How can I get my form to submit a list of all the checkbox values which have been checked?</p>
  
  <p><strong>TaskController.jsp</strong></p>
  
  <pre><code>package com.petehallw.todolist.main;
  
  @Controller
  public class TaskController {
  
      private static final String TASKS = "/tasks";
      private static final String DELETE_TASK = TASKS + "/delete";
  
      @Autowired
      private TaskEntityDao taskEntityDao;
  
      ObjectMapper mapper = new ObjectMapper();
  
      @RequestMapping(value = TASKS, method = RequestMethod.GET)
      public ModelAndView readTasks() 
      {
          List&lt;TaskEntity&gt; tasks = taskEntityDao.readAllTasks();
          String tasksJson;
  
          try {
              tasksJson = mapper.writeValueAsString(tasks);
              return new ModelAndView("tasks", "tasksJson", tasksJson);
          } catch (IOException  e) {
              // ...
          }       
      }
  
      @RequestMapping(value = DELETE_TASK, method = RequestMethod.POST)
      public String taskDelete(@ModelAttribute("selectedTasks") String selectedTasks)
      {           
          System.out.println(selectedTasks);
          return "taskDeleted";
      }
  }
  </code></pre>
  
  <p><strong>tasks.jsp</strong></p>
  
  <pre><code>&lt;%@taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%&gt;
  &lt;html&gt;
  &lt;head&gt;
  &lt;link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/stylesheet.css"&gt;
  &lt;script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.3.js"&gt;&lt;/script&gt;
  &lt;script src="${pageContext.request.contextPath}/js/tasks.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;h2&gt;My Tasks&lt;/h2&gt;
      &lt;div&gt;
          &lt;form:form action = "tasks/delete"&gt;
              &lt;table&gt;
                  &lt;tbody id="tasks_table_body"/&gt;
              &lt;/table&gt;
              &lt;div&gt;
                  &lt;input type = "submit" value = "Delete Selected"/&gt;
                  &lt;input type = "submit" value = "Do something else"/&gt;
              &lt;/div&gt;
          &lt;/form:form&gt;
      &lt;/div&gt;
      &lt;br&gt;
      &lt;div class="actions"&gt;
          &lt;a href="addTask"&gt;Add Task&lt;/a&gt;
      &lt;/div&gt;
  
      &lt;!-- Populate tasks table. --&gt;
      &lt;script type="text/javascript"&gt;
          taskJsonToTable(${tasksJson});
      &lt;/script&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>tasks.js</strong></p>
  
  <pre><code>/**
   * Populate the tasks table from JSON.
   * @param tasksJson A JSON array representing the tasks data from the database.
   */
  function taskJsonToTable(tasksJson)
  {   
      var tableBody = document.getElementById('tasks_table_body');
  
      var tableHeaders = "&lt;tr&gt;&lt;th&gt;Title&lt;/th&gt;"
              + "&lt;th&gt;Description&lt;/th&gt;"
              + "&lt;th&gt;Due Date&lt;/th&gt;"
              + "&lt;th&gt;Priority&lt;/th&gt;"
              + "&lt;th&gt;Select&lt;/th&gt;&lt;/tr&gt;";
  
      /* Add the table headers to the table. */
      tableBody.innerHTML += tableHeaders;
  
      for (var i = 0; i &lt; tasksJson.length; i++) 
      {       
          var tableContent = "&lt;tr&gt;";
  
          tableContent += "&lt;td&gt;" + tasksJson[i].title + "&lt;/td&gt;" 
                  + "&lt;td&gt;" + tasksJson[i].description + "&lt;/td&gt;"
                  + "&lt;td&gt;" + tasksJson[i].dueDate.toString() + "&lt;/td&gt;"
                  + "&lt;td&gt;" + tasksJson[i].priority + "&lt;/td&gt;" 
                  + "&lt;td&gt;&lt;input type='checkbox' name='selectedTasks' value='" +
                  + tasksJson[i].taskId + "'"
                  + "/&gt;&lt;/td&gt;&lt;/tr&gt;";
  
          /* Add the table row to the table. */
          tableBody.innerHTML += tableContent;
      }
  }
  </code></pre>