# Thymeleaf - ์Šคํ”„๋ง ํ†ตํ•ฉ ๊ธฐ๋Šฅ
Study Repository

Thymeleaf - ์Šคํ”„๋ง ํ†ตํ•ฉ ๊ธฐ๋Šฅ

by rlaehddnd0422

ํƒ€์ž„๋ฆฌํ”„๋Š” ์•ž์„œ ๋‹ค๋ฃฌ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ ์™ธ์— ์Šคํ”„๋ง๊ณผ ํ†ตํ•ฉํ•ด์„œ ๋™์ž‘ํ•˜๋Š” ์ถ”๊ฐ€์ ์ธ ์Šคํ”„๋ง ํ†ตํ•ฉ ๋ฉ”๋‰ด์–ผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

Tutorial: Thymeleaf + Spring

Preface This tutorial explains how Thymeleaf can be integrated with the Spring Framework, especially (but not only) Spring MVC. Note that Thymeleaf has integrations for both versions 3.x and 4.x of the Spring Framework, provided by two separate libraries c

www.thymeleaf.org

์ถ”๊ฐ€ ์Šคํ”„๋ง ํ†ตํ•ฉ ๊ธฐ๋Šฅ

  • ์Šคํ”„๋ง์˜ SpringEL ๋ฌธ๋ฒ• ํ†ตํ•ฉ
    • ex) {@myBean.doSomething()}์ฒ˜๋Ÿผ ์Šคํ”„๋ง ๋นˆ ํ˜ธ์ถœ ์ง€์›
  • ํŽธ๋ฆฌํ•œ ํผ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ถ”๊ฐ€ ์†์„ฑ
    • th:object(๊ธฐ๋Šฅ ๊ฐ•ํ™”, ํผ ์ปค๋งจ๋“œ ๊ฐ์ฒด ์„ ํƒ)
    • th:field, th:errors, th:errorclass
  • ํผ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋Šฅ
    • checkbox, radio button, Select box(List) ๋“ฑ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ ์ง€์›
  • ์Šคํ”„๋ง์˜ ๋ฉ”์‹œ์ง€, ๊ตญ์ œํ™” ๊ธฐ๋Šฅ์˜ ํŽธ๋ฆฌํ•œ ํ†ตํ•ฉ
  • ์Šคํ”„๋ง์˜ ๊ฒ€์ฆ, ์˜ค๋ฅ˜์ฒ˜๋ฆฌ ํ†ตํ•ฉ
  • ์Šคํ”„๋ง์˜ ๋ณ€ํ™˜ ์„œ๋น„์Šค ํ†ตํ•ฉ

์ง€๊ธˆ๋ถ€ํ„ฐ ์ด ์ „์˜ ์ƒํ’ˆ๊ด€๋ฆฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด์„œ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 


์ž…๋ ฅ ํผ ์ฒ˜๋ฆฌ

  • th:object ๋Š” ์ปค๋งจ๋“œ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. 
    • th:object๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ์˜ค๋ธŒ์ ํŠธ ์ •๋ณด๋ฅผ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ชจ๋ธ์— ๋‹ด์•„์„œ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • th:object๋กœ ์ง€์ •๋œ ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ *{...}๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • th:field - HTML ํƒœ๊ทธ์˜ id, name, value ์†์„ฑ์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค.
    • HTML์—์„œ id๋Š” ๊ณ ์œ ํ•œ ์‹๋ณ„์„ ๋ชฉ์ ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํŽ˜์ด์ง€์—์„œ ํ•˜๋‚˜์˜ ์š”์†Œ๋งŒ ์ง€์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • name์€ form ์ปจํŠธ๋กค ์š”์†Œ์˜ ๊ฐ’(value)๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ  ๋‹ค์ค‘ ์„ค์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • value๋Š” ํผ ์ปจํŠธ๋กค ์š”์†Œ์˜ ๊ฐ’์œผ๋กœ name=value๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

https://okky.kr/questions/645583

 

OKKY - HTML์—์„œ Value, Name์˜ ์ฐจ์ด๊ฐ€ ๋ญ”๊ฐ€์š”..???

