Spring

MVC 모델 타임리프 폼 (체크 박스 / 셀렉 박스 / 라디오박스)

쭈녁 2024. 2. 2. 00:43

 

 

MVC 모델에서 특정 값을 받을 때 타임리프와 form 태그를 활용 하여 값을 받아올 수 있다.

 

아래 Entity의 예시에서 Boolean값과 enum타입, 특정 String 값을 유저가 직접 입력하는 것이 아닌 체크 박스 / 셀렉 박스 / 라디오박스 를 활용하여 받아오는 예시이다.

 

 

Item Entity

@Getter
@Setter
public class Item {

    private Long id;
    private String itemName;
    private Integer price;
    private Integer quantity;

    private Boolean open;
    private List<String> regions;
    private ItemType itemType;
    private String deliveryCode;
}

 

enum 타입 ItemType

public enum ItemType {

    BOOK("도서"), FOOD("음식"), ETC("기타");

    private final String description;

    ItemType(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

 

Controller

  • 메서드 상단에 @ModelAttribute 어노테이션을 통해 해당 컨트롤러 들어왔을때 model을 넣어줄 수 있다.
    • 컨트롤러에서 HashMap 형태의 객체를 "regions"라는 이름의 Model에 넣어 줌
    • DeliveryCode 객체를 생성하여 List에 담고 이를 Model에 넣어 줌
@Controller
@RequestMapping("/form/items")
@RequiredArgsConstructor
public class FormItemController {

    private final ItemRepository itemRepository;

    @ModelAttribute("regions")
    private Map<String, String> regions() {
        Map<String, String> regions = new LinkedHashMap<>();
        regions.put("SEOUL", "서울");
        regions.put("BUSAN", "부산");
        regions.put("JEJU", "제주");

        return regions;
    }
    
    @ModelAttribute("deliveryCodes")
    public List<DeliveryCode> deliveryCodes() {
        List<DeliveryCode> deliveryCodes = new ArrayList<>();
        deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송"));
        deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송"));
        deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송"));
        return deliveryCodes;
    }
    
    @GetMapping("/add")
    public String addForm(Model model) {
        model.addAttribute("item", new Item());
        return "form/addForm";
    }

    @PostMapping("/add")
    public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {

        Item savedItem = itemRepository.save(item);
        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/form/items/{itemId}";
    }
}

 

타임리프와 form 태그를 활용한 웹페이지 렌더링

  • 컨트롤러를 통해 받아온 Model을 기반으로 타임리프를 통하여 item 객체에 매핑함
    • 멀티 체크박스 ,라디오 박스 , 셀렉트 박스의 경우 받아온 컬렉션을 반복문을 통하여 렌더링함

 

<form action="item.html" th:action th:object="${item}" method="post">
<!--중략-->

<!--single checkbox-->
        <div>판매여부</div>
        <div>
            <div class="form-check">
                <input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
<!--                <input type="hidden" name="_open" value="on"/> &lt;!&ndash;히든 필드 추가&ndash;&gt;-->
                <label for="open" class="form-check-label">판매오픈</label>
            </div>
        </div>
        <!-- multi checkbox -->
        <div>
            <div>등록 지역</div>
            <div th:each="region : ${regions}" class="form-check form-check-inline">
                <input type="checkbox" th:field="*{regions}" th:value="${region.key}"
                       class="form-check-input">
                <label th:for="${#ids.prev('regions')}"
                       th:text="${region.value}" class="form-check-label">서울</label>
            </div>
        </div>

        <!-- radio button -->
        <div>
            <div>상품 종류</div>
            <div th:each="type : ${itemTypes}" class="form-check form-check-inline">
                <input type="radio" th:field="*{itemType}" th:value="${type.name()}"
                       class="form-check-input">
                <label th:for="${#ids.prev('itemType')}" th:text="${type.description}"
                       class="form-check-label">
                    BOOK
                </label>
            </div>
        </div>
        <!--SELECT-->
        <div>
            <div>배송방식</div>
            <select th:field="*{deliveryCode}" class="form-select">
                <option value="">==배송 방식 선택==</option>
                <option th:each="deliveryCode:${deliveryCodes}" th:value="${deliveryCode.code}"
                        th:text="${deliveryCode.displayName}">FAST</option>
            </select>
        </div>

 

실제 페이지 뷰

 

 

코드 출처 및 참고 자료

인프런 / 김영한 / 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard