title: Spring MVC and form binding : how to remove an item from a List?
body: <p>I have a <code>Person</code> model attribute that contains a <em>list</em> of emails.</p>
  
  <p>I've created some JavaScript code that deletes elements from an HTML list of emails. This is pure JavaScript client side code, no AJAX call.</p>
  
  <p>After submitting, I don't understand why I get <strong>all</strong> the emails in the corresponding <code>@Controller</code> method, even the ones that were deleted in the HTML.</p>
  
  <p>Can anyone please explain?</p>
  
  <hr>
  
  <h3>JSP</h3>
  
  <pre><code>&lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
  &lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %&gt;
  &lt;%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %&gt;
  &lt;%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %&gt;
  &lt;!DOCTYPE html&gt;
  &lt;html&gt;
  
  &lt;head&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;&lt;/meta&gt;
      &lt;link rel="stylesheet" href="&lt;c:url value="/styles/resume.css"/&gt;" type="text/css"&gt;&lt;/link&gt;
      &lt;link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"&gt;&lt;/link&gt;
      &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"&gt;&lt;/script&gt;
      &lt;script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"&gt;&lt;/script&gt;
      &lt;script src="/resume/js/jquery.editable-1.0.1.js"&gt;&lt;/script&gt;
      &lt;title&gt;Resumes manager&lt;/title&gt;
  
      &lt;script&gt;
      $(document).ready(function() {
          $('.trash').click(function() {
              $(this.parentNode).remove();
          });
  
      });
  
      &lt;/script&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
      &lt;h1&gt;Personal data&lt;/h1&gt;
      &lt;form:form modelAttribute="person" action="/resume/person/edit/save" id="personForm" method="post" &gt;
          &lt;table&gt;
              &lt;tr&gt;
                  &lt;td&gt;Email addresses:&lt;/td&gt;
                  &lt;td colspan="4"&gt;
                      &lt;ol id="emails"&gt;
                          &lt;c:forEach items="${person.emails}" varStatus="status"&gt;
                              &lt;li&gt;&lt;form:hidden path="emails[${status.index}].order" class="emailsDisplayOrder"&gt;&lt;/form:hidden&gt;&lt;form:input path="emails[${status.index}].label"&gt;&lt;/form:input&gt;&lt;form:input type="email" path="emails[${status.index}].value"&gt;&lt;/form:input&gt;&lt;input type="image" src="/resume/images/trash.png" class="trash" value="${status.index}"&gt;&lt;/input&gt;&lt;/li&gt;
                          &lt;/c:forEach&gt;
                      &lt;/ol&gt;
                  &lt;/td&gt;
              &lt;/tr&gt;
          &lt;/table&gt;
      &lt;/form:form&gt;
  &lt;/body&gt;
  
  &lt;/html&gt;
  </code></pre>
  
  <h3>Controller</h3>
  
  <pre><code>@Controller
  @SessionAttributes(types={Person.class}, value={"person"})
  public class PersonController {
  
      private final static String PERSON_VIEW_NAME = "person-form";
  
      private ResumeManager resumeManager;
  
      @Autowired()
      public PersonController(ResumeManager resume) {
          this.resumeManager = resume;
      }
  
      @InitBinder
      public void initBinder(WebDataBinder dataBinder) {
          dataBinder.setDisallowedFields("id");
          SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
          dateFormat.setLenient(false);
          dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
      }
  
      @RequestMapping(value="/person/edit/save")
      public String save(@ModelAttribute(value="person") Person p, BindingResult result, SessionStatus status) {
          new PersonValidator().validate(p, result);
          Collections.sort(p.getEmails()); //this collection still contains client-side dropped objects
  
          this.resumeManager.savePerson(p);
  
          return PERSON_VIEW_NAME;
      }
  }
  </code></pre>