์ด๋Ÿฐ์‹์œผ๋กœ ๋นˆ์นธ๊ณผ ์ „์†ก๋ฒ„ํŠผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ž–์•„์š”.๊ถ๊ธˆํ•œ๊ฒŒ value์™€ name์˜ ์ฐจ์ด๋Š” ๋ญ”๊ฐ€์š”?? <input type="submit" value="Submit" /><input type="text" name="firstName" />

okky.kr

https://velog.io/@dongeranguk/input-%ED%83%9C%EA%B7%B8-id%EC%99%80-name%EC%9D%98-%EC%B0%A8%EC%9D%B4

 

input ํƒœ๊ทธ id์™€ name์˜ ์ฐจ์ด

document.all.id.valueid.valuedocument.getElementById("ํผ id").valueid ์†์„ฑ์€ page ์•ˆ์—์„œ ์ค‘๋ณต์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ์ฃผ๋กœ JavaScript์—์„œ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ์ง€์ •ํ•œ๋‹ค.name ์†์„ฑ์œผ๋กœ๋„ JavaScript๋ฅผ ํ†ต

velog.io

 

๋“ฑ๋ก ํผ

ํ†ตํ•ฉ ์ปจํŠธ๋กค๋Ÿฌ 

@GetMapping("/add")
public String addForm(Model model) {
    model.addAttribute("item",new Item());
    return "form/addForm";
}

 addForm์—์„œ th:object๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋ธ์— ๋‹ด์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. 

addForm.html(์ˆ˜์ • ์ „) 

<form action="item.html" th:action method="post">
    <div>
        <label for="itemName">์ƒํ’ˆ๋ช…</label>
        <input type="text" id="itemName" name="itemName" class="form-control" placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”"> </div>
    <div>
        <label for="price">๊ฐ€๊ฒฉ</label>
        <input type="text" id="price" name="price" class="form-control" placeholder="๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”">
    </div>

    <div>
        <label for="quantity">์ˆ˜๋Ÿ‰</label>
        <input type="text" id="quantity" name="quantity" class="form-control" placeholder="์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”">
    </div>

addForm.html (์ˆ˜์ • ํ›„)

<form action="item.html" th:action th:object="${item}" method="post">
    <div>
        <label>์ƒํ’ˆ๋ช…</label>
        <input type="text"  th:field="*{itemName}" class="form-control" placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”">
    </div>
    <div>
        <label>๊ฐ€๊ฒฉ</label>
        <input type="text"  th:field="*{price}" class="form-control" placeholder="๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”">
    </div>
    <div>
        <label>์ˆ˜๋Ÿ‰</label>
        <input type="text"  th:field = "*{quantity}" class="form-control" placeholder="์ˆ˜๋Ÿ‰์„ ์ž…๋ ฅํ•˜์„ธ์š”">
    </div>
  • th:object="${item}" : <form> ์—์„œ ์‚ฌ์šฉํ•  ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์„ ํƒ ๋ณ€์ˆ˜ ์‹ *{...}์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • th:field="*{itemName}"
    • ์ด์ œ <form>ํƒœ๊ทธ ๋‚ด์—์„œ object๋ฅผ item์œผ๋กœ ์ง€์ •ํ•œ ๋•๋ถ„์— item๊ฐ์ฒด์— ๋Œ€ํ•œ ์„ ํƒ๋ณ€์ˆ˜ ์‹์„ *{...}์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • th:field๋Š” id, name, value ์†์„ฑ์„ ๋ชจ๋‘ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. 
      • th:field="*{itemName}" โ–ถ๏ธŽ id="itemName", name="itemName", value="" (value๋Š” th:field์—์„œ ์ง€์ •ํ•œ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋“ฑ๋ก ํผ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง€์ •๋˜์ง€ ์•Š์€ ์ƒํƒœ )

 

th:object, th:field ๋•๋ถ„์— ํผ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ์กฐ๊ธˆ ํŽธ๋ฆฌํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค th:object, th:field์˜ ์žฅ์ ์€ ๊ฒ€์ฆ ๋‹จ๊ณ„์—์„œ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. 

