JaveDeveloper
JaveDeveloper

Reputation: 133

Pass multiple values from spring form jsp to spring controller on submit

I've a table which has multiple columns as in my database table. Few of the columns are editable and the values entered by the user should be updated back in the database on click of submit. For this Ive a foreach loop with value as HashMap of list of bean. Below is my foreach loop:

<c:forEach items="${feeType.value}" var="feeItem" varStatus="feeVar">                    
<td >[b]<form:checkbox disabled="true" class="editable${ifeeCount}" path="includeFeeValue" value="${feeVar.index}"/> [/b]</td>
<td >${feeItem.feetypeId} </td>
<td >${feeItem.feeValue} </td>
<td >[b]<form:input class="editable${ifeeCount}" disabled="true" path="${feeItem.overridenFee}" value="${feeItem.overridenFee}"/>[/b]</td>
    <td><form:errors path="overriddenFee" cssClass="error" /></td>
<td >${feeItem.lastUpdatedBy} </td>
<td >${feeItem.lastUpdatedDate} </td>

<td > ${feeItem.approvedBy}</td>
<td >${feeItem.approvalDate}</td>

<td align="left">[b]<form:input class="editable${ifeeCount}" disabled="true" path="feeComments[${feeVar.index}]"/>[/b]</td>
<td><form:errors path="feeComments" cssClass="error" /></td>

I'm iterating through a map called feeApprovalByFundId which is Map>. How do I get the updated values of the columns like checkbox, input box? I'm able to get in a String or String array but I won't know to which key was that mapped to. (Eg. Fund1 will have 10 fees - I will have under one hashmap key). I tried iterating like this :

Collection<List<MyBaseBean>> newList = paswFeeMaintForm.getFeeApprovalByFundId().values();
for(List<MyBaseBean> myList: newList){
for(MyBaseBean myBean : myList){
    System.out.println("Overriden fee : "+myBean.getOverridenFee());
}
}

Upvotes: 0

Views: 2044

Answers (1)

sh0rug0ru
sh0rug0ru

Reputation: 1626

The path in the form control binding is a string that represents a property binding expression. When the form is rendered, Spring knows what feeItem is due to the JSTL context in which the form control is being rendered. But on POST, that context is lost, so feeItem doesn't make sense.

Instead, given a form bean like this:

public class FormBean {
    private Map<Integer, ChildBean> children = new HashMap<>();

    public Map<Integer, ChildBean> getChildren() { return children; }   
}

public class ChildBean {
    private String name;
    private String age;
}

And a controller like this:

@ModelAttribute("formBean")
public FormBean createFormBean() {
    FormBean bean = new FormBean();
    bean.add(new ChildBean("Joe", 5));
    bean.add(new Childbean("Sam", 10));
}

@RequestMapping(...)
public String post(@ModelAttribute("formBean") FormBean formBean) { ... }

@RequestMapping(...)
public String get(@ModelAttribute("formBean") FormBean formBean) { ... }

In the view you would do this:

<form:form modelAttribute="formBean">
    <c:forEach items="${formBean.children}" varStatus="s">
        <form:input path="children[${s.index}].name" />
        <form:input path="children[${s.index}].age" />
    </c:forEach>
</form:form>

The rendered form elements would look something like:

<input type="text" name="children[0].name" />
<input type="text" name="children[0].age" />
<input type="text" name="children[1].name" />
<input type="text" name="children[1].age" />

Note that this is the standard indexed property syntax. Now, on the server side, there is enough context to determine which item in the collection should be modified.

For a map, the following no longer applies:

Also note that you don't have to return a list, but can specify the bean method to take an index and a single item, allowing you to define sparse collections (if you haven't constructed the collection ahead of time).

Upvotes: 1

Related Questions