Thymeleaf 構文一覧

何番煎じって感じですけど、書きます。

##コメント
  HTMLファイル展開後、上のコメントは削除されるが、下は残る。

```html:test.html
  <!--/* Thymeleafコメントアウト */-->
  <!-- HTMLのコメントアウト -->
```

##値の出力

```html:test.html
   <p th:text="${form.text}"></p>  <!-- サニタイジングあり -->
   <p th:utext="${form.text}"></p> <!-- サニタイジングなし -->
```

## 文字列結合
```html:test.html
  <p th:text="'Test Strings' + ${form.text}"></p>
  <p th:text="|Test Strings ${form.text}|"></p>
```


## オブジェクト参照
オブジェクトのメンバへのアクセスを省略して記載できる。

```html:test.html
  <div th:object=${form}>
    <p th:text="*{text}"></p>
  </div>
```


## メッセージ出力

```html:test.html
   <p th:text=#{test.message1}></p> 
```

```messages.properties
   test.message1=This is Test Message
```

## 様々な演算子

```html:test.html
   <!--　 算術演算子 -->
   <p th:text="${form.text} + 5"> <!-- 25 -->
   <p th:text="${form.text} - 5"> <!-- 15 -->
   <p th:text="${form.text} * 5"> <!-- 100 -->
   <p th:text="${form.text} / 5"> <!-- 4 -->
   
   <!--　 比較演算子１-->
   <p th:text="${form.text} eq 20"> <!-- x =  20 : true-->
   <p th:text="${form.text} gt 20"> <!-- x >  20 : false-->
   <p th:text="${form.text} ge 20"> <!-- x >= 20 : true-->
   <p th:text="${form.text} lt 20"> <!-- x <  20 : false-->
   <p th:text="${form.text} le 20"> <!-- x <= 20 : true-->

   <!--　 比較演算子２-->
   <p th:text="${form.text} == 20">
   <p th:text="${form.text} >  20">
   <p th:text="${form.text} >= 20">
   <p th:text="${form.text} <  20">
   <p th:text="${form.text} <= 20">
   
   <!-- 論理演算子１--> 
   <p th:text="not ${form.text} == 20"></p> <!-- not true  : false -->
   <p th:text="not ${form.text} == 10"></p> <!-- not false : true -->
   
   <!-- 論理演算子２ -->
   <p th:text="! ${form.text} == 20"></p>    
   <p th:text="! ${form.text} == 10"></p>

   <!-- 条件演算子１ 三項演算子 -->
   <p th:text="${form.text} % 2 == 0 ? 'even' : 'odd' "></p>  <!-- even -->
   
   <!-- 条件演算子１ エルビス演算子(C#のNull条件演算子と同じ) -->
   <p th:text="${form.text} ?: 'default Name'"></p>           <!-- nullの場合default Name -->
```
## 定数と変数
・条件式を`${}`の中にまとめて書いてしまう場合，型によって結果が変わってしまうため，
　外だしするほうが無難。

```html:test.html
   <!-- 型がStringの場合 -->
   <p th:text="${testForm.text == 20}"> <!-- false -->
   <p th:text="${testForm.text} == 20"> <!-- true  -->

   <!-- 型がIntegerの場合 -->
   <p th:text="${testForm.text == 20}"> <!-- true -->
   <p th:text="${testForm.text} == 20"> <!-- true  -->
```
## 条件式

評価式で偽になる値
・null
・数値型の0
・文字列型のfalse, off, no

評価式で真になる値
・boolean型，数値型，文字列型以外が常に真

```html:test.html
  <!-- iF式 -->
  <div th:if="${form.text} == 20"> <!-- falseの場合，divタグとその中身が全部削除される。-->
    <span>True</span>               
  </div>

  <!-- else式 -->
  <div th:unless="${form.text} == 20"> <!-- trueの場合，divタグとその中身が全部削除される。-->
     <span>False</span>
  </div>

  <!-- case式 -->
  <div th:switch="${form.text}"><!--不一致になった場合,divタグとその中身が全部削除される。 -->
    <div th:case="10">
      <span>Value 1</span>
    </div>
    <div th:case="20">
      <span>Value 2</span>
    </div>
    <div th:case="*"><!-- default文-->
      <span>Value Other</span>
    </div>

  <!-- for文１ -->
  <tr th:each="form : ${formList}">
    <td th:text=${form.text}></td>
  </tr>

  <!-- for文２  th:objectの併用 -->
  <tr th:each="form : ${formList}" th:object=${form}>
    <td th:text=*{text}></td>
  </tr>
```


## for文でステータスを利用する。
```html:test.html
  <table>
    <tr>
      <th>値</th>
      <th>連番１</th>
      <th>連番2</th>
      <th>要素数</th>
      <th>オブジェクト参照値</th>
      <th>偶数か</th>
      <th>奇数か</th>
      <th>最初か</th>
      <th>最後か</th>
    </tr>
    <!-- 繰り返し -->
    <tr th:each="form, xxx : ${formList}" th:object=${form}>
      <td th:text=*{text}></td>
      <td th:text="${xxx.index}"></td>
      <td th:text="${xxx.count}"></td>
      <td th:text="${xxx.size}"></td>  
      <td th:text="${xxx.current}"></td>
      <td th:text="${xxx.even}"></td>
      <td th:text="${xxx.odd}"></td>
      <td th:text="${xxx.first}"></td>
      <td th:text="${xxx.last}"></td>
    </tr>
  </table>
```

