[Rails]モーダルウィンドウを作成する(データを削除前に再度確認する)

# モーダルウィンドウとは？

モーダルウィンドウというのは下のGIFのようなもので、
間違って削除してしまった…というのを防ぐことができるポップアップのようなものです。
今回、こちらと同じものを作成します。

![19e47dcaaf847fef9bdbbd0a4070fd68.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/bee8ecf8-4f4b-eaeb-8ae9-99b3f6808132.gif)

# 方針・前提条件
コントローラーなどで__ボタンやリンクを押せばデータが削除される__機能を
ページ上に既に実装されていることが前提です。
(もちろん削除だけじゃなくて登録や実施などでもOK)

また、いろんな作り方があるとは思いますが、
今回は下記の条件のもとで作成しました。


- preventDefaultは使わず、モーダル用と送信用削除ボタンの２つを使用する。
- 削除ボタンをCSSで非表示にし、モーダルウィンドウの削除ボタンが押された時に初めて実施される。
- モーダルウィンドウとオーバーレイを表示するボタンをページ上に設置する。
- モーダルウィンドウの要素はhtml.hamlファイル上に記載する（メッセージ、ボタン２個）。

__バージョン__

- Rails 5.0.7.2
- ruby 2.3.1
- haml導入

# サンプルコード

```index.html.haml
%button#modal-open-btn この商品を削除する
= link_to "", item_path(@item), method: :DELETE, id: 'item-delete-btn'
#overlay
  #modalWindow
    .modal-message-box
      %div 確認
      %div 本当に削除しますか？
    %button#modal-close-btn キャンセル
    %button#delete-comformation-btn 削除する
```

↑この部分はコントローラーなどに合わせて記載してください。
`= link_to "", item_path(@item), method: :DELETE, id: 'item-delete-btn'`

```modal.js
document.addEventListener(
  "DOMContentLoaded", e => {
    let modal_open = document.getElementById("modal-open-btn");
    modal_open.onclick = function () {
      $('#overlay').fadeIn();
      document.getElementById('modal-close-btn').onclick = function () {
        $('#overlay').fadeOut();
      };
      document.getElementById("delete-comformation-btn").onclick = function () {
        document.getElementById("item-delete-btn").click();
      };
    };
  },
  false
);
```

```modal.scss
#overlay {
//モーダルウィンドウの背景を設定
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
//透過度をつける
  background: rgba(0, 0, 0, 0.3);
  display: none;
  z-index: 1;
}

#modalWindow {
// モーダルウィンドウの画面を設定(高さ・幅は調整ください)
  width: 500px;
  height: 200px;
  position: absolute;
//トップからの場所を指定（topをいじれば高さが調整できます）
  top: 20%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  z-index: 2;
//flexboxで子要素のボタンとメッセージボックスの要素を配置する
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;

  .modal-message-box {
    width: 100%;
//下記heightの60pxはボタンの高さで、それを画面の大きさから引いています。
    height: calc(100% - 60px);
    text-align: center;
//flexboxで文字の配置を決める（縦方向、中央揃え）
    display: flex;
    flex-direction: column;
    justify-content: space-around;
  }

  #modal-close-btn {
    width: 50%;
    height: 60px;
  }

  #delete-comformation-btn {
    width: 50%;
    height: 60px;
  }
}

.item-delete-btn {
//削除ボタンの非表示
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
```

完成部品１ ボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/0720e4da-b621-201e-30fc-d341fafac842.png)
完成部品２ モーダルウィンドウとオーバーレイ（背景）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224314/e8458fb2-1a3f-3189-1be8-b14a9ce2887a.png)


# 参考

- [Modalコンテンツの幅を％指定したときに左右天地の中央に配置するCSS設定｜Qiita](https://qiita.com/katsukii/items/e3af06a43622fe684819)
- [JQueryでオーバーレイとモーダルウィンドウを作ってみよう！｜ExRecord](http://exrecord.net/how-to-create-overlay-and-modal-window-in-jquery)
- [日本語対応！CSS Flexboxのチートシートを作ったので配布します
｜Webクリエイターボックス](https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet)