[Spring] Implement the input form (input screen ⇒ confirmation screen ⇒ completion screen)

Introduction

Thing you want to do

--I want to do something based on the value entered by the user in the form. --I want to transition from the input screen ⇒ confirmation screen ⇒ completion screen.

People who find this article helpful

--People who implement the inquiry form. --A person who has a minimum knowledge of Java, Spring, Thymeleaf.

Technical elements used

Implementation

You may have a preference, but I think you should implement it by following the steps below. Only the minimum snippets will be posted.

input screen

HTML

input.html


<blc:form  th:action="@{/input}" method="POST" name="hogeForm" th:object="${hogeForm}">
	<p>Inquiry category</p>
	<select name="category" th:field="*{category}">
		<option value="">---</option>
		<option th:each="item : *{getCategoryList()}" th:value="${item.key}" th:text="${item.value}"/>
	</select>
	<p th:if="${#fields.hasErrors('category')}" th:errors="*{category}">Error message</p>

	<p>Inquiry</p>
	<textarea name="content" placeholder="Please enter your inquiry." th:field="*{content}"></textarea>
	<p th:if="${#fields.hasErrors('content')}" th:errors="*{content}">Error message</p>

	<input type="submit" value="Verification"/>
</blc:form>

Form object

HogeForm.java


@Getter
@Setter
public class HogeForm implements Serializable {
	@NotBlank(message="Please select")
	private String category;

	@NotBlank(message="Please enter something")
	@Length(max=1000)
	private String content;

	public Map<String, String> getCategoryList() {
	Map<String, String> categoryMap = new LinkedHashMap<String, String>();
        categoryMap.put("1", "Category 1");
        categoryMap.put("2", "Category 2");
        categoryMap.put("3", "Category 3");
        return categoryMap;
	}
}

point

--Use the same variable name for the property name and the name attribute of form. --Use getCategoryList () to keep the contents of the select box in Form. Use LinkedHashMap because you want to display them in order. The display method on the HTML side is as follows.

<option th:each="item : *{getCategoryList()}" th:value="${item.key}" th:text="${item.value}"/>

--When an error occurs in Validation --On the HTML side, # fields.hasErrors ('(property name)') becomes true. --If you specify @ (Validation type) (message =" ~~~ ") and message in the property, you can write th: errors =" * {(property name)} " on the HTML side. , The specified message can be displayed.

Controller

HogeController.java


@RequestMapping("/input")
public ModelAndView input(
		@ModelAttribute("hogeForm") HogeForm hogeContactForm,
		Model model, HttpServletRequest request) {

	return "index.html";
}

@RequestMapping(value = "/input", method = RequestMethod.POST)
public ModelAndView input(
		@Valid @ModelAttribute("hogeForm") HogeForm hogeForm,
		BindingResult bindingResult,
		Model model, HttpServletRequest request) {

	//If there is an error, it will transition to its own screen
	if (bindingResult.hasErrors()) {
		return "index.html";
	}

	HttpSession session = request.getSession();
	session.setAttribute("hogeForm", hogeForm);
	return "redirect:/confirm";
}

point

--Instead of making the POST destination of the form a confirmation screen (/ confirm), create a second input method for it. --Advantage: The / confirm method can concentrate on displaying the confirmation screen. --If you set the POST destination to / confirm, you will have to implement two processes, one for the input screen and one for the confirmation screen, in the confirm method. ――Since the above is a simple example, you can't feel the merit so much, but in actual business, the code is clean and nice.

confirmation screen

HTML

confirm.html


<blc:form  th:action="@{/complete}" method="POST" name="hogeForm" th:object="${hogeForm}">
	<p>Inquiry category</p>
	<p th:text="*{getCategoryList().get('__*{category}__')}">Category 1</p>

	<p>Inquiry</p>
	<p th:text="*{content}">Display the inquiry contents here</p>

	<div>
		<input type="hidden" name="category" th:value="*{category}" />
		<input type="hidden" name="content" th:value="*{content}" />
		<input type="submit" value="Send" />
	</div>
</blc:form>

point

--You can display the value of Map with * {getCategoryList (). Get ('__ * {category} __')}. Normally, if only * {category} is used, the key will be displayed.

Controller

HogeController.java


@RequestMapping("/confirm")
public ModelAndView confirm(
		Model model, HttpServletRequest request) {

	HttpSession session = request.getSession();
	HogeForm hogeForm = (HogeForm) session.getAttribute("hogeForm");
	model.addAttribute("hogeForm", hogeForm);
	return "confirm.html";
}

Completion screen

HTML

complete.html


<p>We accepted with the following contents.</p>

<p>Inquiry category</p>
<p th:text="*{getCategoryList().get('__*{category}__')}">Category 1</p>

<p>Inquiry</p>
<p th:text="*{content}">Display the inquiry contents here</p>
</blc:form>

Controller

HogeController.java


@RequestMapping("/complete")
public ModelAndView complete(
		@ModelAttribute("hogeForm") HogeForm hogeContactForm,
		Model model, HttpServletRequest request) {

	model.addAttribute("hogeForm", hogeForm);
	return "complete.html";
}

Impressions

I implemented the form for the first time in about two years, so it was a terrible implementation. ..

Recommended Posts

[Spring] Implement the input form (input screen ⇒ confirmation screen ⇒ completion screen)
[Rails] "Input"-> "Confirmation screen"-> "Save"-> "View"
Implement image input / output with Spring MVC
How to display the result of form input
Spring Boot Form