Railsでモーダルの表示処理をまとめて衝突しないように管理する方法を紹介します。
背景
ツクリンクを運営する中でモーダルが少しづつ増え、衝突することがあったためモーダルの優先順位を付け、衝突しないよう実装をしました。
実装
前提
以下の3つのモーダルがあるとします。
- A: 初回ログインで出すモーダル(全ページ)
- B: 特定のユーザーにだけお知らせを出すモーダル(全ページ)
- C: 特定のページで出すモーダル(Posts#show)
コードサンプル
全ページに出すモーダルはApplicationControllerで該当ユーザーか判断しモーダルに必要な情報をセットします。
# controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :set_modal_A
before_action :set_modal_B
def set_modal_A
return if cookies['modal_A'].present? # 表示済みなら何もしない
if is_first_signed_in? # 初回ログインか?
@modal_A = { title: '表示に必要な情報など' }
end
end
def set_modal_B
return if cookies['modal_B'].present? # 表示済みなら何もしない
if show_notice? # お知らせを出すユーザーか?
@modal_B = true
end
end
end
Viewごとに出るモーダルは provide
でモーダルをセット
# views/posts/show.html.erb
<% provide :modal, render('modal/C') %>
レイアウトのView(もしくはそれに準ずるパーシャル)でモーダルの出し分けを行います。
ifの上位にあるものが優先され、モーダルが複数renderされるのを防いでいます。
# views/layouts/application.html.erb
<% if yield(:modal).present? %>
<%= yield(:modal) %>
<% elsif @modal_B.present? %>
<%= render 'modal/B' %>
<% elsif @modal_A.present? %>
<%= render 'modal/A' %>
<% end %>
各モーダルのViewでは表示を管理するCookieを保存するなどの処理をしています。
# views/modal/A.html.erb
<% cookies.permanent['modal_A'] = { value: true, expires: 1.day } %>
<div class="modal">お知らせだよ!</div>
※こちらの記事は自ブログからの転載です
https://akinov.hatenablog.com/entry/2020/05/01/222151