ํผ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ๋œ ๋ถ€๋ถ„์€๊ฒ€์ฆ ๋‹จ๊ณ„์—์„œ ๋” ๊นŠ๊ฒŒ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


์š”๊ตฌ์‚ฌํ•ญ ์ถ”๊ฐ€ for Checkbox, RadioButton, SelectBox

์ด์ œ ํƒ€์ž„๋ฆฌํ”„๋ฅผ ์‚ฌ์šฉํ•ด ํผ์—์„œ ์ฒดํฌ๋ฐ•์Šค, ๋ผ๋””์˜ค๋ฒ„ํŠผ, ์…€๋ ‰ํŠธ ๋ฐ•์Šค๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์ƒํ’ˆ ๊ด€๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ํŒ๋งค ์—ฌ๋ถ€ - Check box

2. ๋“ฑ๋ก ์ง€์—ญ - Check box(๋‹ค์ค‘ ์„ ํƒ)

3. ์ƒํ’ˆ ์ข…๋ฅ˜ - Radio button(๋‹ค์ค‘ ์ผํƒ)

4. ๋ฐฐ์†ก ๋ฐฉ์‹ - Select box(๋‹ค์ค‘ ์ผํƒ)

์˜ˆ์‹œ ์ด๋ฏธ์ง€

์šฐ์„  Item ํด๋ž˜์Šค์— ์ถ”๊ฐ€ ์š”์†Œ๋ฅผ ๋„ฃ์–ด์ฃผ์–ด์•ผ๊ฒ ์ฃ  

@Data
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; // ๋ฐฐ์†ก ๋ฐฉ์‹ ( ๋น ๋ฆ„, ์ผ๋ฐ˜, ๋Š๋ฆผ )

 

์ƒํ’ˆ ์ข…๋ฅ˜ ItemType์€ enum์œผ๋กœ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

public enum ItemType {
    BOOK("๋„์„œ"), FOOD("์‹ํ’ˆ"), ETC("๊ธฐํƒ€");

    private final String description;

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

    public String getDescription() {
        return description;
    }
}

 

๋ฐฐ์†ก ๋ฐฉ์‹ Delivery๋ผ๋Š” ํด๋ž˜์Šค ์‚ฌ์šฉ

code - FAST๊ฐ™์€ ์‹œ์Šคํ…œ์— ์ „๋‹ฌํ•˜๋Š” ๊ฐ’

displayName - "๋น ๋ฅธ ๋ฐฐ์†ก"๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ์— ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ’

/**
 * FAST : ๋น ๋ฅธ๋ฐฐ์†ก
 * NORMAL : ์ผ๋ฐ˜ ๋ฐฐ์†ก
 * SLOW : ๋Š๋ฆฐ ๋ฐฐ์†ก
 */
@Data
@AllArgsConstructor
public class DeliveryCode {
    private String code;
    private String displayName;
}

ํŒ๋งค ์—ฌ๋ถ€ - Check box

addForm์˜ <form>ํƒœ๊ทธ ์•„๋ž˜์— ์ถ”๊ฐ€

<hr class="my-4">
    <!-- single checkbox -->
    <div>ํŒ๋งค ์—ฌ๋ถ€</div>
    <div>
        <div class="form-check">
            <input type="checkbox" id="open" name="open" class="form-check-input">
            <label class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
        </div>
    </div>

 

 

์ปจํŠธ๋กค๋Ÿฌ์— ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ์„œ POST๋กœ ์ž˜ ๋„˜์–ด์˜ค๋Š”์ง€ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Controller - @Slf4j ์ถ”๊ฐ€

@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {
    log.info("item.open = {}",item.getOpen());
    Item savedItem = itemRepository.save(item);
    redirectAttributes.addAttribute("itemId", savedItem.getId());
    redirectAttributes.addAttribute("status", true);
    return "redirect:/form/items/{itemId}";
}

check box - checkํ•œ ๊ฒฝ์šฐ / checkํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
log

