ykesh
ykesh

Reputation: 1209

Dynamic form with multiple objects submission in Spring?

I have an Object CreateProjectFormModel as follows (I am using Spring 4).

public class CreateProjectFormModel {
    private Project project;
    private List<DUser> users;

    public CreateProjectFormModel() {
        this.project = new Project();
        this.users = new ArrayList<DUser>();
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public List<DUser> getUsers() {
        return users;
    }

    public void setUsers(List<DUser> users) {
        this.users = users;
    }
}

I am not able to figure out how to create Controller and a corresponding form so that multiple DUser can be submitted at once - can do it if the object does not consist of a collection?

Read this, but I don't know how may users will be added to the project in advance, so cannot fix the users size.

I read through thymeleaf tutorial, but would be interested to know if can do without use of thymeleaf.

Thanks.

Upvotes: 2

Views: 7481

Answers (2)

sbsatter
sbsatter

Reputation: 581

Although the above answer works, here's an alternate that does not require you to create a wrapper class/ form class.

Model And Controller

public class Foo {
    private String name;
    private List<Foo> fooList;
    public Foo() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getFooList() {
        return fooList;
    }

    public void setFooList(String fooList) {
        this.fooList = fooList;
    }

}

@Controller("/")
public class FooController{

    //returns the ModelAttribute fooListWrapper with the view fooForm
    @RequestMapping(value = "/FOO", method = RequestMethod.GET)
    public String getFooForm(Model model) {
        List<Foo> fooList = service.getFooList();

        model.addAttribute("fooList", fooList);

        return "list_foo"; //name of the view
    }

    @RequestMapping(value = "/FOO", method = RequestMethod.POST)
    public String postFooList(@ModelAttribute("foo")Foo foo, Model model) {
        List<Foo> list = foo.getFooList(); // **This is your desired object. 
        //If you debug this code, you can easily find this is the list of  
        //all the foo objects that you wanted, provided you pass them properly. 
        //Check the jsp file to see one of the ways of passing such a list of objects**
        //Rest of the code
    }

}

JSP View

<form:form id="form" action="<paste-target-url-here>" method="POST" modelAttribute="fooList">


    <c:forEach items="${fooList}" varStatus="i">
           <form:input path="fooList[${i.index}].name" type="text"/>
           <!-- Here you are setting the data in the appropriate index which will be caught in the controller -->
    </c:forEach>


    <button>submit</button>
</form:form>

Upvotes: 1

Master Slave
Master Slave

Reputation: 28519

The link you posted in the question List<Foo> as form backing object using spring 3 mvc, correct syntax? should provide a solution for you, what is discussed in the comments

I assume that this solution requires having a fixed amount of input fields, is that correct? What if you have a dynamic number of input fields?

does not concern the number of users, which doesn't have to be fixed, rather it concerns the fact that that the properties of the object is differing, which I don't believe is your case. So, if your DUser has a property userName, and e.g. your Project has a property name. Your controller method could simply be,

@RequestMapping(value = "/test", method=RequestMethod.POST)
public String processSubmit(CreateProjectFormModel createProjectFormModel) {
       ...
}

and your form

<form:form action="/form/test" method="post">
    <div class="single">
        <input type="text" name="project.name"/>
        <input type="text" name="users[0].userName"/>
        <a href="#" onclick="addNewUserInputSection();return false">add another user</a>
        <input type="submit" value="Save">
    </div>
</form:form>

where you will have to provide some effort is to create a javascript function addNewUserInputSection that will add new set of input fields for the users property with an incremented index, e.g.

<form:form action="/form/test" method="post">
    <div class="single">
        <input type="text" name="project.name"/>
        <input type="text" name="users[0].userName"/>
        <input type="text" name="users[1].userName"/>
        <a href="#" onclick="addNewUserInputSection();return false">add another user</a>
        <input type="submit" value="Save">
    </div>
</form:form>

the examples are basic, but should be enough to have you resolve your issue

Upvotes: 2

Related Questions