質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

4429閲覧

【Rails6,Bootstrap5,JavaScript】フォームの値をAjaxでPOSTした後にモーダルを閉じたい

Hamadust

総合スコア5

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/07/02 11:15

編集2021/07/02 11:53

前提・実現したいこと

Rails6でAjaxを用いたTODOアプリを作成しています。

Modalウィンドウ内のフォームでメッセージをAjaxで投稿投稿後、Modalウィンドウを閉じる
という動作を実現したいのですが、上手くいきません。

すでに開かれているモーダルの要素を取得し、それを「閉じる」という動作を実行したいです。

環境

  • Rails 6.0.3
  • Bootstrap 5.0.0-beta3

イメージ説明

該当のソースコード

erb

1<!-- app/views/messages/index.html.erb --> 2 3<!-- モーダルのトリガーボタン --> 4<%= link_to 'NEW TASK CREATE', 5 new_message_path, 6 data: { remote: true }, 7 class: "btn btn-primary", 8 id: :modalButton %> 9 10<!-- モーダルをレンダリング --> 11<%= render 'modal' %> 12 13<div id="messages"> 14 <%= render @messages %> 15</div>

erb

1<!-- app/views/messages/_modal.html.erb --> 2 3<!-- Modal --> 4<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> 5 <div class="modal-dialog"> 6 <div class="modal-content"> 7 <div class="modal-header"> 8 <h5 class="modal-title" id="exampleModalLabel">Modal title</h5> 9 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 10 </div> 11 <div class="modal-body"> 12 <!-- フォームをレンダリング --> 13 <%= render 'form', message: Message.new, value: '投稿' %> 14 </div> 15 </div> 16 </div> 17</div>

erb

1<!-- app/views/messages/_form.html.erb --> 2 3<%= form_with model: message, local: false do |f| %> 4 <%= f.text_field :content, autocomplete: 'off' %> 5 6 <div class="modal-footer"> 7 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> 8 <%= f.submit value, class: "btn btn-primary", id: "submitButton" %> 9 </div> 10 <% if value == '更新' %> 11 <%= link_to '取消', new_message_path, data: { remote: true } %> 12 <% end %> 13<% end %>

js

1// app/views/messages/new.js.erb 2// indexの「NEW TASK CREATE」をクリックしたらこちらの処理が流れてモーダルが開く 3 4// モーダル内のフォームを取得 5var form = document.getElementsByTagName('form')[0] 6// フォームのレンダリング 7form.outerHTML = '<%= j(render 'form', message: Message.new, value: '投稿') %>' 8 9// モーダルを開く ================================================================== 10// 「NEW TASK CREATE」ボタンを取得 11var modalButton = document.getElementById('modalButton'); 12 13// モーダルを新規に作成 14var exampleModal = new bootstrap.Modal(document.getElementById('exampleModal'), { 15 keyboard: false 16}) 17 18// モーダルを開く 19modalButton.addEventListener('click', function () { 20 exampleModal.show(); 21 console.log('[new_message_path Modal Open]') 22}) 23// ============================================================================== 24 25

js

1// app/views/messages/create.js.erb 2// フォームの「投稿」ボタンがクリックされたら投稿内容がPOSTされ、こちらの処理が流れる 3 4// メッセージ一覧の一番下に新規メッセージを追加する 5document.getElementById('messages').insertAdjacentHTML('beforeend', '<%= j(render @message) %>') 6// フォームのインプットを空にする 7document.getElementById('message_content').value = '' 8 9console.log('[POST]') 10 11// モーダルを閉じる動作(エラーが出る)============================ 12// モーダルを取得 13var exampleModal = document.getElementById('exampleModal') 14 15// モーダルを閉じる 16exampleModal.hide() 17console.log('hide') 18 19// Uncaught TypeError: exampleModal.hide is not a function 20// at <anonymous>:11:14 21// at processResponse (rails-ujs.js:283) 22// at rails-ujs.js:196 23// at XMLHttpRequest.xhr.onreadystatechange (rails-ujs.js:264) 24 25// ========================================================= 26

