チーム開発で活用しようと思った技術をアウトプット投稿
目的
以下のようなモーダルウィンドウの実装
商品の写真をクリックすると以下のように表示、背景の黒い部分をクリックすると戻る
開発環境
- Ruby 3.1.2
- Rails 6.1.7
- bootstrap併用(bootstrap自体は実装機能と関係なし)
実装手順
1.モーダルの設置
モーダルを表示させたいページに以下の記述を行う
例)index
ページにshow
ページの内容を表示したい場合はindex
に記述
<div id="mask" class="hidden"></div>
<div id="modal" class="hidden"></div>
2.CSSの設定
今回はbootstrap併用のため
app/javascript/stylesheets
の中にproduct.css
を作成
app/javascript/packs/application
内に以下を記述
import "../stylesheets/product.css"
これでproduct.cssが読み込まれるようになるのでモーダル処理の記述
#mask等の#はidで適応する箇所を指定している
/*#mask、つまり背景の設定*/
#mask {
background-color: rgba(0, 0, 0, 0.5);/*背景色の指定*/
position: fixed; /* スクロールで移動しないようmodalの位置を固定 */
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 1; /*z-index を持つ要素はより小さな要素の上に重なる*/
}
#modal {
position: fixed;/* スクロールで移動しないようmodalの位置を固定 */
top: 20vh; /*上端からの距離の指定、今回は画面上から20%の位置から配置*/
left: 0; /*左からの距離の指定*/
right: 0; /*右からの距離の指定*/
margin: 0 auto; /*上2つと合わせ中央に配置される*/
transform: translate(0, 0) scale(1); /*平行移動(translate)、拡大縮小(scale)の指定*/
transition: 0.2s; /*上記trancsformに要する時間、今回は0.2秒*/
z-index: 2; /*z-index を持つ要素はより小さな要素の上に重なる*/
width: 50vw; /*モーダルの幅の指定、今回はvwを用いて画面の50%幅でモーダルを作成*/
background-color: white; /*背景色*/
border-radius: 8px; /*角の処理、指定することで丸みを帯びる*/
}
#mask.hidden {
opacity: 0; /*透明度*/
visibility: hidden; /*視認性、最初は隠しておきたいのでhiddenを指定*/
}
#modal.hidden {
opacity: 0;
visibility: hidden;
transform: translate(0, 0) scale(0.8);
}
3.モーダル化したい部分の部分テンプレート化、及びコントローラー処理
モーダルとしてshowページを指定したいのでshowページを部分テンプレート化
また今回は商品一覧で、商品の写真をクリックした際にshowページを呼び出したいので、indexのlink_toにremote: true
を指定しJS形式で送信させる
〜省略〜
<%= link_to product_path(product.id), remote: true do %>
<%= image_tag product.get_image(180, 120), class: 'm-1 img-fluid mb-1' %>
<% end %>
〜省略〜
今回はshowページの表示だけなので、特にコントローラーに記述する必要は無いが、送信形式で表示処理を分けたい場合は以下のように記述
def show
# 〜省略〜
respond_to do |format|
format.html
format.js # js形式で送信された場合はこちらが適応され、js.erbを探す
end
# 〜省略〜
end
4.jsファイルの作成
app/views/public/products
内に(要はindex,showと同じフォルダに)show.js.erb
を作成
-
partial:
に先程作成した部分テンプレート -
locals:
に部分テンプレート内に必要な変数を記述
<!--モーダルを取得-->
var modal = document.getElementById('modal');
<!--マスクを取得-->
var mask = document.getElementById('mask');
<!--// # モーダルの中身をshowビューに置き換え-->
<!--// # 部分テンプレートを指定する-->
modal.innerHTML = '<%= escape_javascript(render partial: 'show', locals: { cart: @cart, genres: @genres, product: @product}) %>';
<!--// # hiddenを削除してモーダルとマスクを表示させる。-->
modal.classList.remove('hidden');
mask.classList.remove('hidden');
<!--// # モーダルの外側(マスク)をクリックするとhiddenクラスが書き込まれ、モーダルとマスクが再び非表示となる-->
mask.addEventListener('click', () => {
modal.classList.add('hidden');
mask.classList.add('hidden');
});
これで完成です!
参照
以下記事を参照させて頂きました、ありがとうございます