Bootstrap5のモーダルを連動しているボタン以外で制御したかったが、古いバージョンの情報だったりclassをJavaScriptで上書きするだったりと、よくわからないやり方しか見つからなかったので書く。
やりたいこと
Bootstrap5のモーダルウィンドウをエラーダイアログ的なノリで使いたい。
data-bs-toggleとかdata-bs-targetが着いてるボタンで制御するのではなくて、JavaScriptで制御して他の処理との流れで開閉したい。
環境
- Bootstrap:5.0.2
やりかた
対象のモーダルのエレメントを引数にモーダルのインスタンスを作成し、そこからshow()やhide()といったメソッドを呼び出すだけ。
※BootstrapのJavaScript必須
controlModal.js
const myModal = new bootstrap.Modal(document.getElementById('myModal'));
// 開く
myModal.show();
// 閉じる
myModal.hide();
サンプル
inputでファイルが選択されていなかったらモーダルダイアログを出すサンプルです。
html1枚でできているのでコピーして動作確認してみてください。
modal.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- BootstrapのCSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  <title>モーダルをJavaScriptで制御</title>
</head>
<body>
  <div class="container">
    <!-- メインコンテンツ -->
    <div class="mb-3 w-50">
      <label for="formFile" class="form-label">モーダルのテスト</label>
      <input class="form-control" type="file" id="formFile">
      <button id="upload" class="btn btn-primary">アップロード</button>
    </div>
    <!-- エラーダイアログ用のモーダル(id重要) -->
    <div class="modal fade" id="errorModal" tabindex="-1" aria-labelledby="errorModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="errorModalLabel">エラー</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            ファイルが選択されていません
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">閉じる</button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- BootstrapのJavaScript(先に読み込む) -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  <!-- モーダルをコントロールするJavaScript -->
  <script>
    // input読み取り用
    const inputFile = document.getElementById('formFile');
    const uploadBtn = document.getElementById('upload');
    // エレメントを引数にしているのがポイント
    const errorModal = new bootstrap.Modal(document.getElementById('errorModal'));
    // ボタンがクリックされたら~っていうよくある処理
    uploadBtn.addEventListener('click', () => {
      const input = inputFile.files[0];
      if (!input) {
        // ファイルが選択されていなかったらモーダルを開く
        errorModal.show();
      } else {
        // 通常処理(今回は何もなし)
      }
    });
  </script>
</body>
</html>
おわりに
私はこの情報に辿り着くまでにまあまあ時間を使ってしまったので、そういう人が減るといいなと思います。