HTML checkbox๋Š” ์„ ํƒ์ด ์•ˆ๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๊ฐ’ ์ž์ฒด๋ฅผ ๋ณด๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ˆ˜์ •์˜ ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์˜๋„์ ์œผ๋กœ ์ฒดํฌ๋˜์–ด ์žˆ๋˜ ๊ฐ’์„ ํ•ด์ œํ•ด๋„ ์ €์žฅ ์‹œ ์•„๋ฌด ๊ฐ’๋„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„ ๊ตฌํ˜„์— ๋”ฐ๋ผ์„œ ๊ฐ’์ด ์˜ค์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•ด์„œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Solution 1

ํžˆ๋“  ํ•„๋“œ๋ผ๋Š” ๊ฒƒ์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด _open ์ฒ˜๋Ÿผ ๊ธฐ์กด ์ฒดํฌ ๋ฐ•์Šค ์ด๋ฆ„ ์•ž์— ์–ธ๋”์Šค์ฝ”์–ด๋ฅผ ๋ถ™์—ฌ์„œ ์ „์†กํ•˜๋ฉด ์ฒดํฌ๋ฅผ ํ•ด์ œํ–ˆ๋‹ค๊ณ  ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<hr class="my-4">

    <!-- single checkbox -->
    <div>ํŒ๋งค ์—ฌ๋ถ€</div>
    <div>
        <div class="form-check">
            <input type="checkbox" id="open" name="open" class="form-check-input">
            <input type="hidden" name="_open" value="on"/> <!-- ํžˆ๋“  ํ•„๋“œ ์ถ”๊ฐ€ -->
            <label class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
        </div>
    </div>

ํžˆ๋“  ํ•„๋“œ๋Š” ํ•ญ์ƒ ์ „์†กํ•˜๊ธฐ ๋•Œ๋ฌธ์— checkbox๊ฐ€ check ๋˜์ง€ ์•Š์œผ๋ฉด ํžˆ๋“  ํ•„๋“œ์—์„œ _open์ด on์œผ๋กœ ์„ค์ •๋˜์–ด ์„œ๋ฒ„์—์„œ๋Š”

  • check ํ–ˆ์„ ๊ฒฝ์šฐ : open=on&_open=on์ด ์„œ๋ฒ„๋กœ ์ „์†ก
  • check ์•ˆํ–ˆ์„ ๊ฒฝ์šฐ : _open=on๋งŒ ์„œ๋ฒ„๋กœ ์ „์†ก

์ฒดํฌ ์—ฌ๋ถ€๋ฅผ ์„œ๋ฒ„์—์„œ ๋‘ ๊ฐ’์ด ๋„˜์–ด์™”๋Š”์ง€ ํ•˜๋‚˜๋งŒ ๋„˜์–ด์™”๋Š”์ง€์˜ ์—ฌ๋ถ€๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ํ•„๋“œ๋ฅผ ํ•ญ์ƒ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์ข€ ๋ฒˆ๊ฑฐ๋กœ์šด ์ผ์ž…๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํผ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฐ ๋ถ€๋ถ„์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Solution 2

์ฒดํฌ ๋ฐ•์Šค์˜ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ฒดํฌ ๋ฐ•์Šค ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ํžˆ๋“  ํ•„๋“œ์™€ ๊ด€๋ จ๋œ ๋ถ€๋ถ„๋„ ํ•จ๊ป˜ ํ•ด๊ฒฐํ•ด ์ค๋‹ˆ๋‹ค.

<hr class="my-4">
    <!-- single checkbox -->
    <div>ํŒ๋งค ์—ฌ๋ถ€</div>
    <div>
        <div class="form-check">
            <input type="checkbox" id="open" th:field = "*{open}" class="form-check-input">
            <label class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
        </div>
    </div>

check๋ฐ•์Šค check ์ „ / check ํ›„ 

 

์ด์ œ ์ƒํ’ˆ ์ƒ์„ธ ํผ๊ณผ ์ˆ˜์ • ํผ์—๋„ ์ ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ˆ˜์ • ํผ ์ˆ˜์ •

