コード例
ここで作成するUIは下記のものです。 実際に動くデモもご覧ください
clickイベントに応答)してUserProfileを表示します。aタグとTurbo Framesの組み合わせであれば自動的にイベントハンドリングをしてくれますので、これを採用しますhover)、あるいはaタグが使えない場合(例えばtrタグにイベントを繋げたい)はStimulusを使いますが、今回はその必要はありません
なお、比較対象としてjQueryやReactを使った例も紹介しますが、詳しくは解説しません。Hotwire, jQuery, Reactのバージョン(variant)を切り替える方法はfooをご覧ください。
<turbo-frame id="user-profile"> <%# ... %> <%# 表示する内容はこの中 %> <%# ... %> </turbo-frame>
id="user-profile"の<turbo-frame>に挿入されますので、同じidの<turbo-frame>で囲みますclass Users::UserProfilesController < ApplicationController # ... # GET /user/1/user_profile or /user/1/user_profile.json def show @user_profile = @user.user_profile render layout: false # Hotwireでは不要。jQuery版でのみ必要 end # ... end
<turbo-frame class="border rounded shadow" id="user-profile"> </turbo-frame>
<turbo-frame>のid属性で、サーバからのレスポンスが挿入される箇所を指定します<tr> <td class="relative"> <%= link_to user_user_profile_path(user), data: {turbo_frame: "user-profile"} do %> <span class="absolute inset-0"></span> <%= user.user_profile.name %> <% end %> </td> <td class="relative"> <%= link_to user_user_profile_path(user), data: {turbo_frame: "user-profile"} do %> <span class="absolute inset-0"></span> <%= user.email %> <% end %> </td> </tr>
<a>や<form>を使いますdata: {turbo_frame: "user-profile"}はレンダリングされるとdata-turbo-frame="user-profile"になりますが、これはTurboでサーバからのレスポンスを受け取った時に、「2. サイドパネルが挿入される箇所」の<turbo-frame="user-panel">に挿入してくださいという指示になります<table>の中で行を丸ごと囲む<a>タグは作れませんので、<a>タグを2列分用意したり、span absolute insetのパターンを使用しています