5
votes

I am following given link to submit table data to be saved in database

http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/

But the difference between given link and my implementation is that the front-end of link uses JSTL (JSP) while i am using Thymeleaf (HTML)

Below are the files being used

HTML Form :

<form method="POST" th:action="@{/updateAllRules}" th:field="${ruleForm}">
<table>
<thead>
<tr>
    <th>S No</th>
    <th>Title</th>
    <th>Body</th>
</tr>
</thead>
<tbody>
<tr th:each="ruleModel,iteration : ${allRules}">
    <td th:text="${ruleModel.id}"></td>
    <td><input type="text" th:name="${'rule'+iteration.index+'.title'}" th:value="${ruleModel.title}"></td>
    <td><input type="text" th:name="${'rule'+iteration.index+'.body'}" th:value="${ruleModel.body}"></td>
</tr>
</tbody>
</table>
<br>
<input type="submit" value="Update All">
</form>

Model Class :

public class Rule  {
  private Integer id;   
  private Date timestamp;   
  private String title; 
  private String body;  
  // constructor and Getter/Setters
}

Form Class :

public class RuleForm { 
  private List<Rule> rule;
  public List<Rule> getRule() {
    return rule;
  }
  public void setRule(List<Rule> rule) {
    this.rule = rule;
  }
}

Controller Method :

@RequestMapping(value = "/updateAllRules", method = RequestMethod.POST)
public String updateAllRules(@ModelAttribute("ruleForm") RuleForm ruleForm) throws IOException
{
    System.out.println(ruleForm); // this prints com.web.model.RuleForm@235f9fcb
    System.out.println(ruleForm.getRule()); //this prints null
   return "redirect:/admin";
}

Please let me know what i am missing.

UPDATE 1:

Made changes as suggested. My new HTML form is as below

<form method="POST" th:action="@{/updateAllRules}" th:object="${ruleForm}">
<table>
<thead>
<tr>
    <th>S No</th>
    <th>Title</th>
    <th>Body</th>
</tr>
</thead>
<tbody>
<tr th:each="rule,iteration : ${ruleForm}">
    <td th:field="*{rule[__${iteration.index}__].id}"></td>
    <td><input type="text" th:field="*{rule[__${iteration.index}__].title}"></td>
    <td><input type="text" th:field="*{rule[__${iteration.index}__].body}"></td>
</tr>
</tbody>
</table>
<br>
<input type="submit" value="Update All">
</form>

On making these changes following exception is being received when the page loads.

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'rule' cannot be found on object of type 'java.util.ArrayList' - maybe not public?

Please see that i am sending original list in model attribute "ruleForm" on page load. Once page loads the data and user make changes , i want to POST complete table back to controller.

1
Got my answer, need to send data via wrapper as in given link stackoverflow.com/questions/36500731/…Sachin Goyal

1 Answers

3
votes

Forms should have a th:object, rather than a th:field:

<form method="POST" th:action="@{/updateAllRules}" th:object="${ruleForm}">

Instead of using th:name and th:value, you should instead be using th:field which does both of those for you. Fields also should be specified using the *{...} syntax, which assumes the th:object automatically.

<input type="text" th:field="*{rule[__${iteration.index}__].title}" />

Everything else looks correct to me.