@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @ModelAttribute Item item) {
    log.info("item.open = {}",item.getOpen());
    itemRepository.update(itemId, item);
    return "redirect:/form/items/{itemId}";
}

update ๋ฉ”์†Œ๋“œ์— ์ถ”๊ฐ€

public void update(Long itemId, Item updateParam) {
    Item findItem = findById(itemId);
    findItem.setItemName(updateParam.getItemName());
    findItem.setPrice(updateParam.getPrice());
    findItem.setQuantity(updateParam.getQuantity());
    findItem.setOpen(updateParam.getOpen());
    findItem.setItemType(updateParam.getItemType());
    findItem.setDeliveryCode(updateParam.getDeliveryCode());
    findItem.setRegions(updateParam.getRegions());

}

 

์ˆ˜์ • ํผ์— ์ถ”๊ฐ€

<!-- single checkbox -->
<div>ํŒ๋งค ์—ฌ๋ถ€</div>
<div>
    <div class="form-check">
        <input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
            <label for="open" class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
    </div>
</div>

์ƒ์„ธ ํผ์— ์ถ”๊ฐ€ 

item์— ์ถ”๊ฐ€

<hr class="my-4">
<!-- single checkbox -->
<div>ํŒ๋งค ์—ฌ๋ถ€</div> <div>
<div class="form-check">
        <input type="checkbox" id="open" th:field="${item.open}" class="form-check-input" disabled>
        <label for="open" class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
    </div>
</div>

์ฃผ์˜ / item์—์„œ๋Š” th:object๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— th:field ๋ถ€๋ถ„์— ${item.open}์œผ๋กœ ์ ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ disabled ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์„œ ์ƒํ’ˆ ์ƒ์„ธ์—์„œ๋Š” ์ฒดํฌ ๋ฐ•์Šค๊ฐ€ ์„ ํƒ๋˜์ง€ ์•Š๋„๋ก ์„ค์ •.

 

ํƒ€์ž„๋ฆฌํ”„์˜ ์ฒดํฌ ํ™•์ธ

checked="checked"

์ฒดํฌ ๋ฐ•์Šค์—์„œ ํŒ๋งค ์—ฌ๋ถ€๋ฅผ ์„ ํƒํ•ด์„œ ์ €์žฅํ•˜๋ฉด, ์กฐํšŒ์‹œ์— checked ์†์„ฑ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋Ÿฐ ๋ถ€๋ถ„์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ์ƒ๋‹นํžˆ ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค. ํƒ€์ž„๋ฆฌํ”„์˜ th:field ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฐ’์ด true ์ธ ๊ฒฝ์šฐ ์ฒดํฌ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค.

๋“ฑ๋ก ์ง€์—ญ - Check Box ๋‹ค์ค‘ ์„ ํƒ

์ด๋ฒˆ์—๋Š” ์ฒดํฌ๋ฐ•์Šค๋ฅผ ๋ฉ€ํ‹ฐ๋กœ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋‚˜ ์ด์ƒ์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋“ฑ๋ก ์ง€์—ญ : ์„œ์šธ , ์ „์ฃผ , ์•ˆ๋™์œผ๋กœ ์ฒดํฌ ๋ฐ•์Šค๋กœ ๋‹ค์ค‘ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋“ฑ๋ก ํผ, ์ˆ˜์ • ํผ, ์ƒ์„ธ ํ™”๋ฉด์—์„œ ๋ชจ๋‘ ์„œ์šธ, ์ „์ฃผ, ์•ˆ๋™์ด๋ผ๋Š” ์ฒดํฌ๋ฐ•์Šค๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ๋ณด์—ฌ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด model.addAttribute()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฒดํฌ๋ฐ•์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ•˜๋Š”๋ฐ ์ข€ ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค.

 

@ModelAttribute๋Š” ์ปจํŠธ๋กค๋Ÿฌ์— ์žˆ๋Š” ๋ณ„๋„์˜ ๋ฉ”์†Œ๋“œ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

