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

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

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

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

Ruby on Rails

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

Ajax

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

Q&A

解決済

1回答

921閲覧

RailsでAjaxを制御しつつ、画面遷移を有効にするには?

FKM

総合スコア3644

Ruby on Rails 6

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

Ruby on Rails

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

Ajax

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

0グッド

0クリップ

投稿2021/04/06 04:40

Rails6でAjax制御のシステムを開発していて、再び解決しない問題に直面したので質問させていただきます。

Ruby : 2.6.6
Rails :6.1.3
centos7.3
Apache2.4.46

発生している問題・エラーメッセージ

以前から実装を続けているRailsでのAjax実装なのですが、Ajaxがうまくいった反面、フォーム内に実装された詳細、編集画面遷移用のボタンが、1度目のクリックで遷移しなくなっているので、遷移できるようにしたいです。

コンソールでイベント発火を確認したところAjaxが干渉しているようで、一度目の押下による画面遷移用ボタンは非同期通信となってしまいます(不思議なことにjQueryのセレクタ外の部分が干渉してしまいます)。二度目の押下だと遷移します(Ajaxは発火しない)。

上の検索用フォームを実行した場合はAjaxを実行し、下の結果一覧の遷移ボタンを押下した場合は画面遷移するようにしたいのですがうまくいきません。

該当のソースコード

ビュー(index.html.erb)

erb

1<%- model_class = City -%> 2 3<div class="panel panel-default" id="list"> 4 <div class="panel-heading"> 5 <div class="panel-title">地方の選択</div> 6 </div> 7 <%= search_form_for(@q , :id=>'city-form', :method=> 'post',:remote => true) do |f| %> 8 <div class="panel-body" id="ajax-contents"> 9 <div class="row"> 10 <!-- 地方の選択 --> 11 <div class="col-sm-12"> 12 <%= f.collection_check_boxes(:region_in,@regions, :region, :region,include_hidden: false) do |b| %> 13 <label class="checkbox-inline"> 14 <%= b.check_box class:"form-control2" do %> 15 <%= b.check_box + b.text %> 16     <% end %> 17 <%= b.label {b.text} %> 18 </label> 19 <% end %> 20 </div><!-- col-sm-12 --> 21 <!-- 都道府県名の完全一致検索 --> 22 <div class="col-sm-6"> 23 <div class="form-group"> 24 <%= f.label :'都道府県選択' %> 25 <%= f.select :pref_no_eq,Pref::PREF.to_a,{},{class:'form-control'} %> 26 </div><!-- form-group --> 27 </div><!-- col-sm-6 --> 28 29 <!-- 市名の部分一致検索 --> 30 <div class="col-sm-4"> 31 <div class="form-group"> 32 <%= f.label :city_name_cont %> 33 <%= f.text_field :city_name_cont, class: "form-control", placeholder: "部分一致" %> 34 </div> 35 </div> 36 </div><!-- @row --> 37 38 <div class="row"> 39 <!-- 人口の範囲検索 --> 40 <div class="form-group"> 41 <div class="col-sm-12 form-inline"> 42 <%= f.label :'人口の範囲検索' %> 43 <%= f.search_field :population_gteq, class: "form-control", placeholder: "最低値" %> 4445 <%= f.search_field :population_lteq, class: "form-control", placeholder: "最高値" %> 46 <%= f.submit class: "btn btn-primary btn-search btn-hide", id: "sbm" %> 47 <%= link_to 'クリア', url_for, class: "btn btn-default" %> 48 <%= link_to t('.new', :default => t("helpers.links.new")),new_city_path,:class => 'btn btn-primary' %> 49 </div><!-- form-inline --> 50 </div> 51 </div><!-- @row --> 52 </div><!-- #ajax-contents --> 53 <% end %> 54 <div class="table"> 55 <table class="table table-striped" id="tbl"> 56 <thead> 57 <tr> 58 <th><%= model_class.human_attribute_name(:id) %></th> 59 <th><%= model_class.human_attribute_name(:base_no) %></th> 60 <th><%= model_class.human_attribute_name(:city_name) %></th> 61 <th><%= model_class.human_attribute_name(:pref_no) %></th> 62 <th><%= model_class.human_attribute_name(:population) %></th> 63 <th><%=t '.actions', :default => t("helpers.actions") %></th> 64 </tr> 65 </thead> 66 <tbody id="ajax-response-wrapper"> 67 <%= render 'ajax_container' %> 68 </tbody> 69 </table> 70 <div id="pager"><%= render 'ajax_pager' %></div> 71 </div> 72</div>

