ThymeleafでJavaScriptに配列を渡す方法を徹底解説!onclick引数での連携をマスターしよう
新人
「先輩、ThymeleafからJavaScriptに配列を渡したいんですが、うまく動かなくて困ってます。」
先輩
「ThymeleafとJavaScriptを連携する場合、サーバー側の変数を正しくJavaScriptに埋め込む必要があるね。onclickイベントで引数に配列を渡す場合は特に注意が必要だよ。」
新人
「onclickで配列を渡すってどうやるんですか?普通にth:onclickで書いてもエラーになります…」
先輩
「Thymeleafの式をJavaScript側に渡すには、少しコツがあるんだ。順を追って説明するね。」
1. ThymeleafとJavaScriptの引数連携の基本
ThymeleafはSpring MVCで使用されるテンプレートエンジンで、サーバー側のデータをHTMLやJavaScriptに動的に埋め込むことができます。特に、JavaScriptの関数呼び出しに引数を渡したいとき、th:onclickを利用して連携させるのが一般的です。
ただし、JavaScriptに直接オブジェクトや配列を渡す場合、Thymeleafの構文をそのまま埋め込むと意図した動作をしないことがあります。そこで重要になるのが、[[...]]というThymeleafの「JavaScript内出力構文」です。
例えば、次のようにHTML側でボタンを作り、クリック時に配列を渡すように設定します。
<button th:onclick="'showData(' + ${dataList} + ')'">データを表示</button>
この書き方だと、ThymeleafがJavaのリストをそのまま文字列として埋め込もうとするため、JavaScriptで構文エラーになることがあります。配列を正しく扱うには、JSON形式に変換して渡すのがコツです。
2. 配列をonclickで渡す仕組みを理解する
ThymeleafからJavaScriptに配列を渡すときは、まずサーバー側のコントローラでデータをリストとしてModelに格納します。
@Controller
public class SampleController {
@GetMapping("/sample")
public String showPage(Model model) {
List<String> names = List.of("田中", "佐藤", "鈴木");
model.addAttribute("names", names);
return "sample";
}
}
次に、HTML側(Thymeleafテンプレート)でJavaScriptのonclickに配列を引数として渡す方法を確認します。ここで重要なのが、Thymeleafの[[...]]構文を使うことです。
<button th:onclick="'showNames(' + '[[${names}]]' + ')'">名前を表示</button>
このように書くことで、Thymeleafがサーバー側のnamesリストをJSON形式に変換してJavaScriptに埋め込んでくれます。例えば、ブラウザ上では次のように変換されます。
<button onclick="showNames(['田中','佐藤','鈴木'])">名前を表示</button>
この結果、JavaScript関数showNames()に配列がそのまま渡されます。JavaScript側では次のように受け取って使えます。
<script th:inline="javascript">
function showNames(list) {
alert("受け取った配列:" + list.join(", "));
}
</script>
th:inline="javascript"を指定すると、ThymeleafがJavaScript内でも式展開を安全に処理してくれるため、サーバー側の値を直接スクリプトに埋め込むことが可能になります。
JavaScript内での配列操作とThymeleafの関係
Thymeleafで配列をJavaScriptに渡す際に、配列を一度JSON形式に変換しておくと、クライアント側で扱いやすくなります。Thymeleafでは[[${変数}]]を使うことで、自動的にJavaScriptに適した形式に変換してくれます。
たとえば、次のように書くと、コントローラで設定したリストがJavaScriptの配列として利用できます。
<script th:inline="javascript">
let items = [[${names}]];
console.log(items); // ["田中","佐藤","鈴木"]
</script>
この方法なら、onclickだけでなく、ページロード時にJavaScriptで動的処理を行いたい場合にも活用できます。ThymeleafとJavaScriptの連携を理解しておくと、フォーム送信やイベント処理など、フロントエンドとの橋渡しがスムーズになります。
onclickイベントで複数引数を渡したい場合
配列だけでなく、他の値も一緒に渡したい場合は、コンマ区切りで複数引数を指定します。次の例では、IDと配列を同時に渡しています。
<button th:onclick="'handleClick(' + ${id} + ', ' + '[[${names}]]' + ')'">実行</button>
ブラウザ上では次のような出力になります。
<button onclick="handleClick(1, ['田中','佐藤','鈴木'])">実行</button>
これにより、サーバー側のIDと配列データを同時にJavaScriptへ渡すことができます。ThymeleafとJavaScriptを組み合わせることで、サーバーとクライアントのデータ連携が非常に柔軟になります。
3. コントローラから配列データをThymeleafへ渡す方法
ここからは、Springの@Controllerを使ってサーバー側から配列データをThymeleafに渡す流れを確認しましょう。Thymeleafはサーバーサイドレンダリングを行うテンプレートエンジンなので、Javaのリストや配列をそのままテンプレートにバインドできます。
次の例では、文字列配列と数値配列をそれぞれ用意して、モデルに追加しています。pleiades+Gradle環境でSpringプロジェクトを構築し、@Controllerを使って処理します。
@Controller
public class ArrayController {
@GetMapping("/arrays")
public String showArrays(Model model) {
List<String> fruits = List.of("りんご", "みかん", "ぶどう");
List<Integer> numbers = List.of(10, 20, 30);
model.addAttribute("fruits", fruits);
model.addAttribute("numbers", numbers);
return "arrays";
}
}
このようにmodel.addAttribute()でリストを登録すれば、Thymeleaf側で変数${fruits}や${numbers}として使用できます。Thymeleafが自動的に配列やリストを認識し、JavaScript内でも扱えるように変換してくれます。
重要なのは、Thymeleafはリストの中身を自動で文字列化して出力しますが、JavaScriptで使う場合はクォートの扱いに注意が必要です。特に「文字列配列」は["A","B","C"]のようにクォート付きで表現され、「数値配列」は[1,2,3]のようにクォート無しで展開されます。
4. onclickでJavaScriptへ配列を引数として渡す例
次に、Thymeleafで作成した配列データをonclickイベント経由でJavaScriptの引数に渡す方法を確認しましょう。先ほどのコントローラで渡したfruitsとnumbersを使います。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ThymeleafとJavaScriptの配列引数連携</title>
</head>
<body>
<h3>文字列配列を渡す例</h3>
<button th:onclick="'showFruits(' + '[[${fruits}]]' + ')'">フルーツ表示</button>
<h3>数値配列を渡す例</h3>
<button th:onclick="'showNumbers(' + '[[${numbers}]]' + ')'">数値表示</button>
<script th:inline="javascript">
function showFruits(list) {
alert("フルーツ一覧: " + list.join(", "));
}
function showNumbers(nums) {
let total = nums.reduce((sum, n) => sum + n, 0);
alert("合計値は " + total + " です");
}
</script>
</body>
</html>
この例では、[[${fruits}]]と[[${numbers}]]をそれぞれJavaScriptの引数として埋め込み、onclickイベントで関数に配列を渡しています。
Thymeleafは[[...]]内でリストをJSON形式に変換するため、HTML出力結果は次のようになります。
<button onclick="showFruits(['りんご','みかん','ぶどう'])">フルーツ表示</button>
<button onclick="showNumbers([10,20,30])">数値表示</button>
このように出力されることで、JavaScript側ではそれぞれの配列をそのまま受け取ることができます。文字列配列では各要素がクォートで囲まれ、数値配列ではクォート無しで出力される点がポイントです。
5. JavaScriptで配列を受け取って処理する基本
Thymeleafから渡された配列をJavaScriptで受け取った後は、通常のJavaScript配列として扱えます。onclickイベントを通じて引数として渡された配列は、関数の中でArrayオブジェクトとして利用できます。
たとえば、文字列配列の場合はjoin()を使ってカンマ区切りで出力したり、forEach()で要素をループ処理できます。
<script th:inline="javascript">
function showFruits(list) {
console.log("受け取った配列:", list);
list.forEach(function(item) {
console.log("要素:", item);
});
alert("フルーツは " + list.join(" と ") + " です");
}
</script>
一方、数値配列の場合は、数値として演算処理ができるので、合計値や平均値を簡単に求められます。
<script th:inline="javascript">
function showNumbers(nums) {
let sum = nums.reduce((a, b) => a + b, 0);
let avg = sum / nums.length;
alert("合計値: " + sum + "\\n平均値: " + avg);
}
</script>
ここで初心者がよくつまずくのが「クォートの違い」です。Java側のリストがList<String>の場合、Thymeleafが生成する配列は['A','B','C']のように文字列として扱われます。一方、List<Integer>のような数値リストは[1,2,3]とクォートなしで出力されます。
もしクォートの有無を誤ると、JavaScriptで「文字列として結合」されてしまったり、「数値として計算できない」エラーが発生することがあります。そのため、Thymeleafでの配列展開結果をブラウザのデベロッパーツールで確認しておくことをおすすめします。
また、onclickで渡すデータが多い場合は、直接onclickに埋め込むのではなく、data属性を利用してJavaScript側で取得する方法もあります。これは可読性や保守性の観点からも有効です。
例えば次のように、Thymeleafでdata-fruits属性に配列を埋め込み、クリック時にJavaScriptで読み込むことができます。
<button th:attr="data-fruits=[[${fruits}]]" onclick="readData(this)">データ読み込み</button>
<script>
function readData(btn) {
const list = JSON.parse(btn.getAttribute("data-fruits").replace(/'/g, '"'));
alert("取得した配列: " + list.join(", "));
}
</script>
このように、Thymeleafで生成した配列をJavaScriptに安全に引き渡す方法は複数あります。onclick引数で直接渡す方法はシンプルですが、データ量が多い場合やエスケープ処理が必要な場合は、data属性やJSON形式を活用するのが効果的です。
ThymeleafとJavaScriptの連携を正しく理解すれば、Springアプリケーションの画面動作をより柔軟に制御できるようになります。
6. よくあるエラーとデバッグのコツ(undefined・展開ミスなど)
ThymeleafとJavaScriptで配列をonclick引数に渡すとき、初心者が特につまずきやすいのが「undefined」エラーや「展開ミス」です。これらの問題は、配列の構文やクォートの扱いを誤ることで発生します。
例えば、次のように書くとブラウザでUncaught SyntaxErrorが出ることがあります。
<button th:onclick="'showData(' + ${list} + ')'">表示</button>
この書き方では、ThymeleafがJavaのリストを文字列化せずにそのまま埋め込もうとするため、出力結果がonclick="showData([田中,佐藤,鈴木])"のようになり、JavaScript構文として不正になります。
正しくは次のように、ThymeleafのJavaScript埋め込み構文[[...]]を使います。
<button th:onclick="'showData(' + '[[${list}]]' + ')'">表示</button>
こうすることで、Thymeleafが自動的に配列をJSON形式に変換し、onclick="showData(['田中','佐藤','鈴木'])"という正しい形で出力します。
もしonclickで受け取った配列がundefinedになってしまう場合は、以下を確認してください。
- Thymeleafの変数名(
${list}など)が正しくControllerで追加されているか - HTMLの出力結果をブラウザの「検証ツール」で確認して、配列形式が崩れていないか
th:inline="javascript"が設定されているか
また、配列内の文字列にカンマやシングルクォートが含まれている場合、Thymeleafがうまくエスケープできずエラーになることがあります。その場合はJSON.stringify()を使ってエンコード処理を行うのが安全です。
<script th:inline="javascript">
function debugData(list) {
console.log("配列内容:", list);
if (!Array.isArray(list)) {
console.error("配列が正しく受け取れていません");
}
}
</script>
ブラウザのデベロッパーツール(F12キー)を使えば、受け取った配列が正しく展開されているか確認できます。console.logを活用して、配列の中身や型をチェックする習慣をつけましょう。
7. 実践例:複数のユーザー情報を配列で渡すケース
ここでは、複数のユーザー情報(名前と年齢)をThymeleafからJavaScriptに配列として渡す実践例を紹介します。Springの@ControllerでリストをModelに追加し、Thymeleafテンプレートでonclick引数に渡します。
@Controller
public class UserController {
@GetMapping("/users")
public String showUsers(Model model) {
List<Map<String, Object>> users = new ArrayList<>();
users.add(Map.of("name", "田中", "age", 25));
users.add(Map.of("name", "佐藤", "age", 30));
users.add(Map.of("name", "鈴木", "age", 28));
model.addAttribute("users", users);
return "users";
}
}
次にThymeleafテンプレートを作成し、JavaScriptのonclickイベントに配列を渡します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ThymeleafとJavaScriptの配列引数例</title>
</head>
<body>
<h3>ユーザー情報を配列で渡す</h3>
<button th:onclick="'showUsers(' + '[[${users}]]' + ')'">ユーザー一覧を表示</button>
<script th:inline="javascript">
function showUsers(userList) {
console.log("受け取った配列:", userList);
userList.forEach(function(u, index) {
console.log("[" + index + "] 名前: " + u.name + ", 年齢: " + u.age);
});
alert("ユーザー数: " + userList.length + "人");
}
</script>
</body>
</html>
このコードを実行すると、ブラウザのコンソールには次のように出力されます。
受け取った配列: [{name: "田中", age: 25}, {name: "佐藤", age: 30}, {name: "鈴木", age: 28}]
[0] 名前: 田中, 年齢: 25
[1] 名前: 佐藤, 年齢: 30
[2] 名前: 鈴木, 年齢: 28
このように、Thymeleafの[[${users}]]はオブジェクト配列をJSON形式に変換して出力するため、JavaScriptでそのまま配列として扱えます。
もし出力結果が[Object Object]と表示される場合は、console.logで確認する代わりにconsole.table(userList)を使うと、表形式で中身を確認できるのでおすすめです。
8. 安全でメンテナンスしやすい配列引数の扱い方と開発のポイント
ThymeleafとJavaScriptを連携させる際は、配列をonclickに直接渡す方法以外にも、より安全で保守性の高い設計が求められます。特にプロジェクト規模が大きくなると、onclickに大量のデータを埋め込むのは非効率です。
おすすめの方法は、ThymeleafでデータをJSON文字列として属性に埋め込み、JavaScript側でJSON.parse()して処理する手法です。次の例を見てみましょう。
<button th:attr="data-users=[[${users}]]" onclick="readUsers(this)">配列を読み込み</button>
<script>
function readUsers(btn) {
const json = btn.getAttribute("data-users").replace(/'/g, '"');
const users = JSON.parse(json);
users.forEach(u => console.log(u.name + "(" + u.age + "歳)"));
}
</script>
この方法なら、onclickに直接大きな配列を渡さずに済むため、HTMLの可読性が向上します。また、ブラウザの開発ツールでHTMLを確認したときも、data属性の中にJSONが安全に格納されているのが分かります。
さらに、配列の展開順序にも注意しましょう。Thymeleafはサーバー側でレンダリングを行うため、JavaScriptよりも先に配列データを埋め込みます。したがって、JavaScript内で参照する前に変数が初期化されているかを確認することが大切です。
また、JavaScriptで配列を受け取る際には、必ずArray.isArray()を使って配列であることをチェックしましょう。予期せぬnullや文字列が渡るケースを防止できます。
<script>
function validateData(data) {
if (!Array.isArray(data)) {
console.error("配列ではありません:", data);
return;
}
console.log("配列の長さ:", data.length);
}
</script>
最後に、ThymeleafとJavaScriptの動的連携では、配列データをサーバーから受け取るだけでなく、双方向にデータを扱う設計も意識することが大切です。例えば、JavaScriptで編集した配列をフォーム送信時にJSONとして再びサーバーへ送ることで、動的なWebアプリを構築できます。
このように、onclickでの配列引数連携を理解することで、ThymeleafによるサーバーサイドテンプレートとJavaScriptの動的操作をスムーズに結びつけることができます。pleiades+Gradle環境でのSpringアプリケーション開発でも、配列の扱い方をマスターすれば、より効率的で安全な実装が実現できます。
まとめ
ThymeleafとJavaScriptで配列を扱う考え方の整理
今回の記事では、Thymeleafを使ってサーバー側の配列データをJavaScriptに渡す方法について、onclick引数を中心に詳しく解説してきました。 Spring MVCとThymeleafを組み合わせたWebアプリケーションでは、コントローラで作成したListや配列を画面側でどのように扱うかが非常に重要です。 特にJavaScriptと連携する場面では、単純に変数を埋め込むだけでは動かず、構文エラーやundefinedといったトラブルが発生しやすくなります。
その原因の多くは、JavaのリストとJavaScriptの配列の表現の違い、そしてクォートの扱いにあります。
Thymeleafでは [[${変数}]] というJavaScript用の出力構文を使うことで、サーバー側のListをJSON形式に変換し、JavaScriptが理解できる形で展開してくれます。
この仕組みを理解することが、ThymeleafとJavaScript連携の第一歩と言えるでしょう。
onclick引数で配列を渡すときの重要ポイント
onclickイベントでJavaScript関数に配列を渡す場合、文字列として連結するのではなく、
ThymeleafにJSON形式へ変換させた配列をそのまま引数として渡すことが大切です。
具体的には、th:onclick属性の中で '[[${配列}]]' を使い、JavaScriptの関数呼び出し文字列を組み立てます。
これにより、ブラウザ上では ['値1','値2'] や [1,2,3] のような正しい配列表現に変換され、
JavaScript側では通常の配列として forEach や join、reduce などの配列メソッドが使えるようになります。
文字列配列と数値配列でクォートの有無が変わる点も、実務では特に注意したいポイントです。
保守性を意識した実装とdata属性の活用
記事の後半で紹介したように、onclickに直接大量の配列データを渡す方法はシンプルですが、 画面が複雑になると可読性やメンテナンス性が低下しやすくなります。 そのような場合は、Thymeleafでdata属性に配列データを埋め込み、JavaScript側で取得して処理する方法が有効です。
data属性を使えば、HTML構造とJavaScriptの責務を分離しやすくなり、後から仕様変更が入った場合でも修正箇所を最小限に抑えられます。 実務レベルのSpring Boot開発では、このような設計の考え方が非常に重要になります。
まとめとしてのサンプルイメージ
<button th:onclick="'summaryClick(' + '[[${names}]]' + ')'">まとめ確認</button>
<script th:inline="javascript">
function summaryClick(list) {
if (!Array.isArray(list)) {
alert("配列が正しく渡っていません");
return;
}
alert("配列の中身: " + list.join(" / "));
}
</script>
このような形で実装しておけば、ThymeleafからJavaScriptへの配列受け渡しを安全かつ直感的に行えます。 コントローラ、テンプレート、JavaScriptの役割を意識しながらコードを書くことが、エラーを減らす近道です。
生徒:「最初は、ThymeleafからJavaScriptに配列を渡すだけなのに、どうしてこんなに難しいんだろうと思っていました。」
先生:「それは自然な反応だよ。JavaとJavaScriptは似ているようで、データの扱い方が違うからね。」
生徒:「でも [[${変数}]] を使う理由が分かってから、配列がそのまま使えるようになってスッと理解できました。」
先生:「そこが一番大事なポイントだね。ThymeleafがJSON形式に変換してくれていることを意識できると、応用も効くようになる。」
生徒:「onclickで渡すだけじゃなくて、data属性を使う方法も実務では役立ちそうだと感じました。」
先生:「その気付きはとてもいいよ。小さなサンプルだけでなく、保守性や可読性まで考えられるようになると、一段レベルアップだ。」
生徒:「ThymeleafとJavaScriptの連携が怖くなくなりました。次はフォーム送信やJSON通信にも挑戦してみたいです。」
先生:「ぜひ挑戦してみよう。今回学んだ配列の扱い方は、これからのSpring開発でも必ず役に立つからね。」