LoginSignup
11
3

More than 1 year has passed since last update.

Thymeleafで動的なonclickを書きたい

Posted at

Thymeleafで動的なonclickを書こうとして少し苦戦したので記事に残しておきます。
失敗例を挙げながら説明していきます。

環境

  • Spring Boot 2.7.0
  • Thymeleaf 3.0.15

目標

HTMLに下記のようなボタンを表示することが目標です。
"hoge"の部分が動的に変わるイメージです。

<button onclick="location.href='https://localhost:8080/list?param=hoge'">ボタン</button>

結論

<button th:onclick="|location.href='https://localhost:8080/list?param=__${hoge}__'|">ボタン</button>

最終的に上記のコードで、目標通りのボタン表示ができました。
シンプルで分かりやすいと思います。

結論までの過程

失敗から結論に至るまでの過程を記載します。

失敗

<button th:onclick="'location.href=\'https://localhost:8080/list?param=' + ${hoge} + '\''">
  ボタン
</button>

愚直に文字列結合で書いてみました。
うまくいくと思いましたが、${hoge}に文字列型を出力しようとすると下記のエラーが発生します。

org.thymeleaf.exceptions.TemplateProcessingException: Only variable expressions returning numbers or booleans are allowed in this context, any other datatypes are not trusted in the context of this expression, including Strings or any other object that could be rendered as a text literal. A typical case is HTML attributes for event handlers (e.g. "onload"), in which textual data from variables should better be output to "data-*" attributes and then read from the event handler.

onclickに埋め込める変数の型は数値またはブール値のみが許可されているようです。
エラー文では、"data-*"属性に変数を出力してから、onclickで読み込むことで解決すると記載されていますが、今回は別の方法で解決しました。

成功

<button th:onclick="'location.href=\'https://localhost:8080/list?param=' + __${hoge}__ + '\''">
  ボタン
</button>

失敗例の${hoge}を「__」(アンダースコア2つ)で囲いました。
「__${変数}__」の形式で書くと、変数部分が事前に評価され、変数部分が値に変換された後にonclickの文が構成されるようです。
これで${hoge}に文字列型を出力してもエラーが出なくなりました。

改善(結論)

<button th:onclick="|location.href='https://localhost:8080/list?param=__${hoge}__'|">
  ボタン
</button>

一個前の成功例の書き方だと、エスケープや+演算子のせいで結構ごちゃごちゃしています。
onclickの式を、「 |式の内容| 」の形式で書くことで、エスケープや+演算子を使わずに記述することができました。(リテラル置換)


参考になれば幸いです。

参考文献

11
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
3