この記事に書いてあること
Java開発においてはSpring MVC(やBOOT)を使うことが多いと思います。その際に画面コンテンツに関してはthymeleafという機構を使うのが一般的だと思います。
(もちろんSpring+JSPを使った開発も経験してます)
その中で、ボタンのonClick属性を使用して他の画面にGETで遷移するようなパターンでちょっと迷ったので備忘メモ。
thymeleafの属性をよく調べればなんてことはないのですが、なかなか公式ドキュメントから漁るのも体力入りますからね・・・誰かの助けになれば。
前提
- Spring MVC 5.1.16
- thymeleaf 3.0.11
- Java11
- ボタンを押した時に動作するonClickのリンク先URLはmodel.attributeを使ってurlという名前でテンプレートに引き渡す
結論
th:attrを使った上で、エスケープしたシングルクオートで${url}を囲ってやる必要がありました。
<input type="button" name="SUBMIT" th:attr="onClick='location.href=\''+${url}+'\''">
概要
thymeleafを使うとなるとQuitaのこの辺りの記事にお世話になることが多いと思うのですが、ボタン押下時の画面遷移についての情報がありません。
自分で試行錯誤してみたところ、無事に想定通りの動きをさせることができました。
ダメな例1:すぐ思いつくパターン
とりあえず思いつくのが以下のパターンではないでしょうか。
<input type="button" name="SUBMIT" onclick="location.href="+th:text=${url}>
location.href=までを書いた後、URLをth:text属性で埋め込んでやろうとしました。
この結果得られたHTMLはボタンを押しても何も反応しませんでした。
この時、ページのソースを表示して中身を確認すると以下のような値が設定されていました。
<input type="button" name="SUBMIT" onclick="location.href="+th:text=${url}>
onclick以下のダブルクオートで囲んだエリアがそのまま文字列として認識されてしまいました。
ダメな例2:1を改善したパターン
先の結果を受けて、onclickなどの属性を使用するときはth:attrを使うことがわかりました。
valueを入れたければth:value,textを表示したければth:textというようになりますが、その他の任意の属性を使用したい場合はth:attrを使います。
th:attr="onclick"としてやることで、thymeleafの機能を使ってonclickを動的に設定することができるようになります。
ということで以下のようにしました。
<input type="button" name="SUBMIT" th:attr="onclick='location.href=${url}'">
この結果得られたページのソースは
<input type="button" name="SUBMIT" onclick="location.href=${url}">
先ほどよりは可能性がありそうです。しかし、肝心のurlが置換されていません。
ダメな例3:シングルクオートを活用したパターン
先の例でダメなポイントは、${url}がシングルクオートの中に入っており、そのまま文字列として扱われている点でした。
そこで、${url}をシングルクオートの外に置いてみます。
<input type="button" name="SUBMIT" th:attr="onclick='location.href='+${url}">
この結果得られたHTMLのソースは以下でした。
<input type="button" name="SUBMIT" onclick="location.href=http://localhost:8080/SampleAP/getendpoint">
これでボタンを押してみると、何も反応しません。よくみたらlocation.href=の後のURLがシングルクオートで囲まれていません。
これによりonclick自体は動いていもlocationn.hrefが動いていないのでしょう。あとはこのURLをシングルクオートで囲ってやれば良さそうです。
いけた例:エスケープしたシングルクオートで${url}を囲うパターン
先の例が非常に惜しかったので、単純な発想でシングルクオートをエスケープしてthymeleafのテンプレートに書いてみることにしました。
<input type="button" name="SUBMIT" th:attr="onClick='location.href=\''+${url}+'\''">
location.hrefの部分にエスケープしたシングルクオートを追加しています。
これにより、以下のHTMLソースを得ることができ、ボタンも無事に動作しました!
<input type="button" name="SUBMIT" onclick="location.href='http://localhost:8080/SampleAP/getendpoint'">
なかなか癖があって難しいですね。th:attrは使わなくてもいいかもしれませんが、thymeleafをhtmlファイルのまま表示する時のためには使っておいた方が無難でしょう。