|連番１|連番2|要素数|オブジェクト参照値|偶数か|奇数か|最初か|最後か|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|0|1|3|com.example.demo.app.form.TestForm@1a3d4e5|false|true|true|false|
|1|2|3|com.example.demo.app.form.TestForm@44a15ab5|true|false|false|false|
|2|3|3|com.example.demo.app.form.TestForm@6ab43eeb|false|true|false|true|

## フラグ属性の有無制御
属性値を省略できるタイプの属性の付加判定を行う。

```html:test.html
  <!-- th:checked (チェック有無の制御) -->
  <input type="checkbox" name="checkbox1" value="test" th:checked="${true}" />
  <input type="checkbox" name="checkbox2" value="test" th:checked="${false}" />
  
  <!-- th:readonly (読み取り専用の制御) -->  
  <input type="text" name="text1" value="test" th:readonly="${true}" />
  <input type="text" name="text2" value="test" th:readonly="${false}" />  
  
  <!-- th:selected (選択要素の制御) -->  
  <select name="selectbox1">
    <option th:each="form : ${formList}" th:value="*{text}" th:selected="*{text} == 20" th:object="${form}">
      [[*{text}]]
    </option>
  </select>
```

## インライン記述
HTMLタグ以外でもth属性の使用が可能になる。

```html:test.html
  <p>[[${form.text}]]</p>

  <div th:object="${form}">
    <p>[[*{text}]]</p>
  </div>  
```

## リンク設定
```html:test.html
  <!-- th:hrefの場合「@」を付ける。 -->
  <a href="/select" th:href="@{/select}">リンク</a>
```

## フォーム設定
### 初期表示
・th:objectはControllerでsetAttributeしたオブジェクト名を指定する。
・th:fieldを使用するとid, name, valueが一度に設定される。

```html:test.html(生成前)
  <form action="./output.html" th:action="@{/echo2/entry1}" th:object ="${testForm}" method="POST">
    <input type="text" th:field=*{text}>
    <button type="submit">登録</button>
  </form>
```

```html:test.html(生成後)
  <form action="/echo2/entry1" method="POST">
    <input type="text" id="text" name="text" value="20">
    <button type="submit">登録</button>
  </form>
```

### エラー表示
・`th:errorclass` : エラー時のみ設定されるクラス属性。テキストの枠を赤くしたりなどなど
・`fields.hasErros(フィールド名)` : エラーが発生したかどうか。
・`th:errors(フィールド名)` : エラーメッセージの表示。

```html:test.html
  <form action="./output.html" th:action="@{/echo/entry1}" th:object ="${testForm}" method="POST">
    <input type="text" name="text" th:field="*{text}" th:errorclass="fieldError"/> <br />
    <span th:if="${#fields.hasErrors('text')}"
          th:errors="*{text}">
    </span>
    <input type="submit" value="送信" />
```

```css:css

<style type="text/css">
.fieldError {
    border: 1px solid #FF0000;
}
</style>
```

http://tk5-21.hatenablog.com/entry/2017/09/01/003345



```java:errorcheck
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
	    Validator validator = factory.getValidator();

	 
	    Set<ConstraintViolation<TestForm>> result = validator.validate(form);  // チェック実行
        if (result.isEmpty()) {
        	System.out.println("エラーあり");
        	
        }

```

## ラジオボタン
```java:フォームクラス
  // 性別値 (M, F, Xのいずれかの値を取る。)
  private String sex;
```
```java:コントローラ

    // ラジオボタングループ
    private final static Map<String, String> RADIO_ITEMS
      = Collections.unmodifiableMap(
          new LinkedHashMap<String,String>(){
				  {
					  put("man","M");
					  put("women","F");
					  put("unknown","X");
			      }
		});
		

    // 初期表示
    @GetMapping
    public String show(@ModelAttribute TestForm form, Model model) {
        model.addAttribute("radioItems", RADIO_ITEMS);
        return "input";
    }

    // 登録
　　@PostMapping
    public String regist(@ModelAttribute @Valid TestForm echoForm, BindingResult result, Model model) {
        model.addAttribute("radioItems", RADIO_ITEMS);
        return "input";
    }
```

```html:input.html
  <form action="./output.html" th:action="@{/connect}" th:object ="${testForm}" method="POST">
      <label>ラジオボタン</label>
      <div class="radio" th:each="item : ${radioItems}">
          <input type="radio" th:value="${item.value}"                                
                              th:text="${item.key}"          
                              th:field="*{sex}" />                
      </div>
  </form>
```
 - `th:value` : フォームに保持する値
 - `th:text` : 画面に表示する値
 - `th:field` : フォームのフィールド名

```html:input.html(展開後)
      <label>ラジオボタン</label>
      <div class="radio">
        <input type="radio" name="sex" value="男" id="sex1" >man</input>
      </div>
      <div class="radio">
        <input type="radio" name="sex" value="女" id="sex2" >women</input>
      </div>
      <div class="radio">
        <input type="radio" name="sex" value="不明" id="sex3" >unknown</input>
      </div>
```

## 参考サイト ラジオボタン
https://qiita.com/rubytomato@github/items/387d46ea34eb92071065