制御用スクリプト(ajax_controll.js)

js

1import * as $ from "jquery"; 2import Rails from "@rails/ujs"; 3 4function register_callback(){ 5 jQuery(function(){ 6 let data 7//対象となるセレクタの外側にまでAjaxが干渉し、formの外側のconsole.logが表示される 8 $("#city-form").each(function(){ 9 $("#ajax-contents").on('change focusout',function(e){ 10 console.log("Ajax") 11 Rails.fire($('#city-form').get(0), 'submit') 12 }) 13 }) 14 $("#city-form").on( 15 "ajax:complete", 16 function(d){ 17 //console.log("BO") 18 if(d.detail[0].status == 200){ 19 data = d.detail[0].responseText 20 data = $.parseJSON(data) 21 //console.log("KU") 22 $('#ajax-response-wrapper').empty().append(data.container) 23 $('#pager').empty().append(data.pager) 24 } 25 } 26 ) 27 $("#city-form").on("ajax:fail",function(event,data,status,xhr){ 28 alert("fail!") 29 }) 30   }) 31} 32 33window.register_callback = register_callback;

コントローラ(cities_controller.rb)

rb

1#前略 2 def index 3 query = "select distinct(region) as region from cities group by region order by pref_no" 4 @regions = City.find_by_sql(query) 5 unless params[:q].blank? 6 logger.debug('TR') 7 @q = City.ransack(params[:q]) 8 @q.sorts = 'population desc' if @q.sorts.empty? 9 @cities = @q.result.page(params[:page]).per(10) 10 #コンテナのレンダリング 11 #p_cities = render_to_string( 12 # partial: 'ajax_container', 13 # locals: { :cities => @cities}, 14 #) 15 #ページャーのレンダリング 16 p_pager = render_to_string( 17 partial: 'ajax_pager', 18 locals: { :cities => @cities }, 19 remote: true 20 ) 21 if request.xhr? 22 #logger.debug("Ajax成功!") 23 render partial: "ajax_container", 24 locals: 25 { 26 container: p_cities, 27 pager: p_pager, 28 } 29 end 30 else 31 @q = City.ransack(params[:q]) 32 @q.sorts = 'population desc' if @q.sorts.empty? 33 @cities = @q.result.page(params[:page]).per(10) 34 end 35 end 36#後略

パーシャル(_ajax_container.erb)

rb

1 <% @cities.each do |city| %> 2 <tr id="t"> 3 <td><%= link_to city.id, city_path(city) %></td> 4 <td><%= city.base_no %></td> 5 <td><%= city.city_name %></td> 6 <td><%= city.pref_no %></td> 7 <td><%= city.population %></td> 8 <td> 9 <%= link_to t('.show', :default => t("helpers.links.show")), 10 city_path(city), :class => 'btn btn-default btn-xs' %> 11 <%= link_to t('.edit', :default => t("helpers.links.edit")), 12 edit_city_path(city), :class => 'btn btn-default btn-xs' %> 13 <%= link_to t('.destroy', :default => t("helpers.links.destroy")), 14 city_path(city), 15 :method => :delete, 16 :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) }, 17 :class => 'btn btn-xs btn-danger' %> 18 </td> 19 20 </tr> 21 <% end %>

試したこと

jQuery内で制御を振り分けようとした → 決め手となる判定文が見つからなかったので保留
フォームの位置をずらした → 効果なし
テーブル部分にもフォームを作り、local: trueとした → 効果なし

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

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

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

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

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

neko_daisuki

2021/04/07 13:53

ajax-contents の focusout が発火しているだけということはありませんか?
FKM

2021/04/08 00:11

それでした、またBAにさせていただきますので、その旨回答いただけたらと思います。 ですが、なぜセレクタ外の部分が反応したのか、その理由もご説明いただけると大変助かります。
guest

回答1

0

ベストアンサー

セレクタ外の部分が反応しているように見えるだけで、
実際には #ajax-contents の focusout が反応しています。

このサンプルでは、#ajax-contents に見立てたボックスにフォーカスを与えた後に
(セレクタ外の)ボタンをクリック、または背景をクリックで focusout が発生します。

つまりセレクタ外の部分をクリックすると focusout が発生し、
あたかもセレクタ外の部分が反応しているように見えます。

投稿2021/04/08 00:42

neko_daisuki

総合スコア2090

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

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

FKM

2021/04/08 01:00

そういうことだったんですね。focusoutの挙動はもっと調べておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問