ThymeleafとJavaScriptのonclickで引数を渡す方法を完全解説!初心者でもわかる値の受け渡し
新人
「先輩、ThymeleafでボタンをクリックしたときにJavaScriptのonclickで値を渡したいんですけど、どうやればいいんですか?」
先輩
「いい質問だね。ThymeleafとJavaScriptを連携してonclickイベントで値を扱うのは、Springアプリ開発でもよく使うテクニックだよ。」
新人
「サーバーの値をJavaScriptに渡したいときって、変数の書き方とか気をつけることありますか?」
先輩
「あるよ。Thymeleafの式展開の仕組みを理解しておかないと、onclickの中で値が正しく渡らなかったり、undefinedになることもあるんだ。」
新人
「なるほど……。じゃあ、まず基本の構造から教えてください!」
1. ThymeleafとJavaScriptのonclick連携とは?
Thymeleafは、Spring BootアプリケーションでHTMLテンプレートを生成するテンプレートエンジンです。サーバーサイドでJavaの値をHTML内に埋め込み、ブラウザに送信することができます。一方、onclickイベントは、ユーザーがボタンなどをクリックした際にJavaScriptの関数を実行する仕組みです。
この2つを組み合わせることで、「サーバーのデータをJavaScript関数に引数として渡す」という動作が可能になります。たとえば、商品IDやユーザー名などをボタンクリックで処理したいときに便利です。
Springの@Controllerで渡したデータをThymeleafで表示し、それをonclickに埋め込むのがポイントです。
2. onclickイベントでサーバーの値を使うための基本構造
Thymeleafでonclickに引数を渡すには、テンプレート内で変数を埋め込む必要があります。以下は基本的な構造の例です。
<button type="button" onclick="showMessage('[[${message}]]')">クリックして表示</button>
上記のように、[[${変数}]]というThymeleaf式でサーバー側の値をHTML内に展開します。この書き方は、「テキストモード展開」と呼ばれ、JavaScriptの中で使う際に便利です。
ここで重要なのは、クォート(シングルクォートやダブルクォート)の扱いです。onclick内ではJavaScriptの文字列として渡す必要があるため、Thymeleafの変数を展開する部分を必ずクォートで囲みましょう。
また、Springの@Controllerでは以下のようにモデルに値を追加しておきます。
@Controller
public class SampleController {
@GetMapping("/onclick")
public String showPage(Model model) {
model.addAttribute("message", "ThymeleafからJavaScriptへようこそ!");
return "onclick-sample";
}
}
このようにしておくと、HTML側で${message}を展開できるようになります。
3. 簡単なサンプル:ボタンから値を渡してJavaScriptで受け取る
それでは、実際にThymeleafとJavaScriptを使ってonclickで引数を渡すサンプルを見てみましょう。
以下はテンプレートファイル(onclick-sample.html)の例です。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>onclickの引数サンプル</title>
<script>
function showMessage(value) {
console.log("受け取った値:", value);
alert("JavaScriptで受け取った値: " + value);
}
</script>
</head>
<body>
<h2>ThymeleafとJavaScriptのonclickサンプル</h2>
<button type="button" onclick="showMessage('[[${message}]]')">メッセージを表示</button>
</body>
</html>
このコードでは、Thymeleafの[[${message}]]がサーバーから受け取った値(たとえば「ThymeleafからJavaScriptへようこそ!」)に展開されます。ボタンをクリックすると、JavaScriptのshowMessage関数が呼ばれ、その引数として展開済みの文字列が渡されます。
実際のブラウザのコンソールでは、以下のように出力されます。
受け取った値: ThymeleafからJavaScriptへようこそ!
アラートウィンドウにも同じメッセージが表示され、サーバーの値がJavaScriptで正しく受け取れていることが確認できます。
このように、ThymeleafとJavaScriptのonclickイベントを組み合わせることで、動的な値の受け渡しが可能になります。特にSpringの@Controller構成でのフロント側の連携では、非常に基本となる部分です。
次のステップでは、コントローラからの値をさらに複雑に扱ったり、複数の引数を渡す方法を解説していきます。
4. コントローラから値を渡してonclickで扱う方法
ここでは、Springの@Controllerから複数の値をThymeleafへ渡し、それをonclickで利用する方法を詳しく見ていきます。実際のアプリ開発では、単一のメッセージではなく、IDや名前など複数の値をJavaScriptへ引き渡す場面が多いです。
まず、Java側のコントローラを作成して、モデルに値を設定します。開発環境はpleiades+Gradleで、依存関係はSpring Webを追加しておきましょう。
@Controller
public class UserController {
@GetMapping("/user-list")
public String showUsers(Model model) {
model.addAttribute("userId", 101);
model.addAttribute("userName", "田中太郎");
return "user-list";
}
}
上記のように、userIdとuserNameをサーバーサイドで用意します。次に、これをHTMLテンプレートのボタンに埋め込み、クリック時にJavaScriptで受け取ってみましょう。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ユーザー情報のonclickサンプル</title>
<script>
function showUserInfo(id, name) {
console.log("ユーザーID:", id);
console.log("ユーザー名:", name);
alert("選択されたユーザー:" + name + "(ID:" + id + ")");
}
</script>
</head>
<body>
<h2>Thymeleafでサーバーの値をJavaScriptに渡す</h2>
<button type="button"
onclick="showUserInfo([[${userId}]], '[[${userName}]]')">
ユーザー情報を表示
</button>
</body>
</html>
ここでのポイントは、数値(ID)と文字列(名前)を区別して扱うことです。Thymeleafでは数値を直接展開できますが、文字列はクォートで囲む必要があります。つまり、'[[${userName}]]'のようにシングルクォートを使うことで、JavaScript文字列として正しく解釈されます。
この状態でブラウザを開いてボタンをクリックすると、console.logには次のように出力されます。
ユーザーID: 101
ユーザー名: 田中太郎
これで、Springコントローラの値がJavaScriptのonclickイベントで動的に利用できるようになりました。
5. 複数の引数を渡す場合の書き方
次に、Thymeleafで複数の引数をonclickに渡す方法を紹介します。たとえば、ID・名前・メールアドレスなど複数のデータをまとめて関数に送るケースです。Thymeleafでは、コンマで区切って複数の値を渡すことができます。
<button type="button"
onclick="showUserDetails([[${user.id}]], '[[${user.name}]]', '[[${user.email}]]')">
詳細を表示
</button>
JavaScript側では、対応する数の引数を受け取る関数を用意します。
<script>
function showUserDetails(id, name, email) {
console.log("ID:", id);
console.log("名前:", name);
console.log("メール:", email);
alert("ユーザー情報: " + name + "(" + email + ")");
}
</script>
Thymeleafの式展開を利用すると、サーバーから受け取ったデータを簡単にonclickイベントに引き渡せます。ただし、文字列のクォートが抜けていると、ブラウザで「Uncaught SyntaxError」といったエラーが発生します。特に、全角文字や日本語名を扱う場合には、クォートを正しく付けることが大切です。
また、サーバーから受け取るデータが空の場合でもエラーが出ないように、th:ifを使ってボタンの表示を制御するのも実践的な方法です。
<button th:if="${user != null}"
onclick="showUserDetails([[${user.id}]], '[[${user.name}]]', '[[${user.email}]]')">
詳細を表示
</button>
このようにThymeleafでは、動的に展開される値の有無を条件分岐で安全に制御できるため、onclickイベントとの連携がより堅牢になります。
6. 動的に生成される要素へのonclick設定(ループ処理とth:each)
実際のアプリでは、ユーザー一覧や商品リストなど、複数の要素を動的に生成してonclickを設定するケースが多くあります。その際に活躍するのがth:each属性です。
以下の例では、コントローラから複数のユーザーリストを渡し、それをHTMLで繰り返し表示します。
@Controller
public class UserListController {
@GetMapping("/users")
public String showUserList(Model model) {
List<User> users = List.of(
new User(1, "佐藤花子", "hanako@example.com"),
new User(2, "鈴木一郎", "ichiro@example.com"),
new User(3, "高橋未来", "mirai@example.com")
);
model.addAttribute("users", users);
return "user-list-loop";
}
}
Thymeleaf側のHTMLは次のようになります。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ユーザー一覧</title>
<script>
function showInfo(id, name, email) {
console.log("選択されたID:", id);
console.log("名前:", name);
console.log("メール:", email);
}
</script>
</head>
<body>
<h2>ユーザー一覧</h2>
<ul>
<li th:each="user : ${users}">
<span th:text="${user.name}"></span>
<button type="button"
th:onclick="'showInfo(' + ${user.id} + ', \\' ' + ${user.name} + ' \\' , \\' ' + ${user.email} + ' \\' )'">
表示
</button>
</li>
</ul>
</body>
</html>
上記のように、th:onclickを使うと、ループ内で動的にonclickを生成できます。注意点は、クォートのエスケープです。Thymeleafでは\'(バックスラッシュ+シングルクォート)を使うことで、HTML内に正しくクォートが出力されます。
ブラウザで「表示」ボタンをクリックすると、コンソールには次のような出力が確認できます。
選択されたID: 2
名前: 鈴木一郎
メール: ichiro@example.com
このように、ThymeleafとJavaScriptを組み合わせることで、サーバー側から動的に値を渡し、ユーザーごとのデータをonclickで制御することができます。Springの@Controller構成と組み合わせれば、Webアプリの操作性を高める実践的なUI連携が実現できます。
次のパートでは、これらのonclickイベントをより安全かつ効率的に管理する方法を紹介していきます。
7. よくあるエラーと注意点(undefined・展開されない・クォートミス)
ThymeleafとJavaScriptのonclick連携では、値がうまく渡らないときに「undefined」や「展開されない」といったエラーが起きがちです。初心者の方が最初につまずくポイントでもあります。まず、「undefined」と表示される場合は、Thymeleafの変数が存在しない、もしくは変数名を間違えていることが多いです。${user.name}と${userName}のような表記揺れに注意しましょう。
次に、「展開されない」問題は、Thymeleafの式がJavaScript文字列として正しく処理されていない場合に発生します。特に、クォート(シングルクォートやダブルクォート)の位置がずれていると、HTML上では単なる文字列として扱われ、onclick内では意図した値になりません。たとえば、onclick="showName([[${user.name}]])"のようにクォートがないと、JavaScript側では識別子として解釈され、結果的にundefinedになります。
このため、文字列として扱いたい値は必ず'[[${user.name}]]'のようにシングルクォートで囲みましょう。また、HTMLエスケープにも注意が必要です。Thymeleafは安全のために自動でエスケープを行いますが、特殊文字を含む場合はth:utextやth:onclickを使って適切に展開するのがポイントです。
さらに、onclick属性の中で複雑な構文を書くと、クォートの対応が崩れやすくなります。初心者のうちは、シンプルな関数呼び出し構造を保ち、複数の引数を扱う際はそれぞれを丁寧に囲むことが安全です。特に日本語や空白を含む値では、シングルクォートを忘れるとブラウザで予期せぬ挙動になります。
8. 実践例:ボタンクリックでIDを渡して詳細情報を取得する
ここでは、Springの@ControllerとThymeleafテンプレートを組み合わせて、ボタンクリックでユーザーIDをJavaScriptへ渡し、そのIDを使って詳細情報を取得する例を見ていきましょう。開発環境はpleiades+Gradle構成で統一します。
まず、コントローラを用意して、ユーザー情報のリストをモデルに渡します。
@Controller
public class DetailController {
@GetMapping("/user-detail")
public String showUserList(Model model) {
List<User> users = List.of(
new User(1, "山田太郎"),
new User(2, "佐藤花子"),
new User(3, "鈴木一郎")
);
model.addAttribute("users", users);
return "user-detail";
}
}
次に、Thymeleafテンプレートでボタンを生成します。クリックされたときにIDをJavaScriptへ渡し、コンソールに出力してみましょう。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>onclickでIDを渡す</title>
<script>
function getDetail(id) {
console.log("取得対象のID:", id);
document.getElementById("result").textContent = "選択されたIDは " + id + " です";
}
</script>
</head>
<body>
<h2>ThymeleafとJavaScriptのonclick連携例</h2>
<ul>
<li th:each="user : ${users}">
<span th:text="${user.name}"></span>
<button type="button" th:onclick="'getDetail(' + ${user.id} + ')'">詳細を見る</button>
</li>
</ul>
<div id="result"></div>
</body>
</html>
この構成では、各ユーザーに対応するボタンが生成され、クリック時に該当のIDがgetDetail()関数へ渡されます。JavaScript関数の中ではdocument.getElementById()でHTML要素を取得し、選択されたIDを動的に表示しています。
この書き方を使う理由は、Thymeleafがサーバーサイドで変数を展開し、HTMLを生成するためです。サーバーで${user.id}が実際の値に置き換わることで、JavaScriptの実行時に正しい引数が渡されます。もしThymeleaf式をクォートで囲まなかったり、エスケープが不完全だと、HTML上に正しいスクリプトが出力されません。
このように、onclickイベントに動的なIDを渡すことで、ユーザーごとの情報取得や画面遷移などを柔軟に制御できます。次のステップでは、より安全でメンテナンス性の高い書き方を紹介します。
9. 安全でメンテナンスしやすいonclickの書き方と開発のコツ
ThymeleafとJavaScriptを使ったonclick連携は便利ですが、コードが増えるにつれて保守性が低下しやすい部分でもあります。安全でメンテナンスしやすい構成を保つためには、いくつかのコツがあります。
まず、onclick属性に直接長いロジックを書かないことです。JavaScript側に関数を定義し、Thymeleaf側では関数呼び出しだけを記述するようにしましょう。これにより、HTMLテンプレートがシンプルになり、変更点を一箇所に集約できます。
次に、動的な値を安全に扱うために、可能であればHTMLのdata属性を活用する方法もあります。たとえば、次のように書くと、onclickを使わずにJavaScriptで値を取得できます。
<button type="button" th:attr="data-id=${user.id}" onclick="showData(this)">表示</button>
<script>
function showData(element) {
const id = element.getAttribute("data-id");
console.log("取得したID:", id);
}
</script>
この方法の利点は、onclickに直接Thymeleaf式を書かなくてもよい点です。値はHTML属性として保持されるため、展開ミスやクォートの問題を避けることができます。また、JavaScript側でthisキーワードを使うことで、クリックされた要素を簡単に特定できるのも便利です。
さらに、onclickイベントの登録をJavaScript側のaddEventListenerで行うと、より柔軟な設計が可能です。ThymeleafではHTML構造を生成し、JavaScriptが動的にイベントを設定するという分離設計が保たれます。これにより、HTMLとスクリプトが混在せず、保守性が格段に上がります。
最後に、開発中はブラウザの開発者ツールを活用して、onclickで渡された引数を確認する習慣をつけましょう。コンソール出力やアラートで値を追跡することで、Thymeleafの展開が意図通りに動作しているかを確かめられます。
このように、ThymeleafとJavaScriptのonclick連携では、単に動かすだけでなく、安全性・保守性・再利用性を意識した書き方が重要です。動的連携を意識した設計を行うことで、Springアプリ全体の品質を高めることができます。