01.Thymeleaf

Thymeleaf

๊ธฐ๋ณธ ๊ธฐ๋Šฅ

  • ์‚ฌ์šฉ ์„ ์–ธ

    <html xmlns:th="http://www.thymeleaf.org"></html>
  • ์†์„ฑ ๋ณ€๊ฒฝ

    th:href="@{/css/bootstrap.min.css}"
  • URL ๋งํฌ ํ‘œํ˜„์‹

    th:href="@{/css/bootstrap.min.css}"
    <!-- -->
    th:href="@{/basic/items/{itemId}(itemId=${item.id})}"
    th:href="@{/basic/items/{itemId}(itemId=${item.id}, query='test')}"
    th:href="@{|/basic/items/${item.id}|}"
  • ์†์„ฑ ๋ณ€๊ฒฝ

    th:onclick="|location.href='@{/basic/items/add}'|"
  • ๋ฐ˜๋ณต ์ถœ๋ ฅ

    <tr th:each="item : ${items}"></tr>
  • ๋ณ€์ˆ˜ ํ‘œํ˜„์‹

    <td th:text="${item.price}">10000</td>
  • ์†์„ฑ ๋ณ€๊ฒฝ

    <input
      type="text"
      id="price"
      name="price"
      value="10000"
      th:value="${item.price}"
    />

๊ธฐ๋ณธ ํ‘œํ˜„์‹

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#standard-expression-syntax

ใ…‡ ๊ฐ„๋‹จํ•œ ํ‘œํ˜„
  - ๋ณ€์ˆ˜ ํ‘œํ˜„์‹: ${...}
  - ์„ ํƒ ๋ณ€์ˆ˜ ํ‘œํ˜„์‹: \*{...}
  - ๋ฉ”์‹œ์ง€ ํ‘œํ˜„์‹: #{...}
  - ๋งํฌ URL ํ‘œํ˜„์‹: @{...}
  - ์กฐ๊ฐ ํ‘œํ˜„์‹: ~{...}

ใ…‡ ๋ฆฌํ„ฐ๋Ÿด
  - ํ…์ŠคํŠธ: 'one text', 'Another one!',โ€ฆ
  - ์ˆซ์ž: 0, 34, 3.0, 12.3,โ€ฆ
  - ๋ถˆ๋ฆฐ: true, false
  - ๋„: null
  - ๋ฆฌํ„ฐ๋Ÿด ํ† ํฐ: one, sometext, main,โ€ฆ

ใ…‡ ๋ฌธ์ž ์—ฐ์‚ฐ
  - ๋ฌธ์ž ํ•ฉ์น˜๊ธฐ: +
  - ๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด: |The name is ${name}|

ใ…‡ ์‚ฐ์ˆ  ์—ฐ์‚ฐ
  - Binary operators: +, -, \*, /, %
  - Minus sign (unary operator): -

ใ…‡ ๋ถˆ๋ฆฐ ์—ฐ์‚ฐ
  - Binary operators: and, or
  - Boolean negation (unary operator): !, not

ใ…‡ ๋น„๊ต์™€ ๋™๋“ฑ
  - ๋น„๊ต: >, <, >=, <= (gt, lt, ge, le)
  - ๋™๋“ฑ ์—ฐ์‚ฐ: ==, != (eq, ne)

ใ…‡ ์กฐ๊ฑด ์—ฐ์‚ฐ
  - If-then: (if) ? (then)
  - If-then-else: (if) ? (then) : (else)
  - Default: (value) ?: (defaultvalue)

ใ…‡ ํŠน๋ณ„ํ•œ ํ† ํฐ
  - No-Operation: \_

