英文:
Java Thymeleaf: Get data from one form into another and then use data from both on submit
问题
这是您提供的内容的翻译部分:
第一个表单(One.html)
<body>
<form action="#" th:action="@{\/}" th:object="${formOne}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{name}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name错误</td>
</tr>
<tr>
<td><button type="submit">提交</button></td>
</tr>
</table>
</form>
</body>
FormOne.class
public class FormOne {
@NotBlank
@Size(min=2, max=10)
private String name;
public FormOne() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "FormOne{" + "name=" + name + "}";
}
}
第二个表单("Two.html")
<body>
<form th:action="@{/name_age}" th:object="${formTwo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:value="${formOne.name}" /></td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" th:field="*{age}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age错误</td>
</tr>
<tr>
<td><button type="submit">提交</button></td>
</tr>
</table>
</form>
</body>
FormTwo.class
public class FormTwo {
private String name;
@NotNull
@Min(10)
private Integer age;
public FormTwo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "FormTwo{" + "name=" + name + ", age=" + age + "}";
}
}
AppController.class
@Controller
public class AppController {
@GetMapping("/")
public String showStart(FormOne formOne) {
return "One";
}
@PostMapping("/")
public ModelAndView checkStartInfo(@Valid FormOne formOne, BindingResult bindingResult) {
System.out.println("==Inside checkStartInfo() - " + formOne.toString());
ModelAndView mav = new ModelAndView();
if (bindingResult.hasErrors()) {
mav.setViewName("One");
return mav;
}
mav.setViewName("Two");
mav.addObject("formOne", formOne);
return mav;
}
@PostMapping("name_age")
public String setName_Age(@Valid FormTwo formTwo, BindingResult bindingResult) {
System.out.println("==Inside setName_Age() - " + formTwo.toString());
if (bindingResult.hasErrors()) {
return "Two";
}
return "Result";
}
}
以上是您提供内容的翻译部分。如有需要,您可以继续问我问题。
英文:
I am using Spring Boot with Thymeleaf. I want to get the value from the first form, display it on the second form where I get extra data and then, when the submit button on the 2nd form is pressed, have both values display in a result Page.
- When trying to add validation to "Age" I get the following error:
Neither BindingResult nor plain target object for bean name 'formTwo' available as request attribute
- How can I get the name that I input on the first form to display on the second form?
Update - I think I have sorted Point 2. now by using th:attr and changing my Controller slightly. I have updated the code snippets to reflect my progress so far.
- How can I read both the Name (from form One but displayed on form Two) and Age (from form Two) to display in the results page?
This is what I have so far. What am I doing wrong?
The 1st form (One.html)
<body>
<form action="#" th:action="@{/}" th:object="${formOne}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{name}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
FormOne.class
public class FormOne {
@NotBlank
@Size (min=2, max=10)
private String name;
public FormOne() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "FormOne{" + "name=" + name + "}";
}
}
The 2nd form "Two.html"
<body>
<form th:action="@{/name_age}" th:object="${formTwo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th.value="*{name}" /></td>
</tr><tr>
<td>Age:</td>
<!-- This has been removed <td><input type="text" th:value="*{age}" /></td> -->
<td><input type="text" th:name="name" th:attr="value = ${formOne.name}" th.field="*{name}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
</tr><tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
FormTwo.class
public class FormTwo {
private String name;
@NotNull
@Min(10)
private Integer age;
public FormTwo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "FormTwo{" + "name=" + name + ", age=" + age + "}";
}
}
AppController.class
@Controller
public class AppController {
@GetMapping("/")
public String showStart(FormOne formOne) {
return "One";
}
@PostMapping("/")
// public String checkStartInfo(@Valid FormOne formOne, BindingResult bindingResult) {
public ModelAndView checkStartInfo(@Valid FormOne formOne, BindingResult bindingResult) {
System.out.println("==Inside checkStartInfo() - " + formOne.toString());
ModelAndView mav = new ModelAndView();
if (bindingResult.hasErrors()) {
mav.setViewName("One");
return mav;
// return "One";
}
mav.setViewName("Two");
mav.addObject("formOne", formOne);
return mav;
// return "Two";
}
@PostMapping("name_age")
public String setName_Age(@Valid FormTwo formTwo, BindingResult bindingResult) {
System.out.println("==Inside setName_Age() - " + formTwo.toString());
if (bindingResult.hasErrors()) {
return "Two";
}
return "Result";
}
}
答案1
得分: 0
我已找到一种使其工作的方法。如果有错误,请提供意见。我把它弄得很复杂。但以下是我让它工作的代码片段。
第一个表单(One.html) - 保持不变
FormOne.class - 保持不变
第二个表单(Two.html) - 如下所示:
<body>
<form action="#" th:action="@{/name_age}" th:object="${formTwo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:name="name" th:attr="value=${formTwo.name}" readonly/></td>
</tr><tr>
<td>Age:</td>
<td><input type="text" th:field="*{age}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
</tr><tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
FormTwo.class - 保持不变
AppController.class - 这是发生大部分更改的地方。
@Controller
public class AppController {
@GetMapping("/")
public String showFormOne(FormOne formOne) {
return "One";
}
@PostMapping("/")
public String checkFormOneInfo(@Valid FormOne formOne, BindingResult bindingResult, Model m) {
if (bindingResult.hasErrors()) {
return "One";
}
FormTwo ft = new FormTwo();
ft.setName(formOne.getName());
m.addAttribute("formTwo", ft);
return "Two";
}
@GetMapping("/name_age")
public String showFormTwo(FormTwo formTwo) {
return "Two";
}
@PostMapping("/name_age")
public String checkPersonInfo(@Valid FormTwo formTwo, BindingResult bindingResult, Model m) {
if (bindingResult.hasErrors()) {
return "Two";
}
m.addAttribute("bothForms", formTwo);
return "Result";
}
}
总之,我必须做以下几点:
- 在Controller中创建一个GetMapping,除了我之前已经有的PostMapping来显示第二个表单。我认为当提交按钮被按下以继续通过第一个表单上的checkFormOneInfo() POST映射时,将调用此映射。
- 我还必须创建一个新的FormTwo对象,并在其中设置从FormOne中捕获的值(这意味着我需要在FormTwo中持有这个变量的字段)。
我的Results.html在以下页面中得到解决:
Results.html
<body>
Congratulations! You Got here!
<p th:text="'Name: ' + ${bothForms.name} + '!'" />
<p th:text="'Age: ' + ${bothForms.age} + '!'" />
</body>
这对于我需要的功能是有效的。如果有专家有更好的方法,请告诉我。
希望能帮助将来的某人。
英文:
So I have found a way to get it to work. Comments if it is incorrect would be appreciated. I was making it really complicated. But below are my code snippets of how I got it to work.
The 1st form (One.html) - Remains unchanged
FormOne.class - Remains unchanged
The 2nd Form (Two.html) - Looks as follows:
<body>
<form action="#" th:action="@{/name_age}" th:object="${formTwo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:name="name" th:attr="value = ${formTwo.name}" readonly/></td>
</tr><tr>
<td>Age:</td>
<td><input type="text" th:field="*{age}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
</tr><tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
FormTwo.class - Remains unchanged
AppController.class - This is where MOST of the changes happened.
@Controller
public class AppController {
@GetMapping("/")
public String showFormOne(FormOne formOne) {
return "One";
}
@PostMapping("/")
public String checkFormOneInfo(@Valid FormOne formOne, BindingResult bindingResult, Model m) {
if (bindingResult.hasErrors()) {
return "One";
}
FormTwo ft = new FormTwo();
ft.setName(formOne.getName());
m.addAttribute("formTwo", ft);
return "Two";
}
@GetMapping("/name_age")
public String showFormTwo(FormTwo formTwo) {
return "Two";
}
@PostMapping("/name_age")
public String checkPersonInfo(@Valid FormTwo formTwo, BindingResult bindingResult, Model m) {
if (bindingResult.hasErrors()) {
return "Two";
}
m.addAttribute("bothForms", formTwo);
return "Result";
}
}
In summary I had to do the following:
- Create a GetMapping in the Controller in addition to the PostMapping I previously had to display the 2nd form. I think this mapping is called when the submit button is pressed to continue past the checkFormOneInfo() POST mappong on the first form.
- I also had to create a new FormTwo object and set the value which was captured in FormOne in it (this meant i need a field to hold this variable in FormTwo).
My Results.html are addressed in the following page:
Results.html
<body>
Congratulations! You Got here!
<p th:text="'Name: ' + ${bothForms.name} + '!'" />
<p th:text="'Age: ' + ${bothForms.age} + '!'" />
</body>
This works for what I need it to do. I would be interested if any gurus had better ways of doing this.
Hope it helps someone in the future.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论