[Rails]turboとstimulusによるモーダル
はじめに
turbo-frame
を使ってモダールを実装してみます。
ライブラリを使った記事はこちら
環境
Rails 7.0.4.3
ruby 3.2.1
turbo_frame_tag
とは
turbo_frame_tag
は、Hotwire フレームワークの一部であり、Turbo Streams の一部として提供されているタグです。Turbo Streams は、非同期で部分的なページ更新を実現するためのツールセットで、turbo_frame_tag
はその中で特定の領域を更新するために使用されます。
turbo_frame_tag
は、指定された HTML 要素をフレームとしてマークアップするために使用されます。これにより、そのフレーム内のコンテンツが非同期に更新されることができます。
よくある使用シーン:
-
部分的なコンテンツの更新: ページ全体をリロードせずに特定の部分的なコンテンツを更新する場合に使用します。例えば、コメントセクションや通知リストの更新などがこれに該当します。
-
フォームの非同期送信: フォームの送信時にページ全体をリロードする代わりに、フォーム内の特定の部分だけを更新したい場合に使用します。
-
モーダルの内容の更新: モーダルウィンドウ内のコンテンツを非同期で更新する場合に便利です。
turbo_frame_tag
を追加する
レイアウトに全ページ上にモーダルを開けるようにしたいので、application.html.erb
にmodal
フレームを追加します。
<%= turbo_frame_tag 'modal' %>
turbo-frame
タグを追加されました。
turbo_frame_tag
にモーダルコンテンツを追加する
turbo_frame_tag
内にモダールコンテンツにを追加していきます。
<%= turbo_frame_tag 'modal' %>
# コンテンツ
<% end %>
キャンセルボタンもしくは閉じるボタンも入れましょう。
クリックしたらmodals
コントローラーのclose
アクションを発火させ、モーダルを閉じるようになります。
<%= link_to 'キャンセル', '#', data: {
controller: "modals",
action: 'modals#click->close'
} %>
モーダルボタンを作成する
リンクをクリックしたらモーダルフォームを表示させます。
<%= link_to '投稿する',
new_blog_path,
data: { turbo_frame: 'modal' },
%>
turbo-frame
タグにURLを追加されました。
stimulusコントローラーを作成する
bin/rails g stimulus modals
create app/javascript/controllers/modals_controller.js
モーダルにhidden
クラスを追加しページ上に非表示させます。
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ['modal']
connect(){
}
close(e){
e.preventDefault();
const modal = document.getElementById("modal");
modal.classList.add("hidden");
}
}
ページをリロードさせたいとき
モーダルからフォームの送信の処理を行う場合、送信後にid="modal"
の要素がないのでcontent-missing
のエラーがでます。
そういう時にページをリロードさせたいですね。
対応方法としては、リスポンスからもう一度ページにアクセスさせます。
リスポンス->content-missing
->visit(response.url);
document.addEventListener("turbo:frame-missing", (event) => {
const { detail: { response, visit } } = event;
event.preventDefault();
visit(response.url);
});
終わりに
こちらの方法、ページをリロードせずに新しいコンテンツを表示させたい時にはすごい便利だと感じました。
Discussion