@ModelAttribute("regions")
public Map<String, String> regions()
{
    Map<String, String> regions = new LinkedHashMap<>();
    regions.put("SEOUL","์„œ์šธ");
    regions.put("JEONJU","์ „์ฃผ");
    regions.put("ANDONG","์•ˆ๋™");
    return regions;
}

์ด๋ ‡๊ฒŒ ์ปจํŠธ๋กค๋Ÿฌ์— ์„ค์ •ํ•ด์ฃผ๋ฉด Model์— ์ž๋™์œผ๋กœ "regions"๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋‹ด๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ฐ๊ฐ์˜ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์˜ ๋ชจ๋ธ์— ์ง์ ‘ ๋‹ด์•„์„œ ์ฒ˜๋ฆฌํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋Š”๊ฒŒ ๊น”๋”ํ•˜๋‹ˆ๊นŒ ์ด ๋ฐฉ์‹์œผ๋กœ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋“ฑ๋ก ํผ์— ์ถ”๊ฐ€

<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>
  • th:each ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ regions map์— ๋‹ด๊ธด ๊ฐ์ฒด๋“ค์„ ํ•˜๋‚˜์”ฉ ๋ฐ˜๋ณตํ•ด์„œ check box ํผ์œผ๋กœ ์ถœ๋ ฅํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • <input type> ์˜ th:field="*{regions}"์—์„œ regions๋Š” item ๊ฐ์ฒด์˜ ์„ ํƒ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.
  • th:value="${region.key}"์—์„œ region.key๋Š” SEOUL, JEONJU, ANDONG ์œผ๋กœ item์˜ ๋ณ€์ˆ˜ region์— ๋‹ด๊ธธ ๊ฐ’์ž…๋‹ˆ๋‹ค.
  • th:for="${#ids.prev('regions')}"
    • ๋ฉ€ํ‹ฐ ์ฒดํฌ๋ฐ•์Šค๋Š” ๊ฐ™์€ ์ด๋ฆ„์˜ ์—ฌ๋Ÿฌ ์ฒดํฌ๋ฐ•์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ฌธ์ œ๋Š” ์ด๋ ‡๊ฒŒ ๋ฐ˜๋ณตํ•ด์„œ HTMLํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ์ƒ์„ฑ๋œ HTMLํƒœ๊ทธ ์†์„ฑ์—์„œ name์€ ๊ฐ™์•„๋„ ๋˜์ง€๋งŒ id๋Š” ๊ณ ์œ  ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋‘ ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํƒ€์ž„๋ฆฌํ”„๋Š” ์ฒดํฌ๋ฐ•์Šค๋ฅผ each๋ฃจํ”„ ์•ˆ์—์„œ ๋ฐ˜๋ณตํ•ด์„œ ๋ง๋“ค ๋–„ ์ž„์˜๋กœ 1,2,3 ์ˆซ์ž๋ฅผ ๋’ค์— ๋ถ™์—ฌ์ค๋‹ˆ๋‹ค. 

 

addForm - POST ์ „ ๋ทฐํ…œํ”Œ๋ฆฟ ์†Œ์Šค์ฝ”๋“œ

  • hidden ํ•„๋“œ ์ž๋™ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ.
  • <label for="id๊ฐ’">์— ์ง€์ •๋œ id๊ฐ€ checkbox์—์„œ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ regions1, regions2, regions3 ์—๋งž์ถ”์–ด ์ˆœ์„œ๋Œ€๋กœ ์ž…๋ ฅ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

addForm - POST ํ›„ ๋ทฐํ…œํ”Œ๋ฆฟ ์†Œ์Šค์ฝ”๋“œ

  • check๋œ ๋ถ€๋ถ„์— check="checked" ์˜ต์…˜์ด ์ž๋™ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ.
  • <label for="id ๊ฐ’">์— ์ง€์ •๋œ id๊ฐ€ checkbox์—์„œ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ regions1, regions2, regions3 ์—๋งž์ถ”์–ด ์ˆœ์„œ๋Œ€๋กœ ์ž…๋ ฅ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ˆ˜์ • ํผ์— ์ถ”๊ฐ€

 

<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>๋“ฑ๋ก ์ง€์—ญ</div>
<div th:each="region : ${regions}" class = "form-check form-check-inline">
    <input type="checkbox" th:field="${item.regions}" th:value="${region.key}" class="form-check-input" disabled>
    <label th:for="${#ids.prev('regions')}"
           th:text="${region.value}" class="form-check-label">์„œ์šธ</label>
</div>

์ฃผ์˜ / item์—์„œ๋Š” th:object๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— th:field ๋ถ€๋ถ„์— ${item.regions}์œผ๋กœ ์ ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ disabled ์˜ต์…˜ ์ถ”๊ฐ€

 


์ƒํ’ˆ ์ข…๋ฅ˜ - radio button(๋‹ค์ค‘ 1ํƒ)

๋ผ๋””์˜ค ๋ฒ„ํŠผ์€ ์—ฌ๋Ÿฌ ์„ ํƒ์ง€ ์ค‘์— ํ•˜๋‚˜๋งŒ ์„ ํƒํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ModelAttribute("itemTypes")
public ItemType[] itemTypes()
{
    return ItemType.values();
}

๋“ฑ๋ก ํผ์— ์ถ”๊ฐ€

<!--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>

๋‹ค์ค‘ check box์™€ ๋™์ผํ•œ ๋ฐฉ์‹

 

์ˆ˜์ • ํผ์— ์ถ”๊ฐ€

<!--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>

 

์ƒ์„ธ ํผ์— ์ถ”๊ฐ€

<!--radio button -->
<div>
    <div>์ƒํ’ˆ ์ข…๋ฅ˜</div>
    <div th:each="type : ${itemTypes}" class="form-check form-check-inline">
        <input type="radio" th:field="${item.itemType}" th:value="${type.name()}" class="form-check-input" disabled>
        <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label">
            BOOK
        </label>
    </div>
</div>

์ฃผ์˜ / item์—์„œ๋Š” th:object๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— th:field ๋ถ€๋ถ„์— ${item.itemType}์œผ๋กœ ์ ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ disabled ์˜ต์…˜ ์ถ”๊ฐ€

 


๋ฐฐ์†ก ๋ฐฉ์‹ - select box(list)

์…€๋ ‰ํŠธ ๋ฐ•์Šค๋˜ํ•œ ์—ฌ๋Ÿฌ ์„ ํƒ์ง€ ์ค‘์— ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@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;
}
/**
 * FAST : ๋น ๋ฅธ๋ฐฐ์†ก
 * NORMAL : ์ผ๋ฐ˜ ๋ฐฐ์†ก
 * SLOW : ๋Š๋ฆฐ ๋ฐฐ์†ก
 */
@Data
@AllArgsConstructor
public class DeliveryCode {
    private String code;
    private String displayName;
}

์•ž์„œ ์ •์˜ํ•œ DeliveCode๋ผ๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ @ModelAttribute๋กœ ๋ฏธ๋ฆฌ ๋ชจ๋ธ์— ๋‹ด์•„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋“ฑ๋ก ํผ์— ์ถ”๊ฐ€

<!--select box-->
<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>

 

์ˆ˜์ • ํผ์— ์ถ”๊ฐ€

<!--select box-->
<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>

 

์ƒ์„ธ ํผ์— ์ถ”๊ฐ€

<!--select box-->
<div>
    <div>๋ฐฐ์†ก ๋ฐฉ์‹</div>
    <select th:field="${item.deliveryCode}" class="form-select" disabled>
        <option value="">== ๋ฐฐ์†ก ๋ฐฉ์‹ ์„ ํƒ ==</option>
        <option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
                th:text="${deliveryCode.displayName}">FAST
        </option>
    </select>
</div>

์ฃผ์˜ / item์—์„œ๋Š” th:object๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— th:field ๋ถ€๋ถ„์— ${item.DeliveryCode}์œผ๋กœ ์ ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ disabled ์˜ต์…˜ ์ถ”๊ฐ€

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