ytnk531の日記

日々調べたことを書きます。

Spring + JSP + JQueryでポチポチしてフォームを増やしたい。

ポチポチしたい

フォームをネストして、サブフォームをいっぱい持つParentForm

package myspring.web;

import java.io.Serializable;
import java.util.List;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class ParentForm implements Serializable{
    private static final long serialVersionUID = 1L;
    
    private List<ChildForm> children;
    
    @NotNull
    @Size(min = 1, max = 20)
    private String name;    
    /**
     * 
     */
    public ParentForm() {
	super();
    }
    /**
     * @return the children
     */
    public List<ChildForm> getChildren() {
        return this.children;
    }
    /**
     * @param children the children to set
     */
    public void setChildren(List<ChildForm> children) {
        this.children = children;
    }
    /**
     * @return the name
     */
    public String getName() {
        return this.name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
}

いっぱい持たれるChildForm

package myspring.web;

public class ChildForm {
    private String name;
    private String group;
    /**
     * 
     */
    public ChildForm() {
	super();
    }
    /**
     * @return the name
     */
    public String getName() {
        return this.name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the group
     */
    public String getGroup() {
        return this.group;
    }
    /**
     * @param group the group to set
     */
    public void setGroup(String group) {
        this.group = group;
    }
}

Controller

package myspring.web;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WelcomeController {
    @RequestMapping("/")
    public String fuck(Model model) {
	return "welcome";
    }
    
    @RequestMapping("/me")
    public String me(ParentForm form, Model model) {
	form.setChildren(Arrays.asList(new ChildForm(), new ChildForm()));
	model.addAttribute("form", form);
	return "fuckYou";
    }
    
    @RequestMapping("/new")
    public String rec(@Valid ParentForm form, BindingResult result, Model model) {
	if (form.getChildren() != null) {
	form.getChildren().stream()
		.filter(Objects::nonNull)
		.forEach(child -> System.out.println("forEach" + child.getName()));
	
	List<ChildForm> childforms = form.getChildren().stream()
		.filter(Objects::nonNull)
		.filter(child -> child.getName() != null)
		.collect(Collectors.toList());
	
	form.setChildren(childforms);
	}
	model.addAttribute("form", form);
	if (result.hasErrors()) {
	    return "fuckYou";
	}
	return "fuckMe";
    }    
}

JSPは、JQueryを使ったけど、たいしたことしてないので使わないほうがいいかもしれない。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Sub Form Sample</title>
<script src="/webjars/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<c:set var="count" value="0"/>
<h2>Sub Form Sample</h2>
  <form:form modelAttribute="form" action="/new">
    <table>
      <tr>
        <td colspan="4">
          <button type="button" id="add">Add</button>          
        </td>
      </tr>
      <c:forEach items="${form.children}" varStatus="rowS" var="item">
        <tr id="subform${rowS.index}">
          <td>Name</td>
          <td><form:input path="children[${rowS.index}].name" /></td>
          <td>Group</td>
          <td><form:input path="children[${rowS.index}].group" /></td>
          <td><button type="button" class="remove" onclick="removeForm(${rowS.index})">Remove</button></td>
        </tr>
        <c:set var="count" value="${rowS.index + 1}" />
      </c:forEach>
      <tr id="subformanker"><td></td></tr>
      <tr>
        <td colspan="4"><input type="submit" value="Save Changes" /></td>
      </tr>
    </table>
  </form:form>

  <script>
      var count = ${count};
      function removeForm(index) {
        $("#subform" + index).remove();
        console.log(count);
      }
      $(document).ready(function () {
        $("#add").click(function (event) {
          $('<tr id=subform' + count + '>').append("<td>Name</td>")
                .append('<td><input id="children' + count + '.name" name="children[' + count + '].name" type="text" value=""/></td>')
                .append('<td>Group</td>')
                .append('<td><input id="children' + count + '.group" name="children[' + count + '].group" type="text" value=""/></td>')
                .append('<td><button type="button" class="remove" onClick="removeForm(' + count + ')">Remove</button></td>')
                .insertBefore("#subformanker");        
          console.log(count);
          count += 1;
        });      
      });

    </script>
</body>
</html>