試したこと

モーダルウィンドウが表示された時に、HTML、CSSにクラス名が変更されたり要素が増えます。

html

1<body class=vsc-initialized modal-open> 2... 3 <div class="modal fade show" ...> 4 ... 5 </div> 6... 7 <div class="modal-backdrop fade show"> 8</body>

これらの要素を「submitButton」がクリックされた時に
jsで削除したりすることを試しましたが、その後の動作に異常が起きます。
Ajaxを諦めれば全てうまくいくのですが、どうしても実現したいと考えています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

投稿ボタンを押すとajaxでPOSTされるのですよね?
ではpostしているところ(完了後)でhide();すれば良いのでは?

投稿2021/07/02 11:33

yuki84web

総合スコア1857

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hamadust

2021/07/02 12:00

ご回答ありがとうございます。ソースコードを一部修正しています。 POST後にcreate.js.erbが呼び出されます。(ソースコードのコメントを付け忘れていました) そこでモーダルを取得してhide();させているのですが、エラーが出ます。 bootstrap5のリファレンスにもhide()で閉じる記述があったのですが…。 https://getbootstrap.jp/docs/5.0/components/modal/#hide
Hamadust

2021/07/02 14:38

お調べいただきありがとうございます。 const container = document.getElementById("exampleModal"); const modal = new bootstrap.Modal(container); modal.hide(); お調べいただいたコードを試したのですが、モーダルは閉じませんでした…。 modal.hide(); → modal.toggle();にしたところ、 const modal = new bootstrap.Modal(container);で作成されたモーダルが重なってしまいました。 new.js.erbで記述した // モーダルを新規に作成 var exampleModal = new bootstrap.Modal(document.getElementById('exampleModal'), { keyboard: false }) このモーダルインスタンスを POST後に処理されるcreate.js.erbで取得できればよいのですが…。
Hamadust

2021/07/03 09:34

解決しました。 モーダルを構成する要素を全て削除することで動作させる上では解決しました。 時間を割いて海外のコミュニティからの回答も提示していただきありがとうございました。 動作が不安定?(1度目のボタン押下ではモーダルが開かない)という問題も残っていますが、 こちらはなんとかなると思います。 ご回答がきっかけとなり、新たな知見が得られました。 また何かありましたら、よろしくお願いいたします。
guest

0

自己解決

自己解決致しましたので、ソースコードを載せます。
方法は、モーダルを生成している要素の削除を行い、モーダルを消しました
ボタンクリックを行うとモーダルは再度生成されます。

js

1// app/views/create.js.erb 2 3// フォームの「投稿」ボタンがクリックするとPOSTリクエスト。 こちらの処理が流れる 4 5// メッセージ一覧の一番下に新規メッセージを追加する 6document.getElementById('messages').insertAdjacentHTML('beforeend', '<%= j(render @message) %>') 7// フォームのインプットを初期化する 8document.getElementById('message_content').value = '' 9 10console.log('[POST]') 11 12// モーダルを閉じる動作(モーダルを生成している要素の削除を行う)====== 13 14// モーダルを取得 15var modal = document.getElementById('exampleModal') 16// モーダルを表示させているクラスを削除 17modal.classList.remove('fade') 18modal.classList.remove('show') 19// モーダルのdisplayを'none'にする 20modal.style.display = 'none' 21 22// 背景の透過した黒いレイヤーを取得・削除 23var backdrop = document.getElementsByClassName('modal-backdrop')[0] 24backdrop.remove() 25 26// bodyタグの'modal-open'クラスを削除 27var body = document.getElementsByTagName('body')[0] 28body.classList.remove('modal-open') 29 30// =========================================================

投稿2021/07/03 09:43

Hamadust

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問