ํ…์ŠคํŠธ

  • ํ…์ŠคํŠธ ์ถœ๋ ฅ

    • ๊ธฐ๋ณธ์ ์œผ๋กœ escape ๋ฅผ ์ œ๊ณต

      • escape : HTML ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ˆ˜ ๋ฌธ์ž๋ฅผ HTML ์—”ํ‹ฐํ‹ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ

      • HTML ์—”ํ‹ฐํ‹ฐ : < ๋ฌธ์ž๋ฅผ ํƒœ๊ทธ์˜ ์‹œ์ž‘์ด ์•„๋‹Œ ๋ฌธ์ž๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•

    <ul>
      <li>th:text ์‚ฌ์šฉ = <span th:text="${data}"></span></li>
      <li>์ปจํ…์ธ  ์•ˆ์—์„œ ์ง์ ‘ ์ถœ๋ ฅํ•˜๊ธฐ = [[${data}]]</li>
    </ul>
  • Unescape

    • th:text --> th:utext

    • [[...]] --> [(...)]

    <ul>
      <li>th:utext = <span th:utext="${data}"></span></li>
      <li><span th:inline="none">[(...)] = </span>[(${data})]</li>
    </ul>

SpringEL ํ‘œํ˜„์‹

Object

  • ${user.username} = userA

  • ${user['username']} = userA

  • ${user.getUsername()} = userA

List

  • ${users[0].username} = userA

  • ${users[0]['username']} = userA

  • ${users[0].getUsername()} = userA

Map

  • ${userMap['userA'].username} = userA

  • ${userMap['userA']['username']} = userA

  • ${userMap['userA'].getUsername()} = userA

Safe Navigation Operator

<div th:if="${errors?.containsKey('globalError')}"></div>
  • errors?. ์€ errors ๊ฐ€ null ์ผ๋•Œ NullPointerException ๋Œ€์‹ , null ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฌธ๋ฒ• ์ฐธ๊ณ 

์ง€์—ญ๋ณ€์ˆ˜

<div th:with="first=${users[0]}">
  <p>first member name : <span th:text="${first.username}"></span></p>
</div>

๊ธฐ๋ณธ ๊ฐ์ฒด

