@kuma49225

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

bootstrap loaded:false モーダルの動作不良

bootstrapが動作せず、モーダルが正常に機能しない。

Ruby on Railsで模擬宿泊予約サイトをつくっています。
外部で受講している講座の課題となります。
モーダルが正常に動作しない課題があり、エラーメッセージ等も明確なものがなく苦慮しています。

発生している問題・エラー

スクリーンショット 2024-07-14 10.05.05.png

予約内容の削除等を行うモーダルの機能が意図した通りに動作しません。
モーダルは添付のように表示されますが、こちらが設定した内容ではなく、さらに削除ボタンを押しても動作しません。
検証ツール上もbootstrap loaded :false は表示されますが、エラーメッセージ等はありません。

また指導者の方にgithub上からソースコードをインストールいただき、試していただいたところbootstrap loaded:trueとなり、削除も動作するとのことで、自身の環境の問題であると考えています。

出ているエラーメッセージを入力
bootstrap loaded :false のみ 
スクリーンショット 2024-07-14 10.08.58.png

該当するソースコード

<!DOCTYPE html>
<html>
<head>
  <title>Potepan Share</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <!-- CSSの読み込み -->
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

  <!-- JavaScriptの読み込み -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>

<body>
  <header>
    <nav class="nav-wrapper">
      <div class="container">
        <a href="/" class="brand-logo">
          <img src="https://rails-02-sample.herokuapp.com/assets/common/logo.png" alt="Potepan Share">
        </a>
        <ul id="nav-mobile" class="right">
          <% if user_signed_in? %>
            <li>
              <a href="#" class="account-menu-toggle">
                <% if current_user.profile_image.present? %>
                  <img src="<%= current_user.profile_image.url %>" alt="Profile Image" class="profile-icon">
                <% else %>
                  <i class="fas fa-user"></i>
                <% end %>
                <%= current_user.name %>
              </a>
              <ul class="account-menu">
                <li><%= link_to '施設の新規登録', new_hotel_path %></li>
                <li class="separator"></li>
                <li><%= link_to '予約済み一覧', hotel_reservations_path(current_user) %></li>
                <li><%= link_to '登録済み一覧', my_hotels_hotels_path %></li>
                <li><%= link_to 'アカウント設定', show_account_account_settings_path %></li>
                <li class="separator"></li>
                <li><%= link_to 'ログアウト', destroy_user_session_path, method: :delete %></li>
              </ul>
            </li>
          <% else %>
            <li><%= link_to 'ログイン', new_user_session_path %></li>
            <li><%= link_to '新規登録', new_user_registration_path, class: 'register-button' %></li>
          <% end %>
        </ul>
      </div>
    </nav>
  </header>
  <main>
    <%= yield %>
  </main>
  <footer>
    <div class="footer-content">
      <a href="/" class="footer-logo">
        <img src="https://rails-02-sample.herokuapp.com/assets/common/logo.png" alt="Potepan Share">
      </a>
      <p>&copy; Potepan Share 2024 All rights reserved</p>
    </div>
  </footer>

  <!-- 削除確認モーダル -->
  <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="deleteModalLabel">削除の確認</h5>
          <button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <p id="deleteModalBody"></p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">キャンセル</button>
          <button type="button" class="btn btn-danger" id="confirmDeleteButton">削除</button>
        </div>
      </div>
    </div>
  </div>

  <script>
    document.addEventListener('turbolinks:load', () => {
      // モーダルの初期化などのコードをここに追加
      $('#deleteModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget); // ボタンがモーダルをトリガーした
        var recipient = button.data('whatever'); // ボタンから情報を抽出

        // モーダルのボディに情報を更新
        var modal = $(this);
        modal.find('.modal-body').text('Are you sure you want to delete ' + recipient + '?');
      });
    });
  </script>
</body>
</html>




### 自分で試したこと
rails newでプロジェクトを新規で作成し、そこにフォルダを移し替えしたが改善せず
その他、キャッシュのクリアやnodeやnpmのバージョンや依存関係を再インストールの実施
0 likes

2Answer

bootstrap のことを聞いているのだから、そのバージョンぐらいは書きましょう。あと、対象とするブラウザは何かとそのバージョンも。

0Like

申し訳ありません。
bootstrap5.3.0
対象のブラウザはバージョン: 126.0.6478.127(Official Build) (x86_64)です。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.4'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '6.1.3.2'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'devise'
gem 'bootstrap', '~> 5.3.0'
gem 'carrierwave', '~> 2.0'
gem 'jquery-rails'
0Like

