前提・実現したいこと
質問ページをご覧いただきましてありがとうございます!
現在RubyonRailsで利用ユーザーが部屋を作成して、作成された部屋を一覧表示する機能を非同期通信で行うべく、JavascriptでAjaxを利用して実装しております。
流れとしては
①ページ上のルーム作成ボタンをクリック
②モーダルウィンドウ上に部屋名と部屋説明を入力するフォームと、作成・キャンセルボタンが表示される。
③フォームに情報を記入後、作成ボタンを押すことでClickイベントが発火し、フォーム内容がRailsの該当コントローラーのCreateアクションへ送信される。
④Createアクション内でフォーム内容をデータベースに登録し、レスポンスを返します。
ここまでの流れは実装済みであり、作成した部屋はリロードを行うことで一覧に表示される仕組みになっています。
発生している問題・エラーメッセージ
上記の④から、現状はjavascript上でlocation.reload();にて強制的にリロードをかけることで一覧表示を更新している状態です。
この部分をinsertAdjacentHTMLを使って、レスポンスの情報を元に追加したルーム部分を部分テンプレート化して、この部分テンプレートを挿入して表示させようとしております。(以下のような感じです)
javascript
1document.getElementById('挿入部分のid').insertAdjacentHTML('beforeend', '<%= render "部分テンプレート名" %>')
ただ当然Javascript上なので、<%= render %>部分は認識されず、文字としてそのまま挿入される状態です。
色々検索をかけてescape_javascriptなどのエスケープを試してみてもダメで、実装方法に詰まっている状態です。
ですので、Javascript上で部分テンプレートを指定する方法や代替案などがあればご教授頂けますと幸いです。
該当のソースコード
html
1(部屋一覧表示部分抜粋) 2<div class="room-screen-box"> 3 <div class="room-screen-lists"> 4 5 <% @rooms.each do |room| %> 6 <div class="room-screen-list-box"> 7 <div class="room-screen-list-header"> 8 <div class="room-screen-list-room-name"><%= link_to room.room_name,"#" %></div> 9 <div class="room-screen-list-btn"> 10 <% unless RoomUser.where(room_id: room.id).exists?(user_id: current_user.id) %> 11 <%= form_with model: @roomuser, local: true do |f| %> 12 <input name="room_user[user_id]" type="hidden" value=<%= current_user.id %>> 13 <input name="room_user[room_id]" type="hidden" value=<%= room.id %>> 14 <%= f.submit "参加", class:"room-entry-btn" %> 15 <% end %> 16 <% else %> 17 <div class="room-exist-btn"> 18 <%= link_to "退出", room_user_path(room), method: :delete %> 19 </div> 20 <% end %> 21 <% if room.owner_id == current_user.id %> 22 <div class="room-delete-btn"> 23 <%= link_to "削除", room_path(room), method: :delete, data: { confirm: '本当に削除しても良いですか?' } %> 24 </div> 25 <% end %> 26 </div> 27 </div> 28 <div class="room-screen-list-body"> 29 <div class="room-screen-list-owner-name">オーナー名:<%= User.find(room.owner_id).nickname %></div> 30 <div class="room-screen-list-create-date">作成日時:<%= room.created_at.to_s(:datetime_jp) %></div> 31 </div> 32 </div> 33 <% end %> 34 35 </div> 36</div>
html
1(モーダルウィンドウ部分抜粋) 2<div id="modal-room-create" class="modal-room-create"> 3 <p>ルームの作成</p> 4 <%= form_with model: @room, id: 'modal-room-create-form', local: true do |f| %> 5 <%= render "devise/shared/error_messages", model: f.object %> 6 <div class="field"> 7 <label class="form-text">ルーム名</label> 8 <%= f.text_field :room_name, placeholder:"ルーム名 (20文字以内)", maxlength:"20", class:"form-default" %> 9 </div> 10 11 <div class="field"> 12 <label class="form-text">ルーム説明文</label> 13 <%= f.text_field :room_description, placeholder:"ルーム説明 (100文字以内)", maxlength:"100", class:"form-default" %> 14 </div> 15 16 <input name="room[user_ids][]" type="hidden" value=<%= current_user.id %>> 17 18 <div class="register-btn"> 19 <%= f.submit "作成", class:"register-blue-btn", id:"modal-create-btn" %> 20 </div> 21 <% end %> 22 <button class="register-blue-btn" id="room-create-cancel">キャンセル</button> 23 24</div> 25 26<div id="modal-overlay" class="modal-overlay"></div>
html
1(挿入したい部分テンプレート) 2<div class="room-screen-list-box"> 3 <div class="room-screen-list-header"> 4 <div class="room-screen-list-room-name"><%= link_to room.room_name, room_posts_path(room) %></div> 5 <div class="room-screen-list-btn"> 6 <% unless RoomUser.where(room_id: room.id).exists?(user_id: current_user.id) %> 7 <%= form_with model: @roomuser, local: true do |f| %> 8 <input name="room_user[user_id]" type="hidden" value=<%= current_user.id %>> 9 <input name="room_user[room_id]" type="hidden" value=<%= room.id %>> 10 <%= f.submit "参加", class:"room-entry-btn" %> 11 <% end %> 12 <% else %> 13 <div class="room-exist-btn"> 14 <%= link_to "退出", room_user_path(room), method: :delete %> 15 </div> 16 <% end %> 17 <% if room.owner_id == current_user.id %> 18 <div class="room-delete-btn"> 19 <%= link_to "削除", room_path(room), method: :delete, data: { confirm: '本当に削除しても良いですか?' } %> 20 </div> 21 <% end %> 22 </div> 23 </div> 24 <div class="room-screen-list-body"> 25 <div class="room-screen-list-owner-name">オーナー名:<%= User.find(room.owner_id).nickname %></div> 26 <div class="room-screen-list-create-date">作成日時:<%= room.created_at.to_s(:datetime_jp) %></div> 27 </div> 28</div>
javascript
1(モーダルウィンドウの表示及び部屋作成時の挙動部分抜粋) 2window.addEventListener('load', function(){ 3 4 const modalRoomCreate = document.getElementById("modal-room-create") 5 const modalOverlay = document.getElementById("modal-overlay") 6 const roomCreateBtn = document.getElementById("room-create-btn") 7 const modalCreateBtn = document.getElementById("modal-create-btn") 8 const modalRoomCancel = document.getElementById('room-create-cancel'); 9 10 roomCreateBtn.addEventListener('click', function() { 11 modalRoomCreate.classList.add("active") 12 modalOverlay.classList.add("active") 13 }) 14 15 modalCreateBtn.addEventListener('click', function(e) { 16 e.preventDefault(); 17 18 const formData = new FormData(document.getElementById("modal-room-create-form")) 19 const XHR = new XMLHttpRequest(); 20 XHR.open("POST", `/rooms`, true) 21 XHR.responseType = "json"; 22 XHR.send(formData); 23 24 XHR.onload = () => { 25 document.getElementById("modal-room-create-form").reset(); 26 if (XHR.status == 422) { 27 alert(`入力項目エラー: ルーム作成のフォームは全て入力してください。`); 28 return null; 29 } 30 else if (XHR.status != 200) { 31 alert(`Error ${XHR.status}: ${XHR.statusText}`); 32 return null; 33 } 34 35 document.getElementById("modal-room-create-form").reset(); 36 modalRoomCreate.classList.remove("active") 37 modalOverlay.classList.remove("active") 38 39 location.reload(); 40 }) 41 42 modalRoomCancel.addEventListener('click', function() { 43 document.getElementById("modal-room-create-form").reset(); 44 modalRoomCreate.classList.remove("active") 45 modalOverlay.classList.remove("active") 46 }) 47 modalOverlay.addEventListener('click', function() { 48 document.getElementById("modal-room-create-form").reset(); 49 modalRoomCreate.classList.remove("active") 50 modalOverlay.classList.remove("active") 51 }) 52})
RubyonRails
1(コントローラー部分抜粋) 2class RoomsController < ApplicationController 3 def index 4 @rooms = Room.all.order(created_at: "DESC") 5 @room = Room.new 6 @roomuser = RoomUser.new 7 end 8 9 def create 10 @room = Room.new(room_params) 11 if @room.save 12 render json: { post: @room } 13 else 14 render json: { post: @room }, status: 422 15 end 16 end 17 18 def search 19 @rooms = Room.search(params[:keyword]) 20 end 21 22 def destroy 23 room = Room.find(params[:id]) 24 room.destroy 25 redirect_to root_path 26 end 27 28 private 29 30 def room_params 31 params.require(:room).permit(:room_name, :room_description, user_ids: []).merge(owner_id: current_user.id) 32 end 33 34end
補足情報(FW/ツールのバージョンなど)
Ruby on Rails6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/02 04:03
2020/12/02 04:11
2020/12/05 01:14