Thymeleaf ๊ธฐ๋ณธ ๊ฐ์ฒด

  • ${#request}

  • ${#response}

  • ${#session}

  • ${#servletContext}

  • ${#locale}

ํŽธ์˜ ๊ฐ์ฒด

  • HTTP ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์ ‘๊ทผ: ${param.paramData}

  • HTTP ์„ธ์…˜ ์ ‘๊ทผ: ${session.sessionData}

  • ์Šคํ”„๋ง ๋นˆ ์ ‘๊ทผ: ${@helloBean.hello('Spring!')}

์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด์™€ ๋‚ ์งœ

  • #message : ๋ฉ”์‹œ์ง€, ๊ตญ์ œํ™” ์ฒ˜๋ฆฌ

  • #uris : URI ์ด์Šค์ผ€์ดํ”„ ์ง€์›

  • #dates : java.util.Date ์„œ์‹ ์ง€์›

  • #calendars : java.util.Calendar ์„œ์‹ ์ง€์›

  • #temporals : ์ž๋ฐ”8 ๋‚ ์งœ ์„œ์‹ ์ง€์›

  • #numbers : ์ˆซ์ž ์„œ์‹ ์ง€์›

  • #strings : ๋ฌธ์ž ๊ด€๋ จ ํŽธ์˜ ๊ธฐ๋Šฅ

  • #objects : ๊ฐ์ฒด ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต

  • #bools : boolean ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต

  • #arrays : ๋ฐฐ์—ด ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต

  • #lists , #sets , #maps : ์ปฌ๋ ‰์…˜ ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต

  • #ids : ์•„์ด๋”” ์ฒ˜๋ฆฌ ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต, ๋’ค์—์„œ ์„ค๋ช…

Reference

ํƒ€์ž„๋ฆฌํ”„ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด

์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด ์˜ˆ์‹œ

URL ๋งํฌ

  • ๋‹จ์ˆœ URL

    • /hello

      <a th:href="@{/hello}"></a>
  • query parameter

    • /hello?param1=data1&param2=data2

      <a th:href="@{/hello(param1=${param1}, param2=${param2})}"></a>
  • path variable

    • /hello/data1/data2

      <a
        th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}"
      ></a>
  • query parameter + path variable

    • /hello/data1?param2=data2

      <a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}"></a>

Reference

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls

๋ฆฌํ„ฐ๋Ÿด

  • ๋ฌธ์ž: 'hello' (๋ฌธ์ž ๋ฆฌํ„ฐ๋Ÿด์€ ํ•ญ์ƒ ์ž‘์€๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ์•ผ ํ•จ)

    <span th:text="'hello'"></span>
  • ์ˆซ์ž: 10

  • ๋ถˆ๋ฆฐ: true , false

  • null: null

์—ฐ์‚ฐ

  • ์‚ฐ์ˆ  ์—ฐ์‚ฐ

    10 + 2 = <span th:text="10 + 2"></span>
  • ๋น„๊ต ์—ฐ์‚ฐ

    <!-- 
      > (gt)
      < (lt)
      >= (ge)
      <= (le)
      ! (not)
      == (eq)
      != (neq, ne)`
    -->
    1 >= 10 = <span th:text="1 >= 10"></span>
  • ์กฐ๊ฑด์‹

    (10 % 2 == 0) ? = <span th:text="(10 % 2 == 0)?'์ง์ˆ˜':'ํ™€์ˆ˜'"></span>
  • Elvis ์—ฐ์‚ฐ์ž

    <!-- ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์„ค์ • ๋ฌธ์ž์—ด ์ถœ๋ ฅ -->
    ${data} = <span th:text="${data}?: '๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.'"></span>
  • No-Operation

    <!-- ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ tag ๋ฐ์ดํ„ฐ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ (Thymeleaf ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋™์ž‘) -->
    ${data} = <span th:text="${data}?: _">๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</span>

์†์„ฑ ๊ฐ’ ์„ค์ •

  • ์†์„ฑ ์„ค์ •

    <input type="text" name="mock" th:name="userA" />
  • ์†์„ฑ ์ถ”๊ฐ€

    <input type="text" class="text" th:classappend="large" /><br />
  • checked ์ฒ˜๋ฆฌ

    <input type="checkbox" name="active" th:checked="true" /><br />
    <input type="checkbox" name="active" th:checked="false" /><br />
    <input type="checkbox" name="active" th:checked="${isChecked}" /><br />

๋ฐ˜๋ณต

  • ๋ฐ˜๋ณต

    <tr th:each="user : ${users}">
      <td th:text="${user.username}">username</td>
      <td th:text="${user.age}">0</td>
    </tr>
  • ์ƒํƒœ ์œ ์ง€

    <!-- ์ƒ๋žต ์‹œ userStat ๋กœ ์‚ฌ์šฉ -->
    <tr th:each="user, state : ${users}"></tr>
    • index : 0๋ถ€ํ„ฐ ์‹œ์ž‘

    • count : 1๋ถ€ํ„ฐ ์‹œ์ž‘

    • size : ์ „์ฒด ์‚ฌ์ด์ฆˆ

    • even , odd : ํ™€/์ง์ˆ˜ ์—ฌ๋ถ€

    • first , last :์ฒ˜์Œ/๋งˆ์ง€๋ง‰ ์—ฌ๋ถ€

    • current : ํ˜„์žฌ ๊ฐ์ฒด

์กฐ๊ฑด๋ถ€ ํ‰๊ฐ€

  • if, unless

    <span th:text="'์–ด๋ฅธ'" th:if="${user.age gt 20}"></span>
    <span th:text="'์–ด๋ฅธ'" th:unless="${user.age le 20}"></span>
  • switch

    <td th:switch="${user.age}">
      <span th:case="10">10์‚ด</span>
      <span th:case="20">20์‚ด</span>
      <span th:case="*">๊ธฐํƒ€</span>
    </td>

์ฃผ์„

  • ํ‘œ์ค€ HTML ์ฃผ์„

    • ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ  ์œ ์ง€

    <!-- <span th:text="${data}"></span> -->
  • ํƒ€์ž„๋ฆฌํ”„ ํŒŒ์„œ ์ฃผ์„

    • ๋ Œ๋”๋ง์—์„œ ์ฃผ์„ ๋ถ€๋ถ„์„ ์ œ๊ฑฐ (ํƒ€์ž„๋ฆฌํ”„ ์ฃผ์„)

    <!--/* [[${data}]] */-->
    
    <!--/*-->
    <span th:text="${data}">html data</span>
    <!--*/-->
  • ํƒ€์ž„๋ฆฌํ”„ ํ”„๋กœํ† ํƒ€์ž… ์ฃผ์„

    • ํƒ€์ž„๋ฆฌํ”„ ๋ Œ๋”๋ง์„ ๊ฑฐ์ณ์•ผ๋งŒ ์ด ๋ถ€๋ถ„์ด ์ •์ƒ ๋ Œ๋”๋ง (HTML ์—์„œ๋งŒ ์ฃผ์„ ์ฒ˜๋ฆฌ)

    <!--/*/
    <span th:text="${data}">html data</span>
    /*/-->

๋ธ”๋ก

  • th:each ๋กœ ํ•ด๊ฒฐ์ด ์–ด๋ ค์šธ ๋•Œ ์‚ฌ์šฉ

<th:block th:each="user : ${users}">
  <div>
    name: <span th:text="${user.username}"></span> age:
    <span th:text="${user.age}"></span>
  </div>
  <div>์š”์•ฝ <span th:text="${user.username} + ' / ' + ${user.age}"></span></div>
</th:block>

JavaScript Inline

  • javascript inline

    <script th:inline="javascript">
      var username = [[${user.username}]];
      var age = [[${user.age}]];
      //์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์ถ”๋Ÿด ํ…œํ”Œ๋ฆฟ
      var username2 = /*[[${user.username}]]*/ "test username";
      //๊ฐ์ฒด
      var user = [[${user}]];
    </script>
    
    <!--
        var username = "userA";
        var age = 10;
        var username2 = "userA";
        var user = {"username":"userA","age":10};
    -->
  • each

    <script th:inline="javascript">
      [# th:each="user, stat : ${users}"]
      var user[[${stat.count}]] = [[${user}]];
      [/]
    </script>
    <!--
      var user1 = {"username":"userA","age":10};
      var user2 = {"username":"userB","age":20};
      var user3 = {"username":"userC","age":30};
    -->

ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ

  • /resources/templates/template/fragment/footer.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
      <body>
        <footer th:fragment="copy">ํ‘ธํ„ฐ ์ž๋ฆฌ ์ž…๋‹ˆ๋‹ค.</footer>
    
        <footer th:fragment="copyParam (param1, param2)">
          <p>ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋ฆฌ ์ž…๋‹ˆ๋‹ค.</p>
          <p th:text="${param1}"></p>
          <p th:text="${param2}"></p>
        </footer>
      </body>
    </html>
  • /resources/templates/template/fragment/fragmentMain.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
      <head>
        <meta charset="UTF-8" />
        <title>Title</title>
      </head>
      <body>
        <h1>๋ถ€๋ถ„ ํฌํ•จ</h1>
        <h2>๋ถ€๋ถ„ ํฌํ•จ insert (div tag ์•ˆ์— ์‚ฝ์ž…)</h2>
        <div th:insert="~{template/fragment/footer :: copy}"></div>
    
        <h2>๋ถ€๋ถ„ ํฌํ•จ replace (div tag ๋Œ€์ฒด)</h2>
        <div th:replace="~{template/fragment/footer :: copy}"></div>
    
        <h1>ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ</h1>
        <div
          th:replace="~{template/fragment/footer :: copyParam ('๋ฐ์ดํ„ฐ1', '๋ฐ์ดํ„ฐ2')}"
        ></div>
      </body>
    </html>

ํ…œํ”Œ๋ฆฟ ๋ ˆ์ด์•„์›ƒ

๋™์ ์ธ ๋ ˆ์ด์•„์›ƒ

  • /resources/templates/template/layout/base.html

    • ๋ ˆ์ด์•„์›ƒ์ด๋ผ๋Š” ํฐ ํ‹€

    <html xmlns:th="http://www.thymeleaf.org">
      <head th:fragment="common_header(title,links)">
        <title th:replace="${title}">๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€</title>
    
        <!-- ๊ณตํ†ต -->
        <link
          rel="stylesheet"
          type="text/css"
          media="all"
          th:href="@{/css/awesomeapp.css}"
        />
        <link rel="shortcut icon" th:href="@{/images/favicon.ico}" />
        <script
          type="text/javascript"
          th:src="@{/sh/scripts/codebase.js}"
        ></script>
    
        <!-- ์ถ”๊ฐ€ -->
        <th:block th:replace="${links}" />
      </head>
    </html>
  • /resources/templates/template/layout/layoutMain.html

    • ํ‹€ ์•ˆ์— ํ•„์š”ํ•œ ์ฝ”๋“œ ์กฐ๊ฐ๋“ค์„ ์ „๋‹ฌ

    • ::title ์€ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ title tag ๋“ค์„ ์ „๋‹ฌ

    • ::link ์€ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ link tag ๋“ค์„ ์ „๋‹ฌ

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
      <head
        th:replace="template/layout/base :: common_header(~{::title},~{::link})"
      >
        <title>๋ฉ”์ธ ํƒ€์ดํ‹€</title>
        <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
        <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}" />
      </head>
      <body>
        ๋ฉ”์ธ ์ปจํ…์ธ 
      </body>
    </html>

๋ฉ”์ธ ๋ ˆ์ด์•„์›ƒ

  • /resources/templates/template/layoutExtend/layoutFile.html

    • ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ(header, footer) ํ‹€์€ ์œ ์ง€ํ•˜๊ณ  title, content ๋งŒ ๋ณ€๊ฒฝ

    <!DOCTYPE html>
    <html
      th:fragment="layout (title, content)"
      xmlns:th="http://www.thymeleaf.org"
    >
      <head>
        <title th:replace="${title}">๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€</title>
      </head>
      <body>
        <h1>๋ ˆ์ด์•„์›ƒ H1</h1>
        <div th:replace="${content}">
          <p>๋ ˆ์ด์•„์›ƒ ์ปจํ…์ธ </p>
        </div>
        <footer>๋ ˆ์ด์•„์›ƒ ํ‘ธํ„ฐ</footer>
      </body>
    </html>
  • /resources/templates/template/layoutExtend/layoutExtendMain.html

    • ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ํ‹€๋กœ ๊ต์ฒดํ•˜๋Š”๋ฐ ํ•˜๋Š”๋ฐ title, content ๋Š” ์ „๋‹ฌ

    <!DOCTYPE html>
    <html
      th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title}, ~{::section})}"
      xmlns:th="http://www.thymeleaf.org"
    >
      <head>
        <title>๋ฉ”์ธ ํŽ˜์ด์ง€ ํƒ€์ดํ‹€</title>
      </head>
      <body>
        <section>
          <p>๋ฉ”์ธ ํŽ˜์ด์ง€ ์ปจํ…์ธ </p>
          <div>๋ฉ”์ธ ํŽ˜์ด์ง€ ํฌํ•จ ๋‚ด์šฉ</div>
        </section>
      </body>
    </html>

Form

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

<form action="item.html" th:action th:object="${item}" method="post">
  <div>
    <label for="itemName">์ƒํ’ˆ๋ช…</label>
    <input
      type="text"
      id="itemName"
      th:field="*{itemName}"
      class="formcontrol"
      placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”"
    />
  </div>
</form>
  • th:object : ์ปค๋งจ๋“œ ๊ฐ์ฒด๋ฅผ ์ง€์ •

  • \*{...} : ์„ ํƒ ๋ณ€์ˆ˜ ์‹ (th:object ์—์„œ ์„ ํƒํ•œ ๊ฐ์ฒด์— ์ ‘๊ทผ)

  • th:field : HTML ํƒœ๊ทธ์˜ id , name , value ์†์„ฑ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑ

  • ๋ Œ๋”๋ง ์ „/ํ›„

    <input type="text" th:field="*{itemName}" />
    <input type="text" id="itemName" name="itemName" th:value="*{itemName}" />

์ฒดํฌ ๋ฐ•์Šค

๋‹จ์ผ

Register

<div>
  <div class="form-check">
    <input
      type="checkbox"
      id="open"
      th:field="*{open}"
      class="form-checkinput"
    />
    <label for="open" class="form-check-label">ํŒ๋งค ์˜คํ”ˆ</label>
  </div>
</div>
  • ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ž๋™์œผ๋กœ <input type="hidden" name="_open" value="on"/> ์ƒ์„ฑ

    • ์ฒดํฌ ๋ฐ•์Šค๋ฅผ ์ฒดํฌํ•  ๊ฒฝ์šฐ on ์„ ์ „๋‹ฌํ•˜์ง€๋งŒ, ์ฒดํฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๊ฐ’ ์ž์ฒด๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š์Œ -> ์ด ๊ฒฝ์šฐ hidden type ์˜ _name input ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, false ๋กœ ๊ฐ’์„ ์ „๋‹ฌ (_open=on)

View

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

๋ฉ€ํ‹ฐ

(์ฐธ๊ณ ) @ModelAttribute ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น Controller ํ˜ธ์ถœ ์‹œ regions() ์—์„œ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์ด ์ž๋™์œผ๋กœ Model์— ํ•ญ์ƒ ๋‹ด๊ธฐ๊ฒŒ ๋จ

@ModelAttribute("regions")
public Map<String, String> regions() {
    Map<String, String> regions = new LinkedHashMap<>();
    regions.put("SEOUL", "์„œ์šธ");
    regions.put("BUSAN", "๋ถ€์‚ฐ");
    regions.put("JEJU", "์ œ์ฃผ");
    return regions;
}

Register

<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>
  • ํƒ€์ž„๋ฆฌํ”„๋Š” each๋กœ ์ฒดํฌ๋ฐ•์Šค ์ƒ์„ฑ ์‹œ ๋™์ ์œผ๋กœ id์— ์ˆœ๋ฒˆ์„ ๋งค๊ฒจ์ค€๋‹ค. #ids๋Š” ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ id๋ฅผ ์ธ์‹

  • result

    <input
      type="checkbox"
      value="SEOUL"
      class="form-check-input"
      id="regions1"
      name="regions"
    />
    <input
      type="checkbox"
      value="BUSAN"
      class="form-check-input"
      id="regions2"
      name="regions"
    />
    <input
      type="checkbox"
      value="JEJU"
      class="form-check-input"
      id="regions3"
      name="regions"
    />

View

<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>
  • ํƒ€์ž„๋ฆฌํ”„๋Š” th:field์— ์ง€์ •ํ•œ ๊ฐ’๊ณผ th:value์˜ ๊ฐ’์„ ๋น„๊ตํ•ด์„œ ์ฒดํฌ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ

๋ผ๋””์˜ค ๋ฒ„ํŠผ

public enum ItemType {

    BOOK("๋„์„œ"), FOOD("์‹ํ’ˆ"), ETC("๊ธฐํƒ€"); // NAME(description)

    private final String description;

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

    public String getDescription() {
        return description;
    }
}
<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>
  • ๋ผ๋””์˜ค ๋ฒ„ํŠผ์€ ํ•ญ์ƒ ํ•˜๋‚˜์˜ ๊ฐ’์ด ์„ ํƒ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ ํžˆ๋“  ๋ฒ„ํŠผ์„ ๋”ฐ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ.

์…€๋ ‰ํŠธ ๋ฐ•์Šค

Register

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

Reference

๊ณต์‹ ์‚ฌ์ดํŠธ

๊ณต์‹ ๋ฉ”๋‰ด์–ผ - ๊ธฐ๋ณธ ๊ธฐ๋Šฅ

๊ณต์‹ ๋ฉ”๋‰ด์–ผ - ์Šคํ”„๋ง ํ†ตํ•ฉ

Last updated