Comments

  1. 質問者が回答欄に書くとどれが質問でどれが回答か分からなくなりますので避けてください。

    対象のブラウザはバージョン: 126.0.6478.127(Official Build) (x86_64)です。

    Windows OS の Chrome ですか?

    問題は recipient が undefined となってしまうのと、削除ボタンクリックの動作が期待と違うことですか? 期待する動作とは?

  2. @kuma49225

    Questioner

    macOSのchromeとなります。
    問題は、まず削除ボタンを押しても一切反応がないことと、apprication.js上で記載しているモーダルの内容が反映されていないことです。下記のコードのlet modalContent以降となります。

    import Rails from "@rails/ujs";
    import Turbolinks from "turbolinks";
    import * as ActiveStorage from "@rails/activestorage";
    import "channels";
    import "bootstrap";
    import "../stylesheets/application";
    
    Rails.start();
    Turbolinks.start();
    ActiveStorage.start();
    
    document.addEventListener("turbolinks:load", function () {
      console.log("JavaScript loaded");
    
      if (typeof jQuery !== 'undefined') {
        console.log("jQuery version:", jQuery.fn.jquery);
      } else {
        console.log("jQuery is not loaded");
      }
    
      const deleteModal = $('#deleteModal');
      const deleteModalBody = $('#deleteModalBody');
      const confirmDeleteButton = $('#confirmDeleteButton');
    
      if (deleteModal.length && deleteModalBody.length && confirmDeleteButton.length) {
        console.log("Modal elements found");
      } else {
        console.log("Modal elements not found");
      }
    
      console.log("Bootstrap loaded:", typeof $.fn.modal === 'function');
    
      // モーダルが表示される際のイベントリスナーを追加
      deleteModal.on('show.bs.modal', function(event) {
        const button = $(event.relatedTarget);
        const hotelName = button.data('hotel-name');
        const checkIn = button.data('check-in');
        const checkOut = button.data('check-out');
        const numberOfPeople = button.data('number-of-people');
        const deleteUrl = button.data('delete-url');
        const isReservation = button.data('is-reservation');
        const imageSrc = button.data('image-src');
        const price = button.data('price');
    
        console.log("hotelName:", hotelName);
        console.log("checkIn:", checkIn);
        console.log("checkOut:", checkOut);
        console.log("numberOfPeople:", numberOfPeople);
        console.log("deleteUrl:", deleteUrl);
        console.log("isReservation:", isReservation);
        console.log("imageSrc:", imageSrc);
        console.log("price:", price);
    
        let modalContent;
        if (isReservation) {
          modalContent = `
            <div class="ConfirmBody">
              <img class="ConfirmBody__image" src="${imageSrc}" alt="${hotelName}">
              <div>
                ${hotelName}<br>
                ${checkIn} ~ ${checkOut}<br>
                ${numberOfPeople}人<br>
                ¥${price}
              </div>
            </div>
            よろしければ「削除」ボタンを押してください。
          `;
        } else {
          modalContent = `
            <div class="ConfirmBody">
              <img class="ConfirmBody__image" src="${imageSrc}" alt="${hotelName}">
              <div>
                ${hotelName}<br>
                ¥${price}〜 / 日
              </div>
            </div>
            よろしければ「削除」ボタンを押してください。
          `;
        }
    
        deleteModalBody.html(modalContent);
    
        // 削除ボタンのイベントリスナーを設定
        confirmDeleteButton.off('click').on('click', function() {
          console.log("Delete button clicked"); // クリックイベントのデバッグメッセージ
          console.log("Sending DELETE request to:", deleteUrl);
    
          Rails.ajax({
            url: deleteUrl,
            type: "DELETE",
            success: function(data) {
              console.log("Delete successful:", data);
              location.reload(); // 成功時にページをリロード
            },
            error: function(err) {
              console.log("Delete failed:", err);
            }
          });
        });
      });
    
      const accountMenuToggle = document.querySelector('.account-menu-toggle');
      const accountMenu = document.querySelector('.account-menu');
    
      if (accountMenuToggle && accountMenu) {
        accountMenuToggle.addEventListener('click', function(event) {
          event.preventDefault();
          accountMenuToggle.parentElement.classList.toggle('show');
        });
    
        document.addEventListener('click', function(event) {
          if (!accountMenuToggle.contains(event.target) && !accountMenu.contains(event.target)) {
            accountMenuToggle.parentElement.classList.remove('show');
          }
        });
      }
    
      const dropdowns = document.querySelectorAll('.dropdown-toggle');
      dropdowns.forEach(dropdown => {
        dropdown.addEventListener('click', function(event) {
          event.preventDefault();
          const menu = this.nextElementSibling;
          menu.classList.toggle('show');
        });
      });
    
      document.addEventListener('click', function(event) {
        dropdowns.forEach(dropdown => {
          const menu = dropdown.nextElementSibling;
          if (menu && !dropdown.contains(event.target) && !menu.contains(event.target)) {
            menu.classList.remove('show');
          }
        });
      });
    });
    
  3. 矢継ぎ早に長~いコードをアップされたのでは読む気力が失われます。問題を再現できる必要最低限までコードに削っていって、それをアップするとか、ちょっと考えてもらえませんか?

    問題を再現できる必要最低限までコードを削っていくというのは、問題の原因を特定して解決するために大変有効な手段なのです。そうすることで自己解決できることも多々あります。Bootstrap Modal は Bootstrap.css と Bootstrap.js で基本的なところは動きます。Ruby とか関係ないところまで、可能であれば html と Bootstrap.css / Bootstrap.js だけになるまで削ってみてください。それでも原因が分からなければ、削ったコードをアップしてもらえば閲覧者・回答者の方でもそれを試すことができ、有用な回答が得られるかもしれません。

Your answer might help someone💌