0

最近、petermac.com の次のチュートリアルを使用して、アプリケーションにカスケード ドロップダウンを実装しようとしました: http://www.petermac.com/rails-3-jquery-and-multi-select-dependencies/

このチュートリアルでは基本的に、カスケード ドロップダウンの実行について説明しています。ここでは、すべてのドロップダウン ボックスが個別のパーシャルであり、親の選択が変更されたときに jQuery onChange イベントが読み込まれます。

これで問題なく動作するようになりました。しかし、実際には、私の選択ボックスは非常に複雑な関係にあります。

したがって、フォームは AuditFunction というモデルに属しており、名前が示すように監査用です。すべての監査にはソースとターゲットがあり、複数のコマンドで比較できます。ソースとターゲットは、3 つの選択ボックスで選択します。最初のボックスはフィールドが含まれるデータベースのタイプを選択します。2 番目のボックスはテーブルを選択し、3 番目のボックスはフィールドを選択します。フィールド ボックスには何千ものオプションを含めることができるため、カスケード ドロップダウンを実装して、ユーザーがフィールドを簡単に選択できるようにしました。

概要を説明すると、私のアクションは次のようになります。

# new.html.erb

<%= simple_form_for @audit_function do |f| %>
  <%= f.input :database_1, :as => :select, :collection => @databases, :include_blank => true %>
  <%= render :partial => 'databases_1'  %>
  <%= render :partial => 'fields_1'  %>
  <%= f.input :database_2, :as => :select, :collection => @databases, :include_blank => true %>
  <%= render :partial => 'databases_2'  %>
  <%= render :partial => 'fields_2'  %>
<% end %>

このための JavaScript は次のようになります。

# jQuery

<script type='text/javascript' charset='utf-8'>
jQuery(function($) {
  // when the #country field changes
  $("#audit_function_database_1").change(function() {
    var database_1 = $('select#audit_function_database_1 :selected').val();
    if(database_1 == "") database_1="0";
    jQuery.get('/audit_functions/update_database_1_id_select/' + database_1, function(data){
        $("#database_1_id").html(data);
    })
    return false;
  });

})
</script>
<script type='text/javascript' charset='utf-8'>
jQuery(function($) {
  // when the #country field changes
  $("#audit_function_database_2").change(function() {
    var database_2 = $('select#audit_function_database_2 :selected').val();
    if(database_2 == "") database_2="0";
    jQuery.get('/audit_functions/update_database_2_id_select/' + database_2, function(data){
        $("#database_2_id").html(data);
    })
    return false;
  });

})

ここでは、database_1_id と field_1_id のパーシャルのみを示しますが、これらはデータベースとフィールド 2 と同じように見えます。

# _databases_1.html.erb

<script type="text/javascript">
  jQuery(function($) {
  $("#audit_function_database_1_id").change(function() {
  var database_1_id = $('select#audit_function_database_1_id :selected').val();
  if(database_1_id == "") database_1_id="0";
  jQuery.get("/audit_functions/update_field_1_id_select/" + ("<%= params[:id] %>_" + database_1_id), function(data){
    $("#field_1_id").html(data);
  })
  return false;
  });
  })
</script>

<%= simple_form_for "audit_function" do |f| %>
  <% if params[:id] %>
<% if params[:id] == "imp" %>
  <%= f.input :database_1_id, collection: AdOriTbl.all.order(ori_filename: :asc).collect{ |a| [a.ori_filename,a.id]} %>
  <% elsif params[:id] == "ori" %>
    <%= f.input :database_1_id, collection: AdOriTbl.all.order(otb_filename: :asc).collect{ |a| [a.otb_filename,a.id]} %>
  <% elsif params[:id] == "mod" %>
    <%= f.input :database_1_id, collection: AdQryMod.all.order(qry_mod_text: :asc).collect{ |a| [a.qry_mod_text,a.id]} %>
  <% end %>
<% end %>
  <% end %>

そして今、ターゲットフィールドを含むファイル。

# _fields_1.html.erb

<%= simple_form_for "audit_function" do |f| %>
  <% if params[:id] %>
    <% if params[:id].gsub(/_{1}\d{1,}\z/, "") == " mod " %>
      <%= f.input :field_1_id, collection: AdQryFld.where(ad_qry_mod_id: params[:id].gsub(/\A\w{1,}_{1}/, "").to_i).order(order_id: :asc).collect{ |f| [f.qry_field_text,f.id]} %>
    <% else %>
      <%= f.input :field_1_id, collection: AdOriFld.where(ad_ori_tbl_id: params[:id].gsub(/\A\w{1,}_{1}/, "").to_i).order(id: :asc).collect{ |f| [f.otb_colhdg,f.id]} %>
    <% end %>
  <% end %>
<% end %>

コントローラーには、javascript でトリガーされたすべてのアクションが含まれます。

# audit_function_conroller.rb

def new
  authorize! :new, :audit_functions
  @audit_function = AuditFunction.new

  @functions = [[I18n.t("text sum"),"sum"],[I18n.t("text quantity"),"quantity"],[I18n.t("text largest_value"),"largest_value"],[I18n.t("text smallest_value"),"smallest_value"]]
  @databases = [[I18n.t("text original_database"),"imp"],[I18n.t("text archive_database"),"ori"],[I18n.t("text query_database"),"mod"]]
end

def update_database_1_id_select
  if params[:id] == "mod"
    type = "mod"
  elsif params[:id] == "ori"
    type = "ori"
  elsif params[:id] == "imp"
    type = "imp"
  end
  render partial: "databases_1", id: type
end

def update_field_1_id_select
  type = params[:id]
  render partial: "fields_1", id: type
end

さて、これはすべて面倒に見えますが、良いことは、それが仕事を成し遂げることです. そして、私のMVCを明確にするために、これらは関係です:

AdOriTbl has_many AdOriFlds
AdOriFld belongs_to AdOriTbl

AdQryMod has_many AdQryFlds
AdQryFld belongs_to AdQryMod

これを読むとき、名前があまり気にならないことを願っています。

ここで問題に戻りましょう。

私が言ったように、このコードは新しいオブジェクトを作成するために機能し、すべてがうまく選択されています。しかし、オブジェクトを編集しようとすると、データベース タイプ (database_1 および database_2) のフィールドのみが入力されます。データベースの ID の選択ボックスはレンダリングされませんが、フィールドのボックスはレンダリングされます。しかし、4 つの ID フィールドはすべて空です。

ここで、すでに持っているものと基本的に似ているjQueryでボックスを手動で埋めようとしましたが、onChangeをトリガーする代わりに、audit_functionにdatabase_idがあるときにトリガーし、選択ボックスをレンダリングして、 database_id の値に応じた値。これも同様に機能します。

問題は、フィールドのjQueryがトリガーされるdatabase_1_idの部分で、@audit_functionオブジェクトが手元になく、他のjavascriptと干渉しているように見えるため、field_idでこれを行うことができないことです.

それに加えて、これを行うためのより良い方法があると考えたいと思います。しかし、私はすでに他のチュートリアルと方法を試しましたが、それらは、国-州-都市の直接的な関係がない場合、または編集時に機能しない場合に機能しません。

ですから、どんな助けも本当に感謝しています。ありがとう!

4

1 に答える 1

0

次のチュートリアルをテンプレートとして使用して、カスケード ドロップダウンを書き直しました。

http://homeonrails.blogspot.de/2012/01/rails-31-linked-dropdown-cascading.html

そこで、すべての異なるモデルを 1 つの配列に入れ、クラスに名前を追加してフィルター処理し、ID だけでなく名前でも区別します。また、jQuery プラグイン chainedTo により、コードがより読みやすくなります。

したがって、コントローラーは次のようになります。

    @types_for_dropdown = [[I18n.t("text archive_database"),"ori"],[I18n.t("text query_database"),"mod"]]

@tables_for_dropdown = []
@ad_qry_mods = AdQryMod.all
@ad_qry_mods.each do |i|
  @tables_for_dropdown = @tables_for_dropdown << [i.qry_mod_text,"mod#{i.id}",{:class => "mod"}]
end
@ad_ori_tbls = AdOriTbl.all
@ad_ori_tbls.each do |i|
  @tables_for_dropdown = @tables_for_dropdown << [i.otb_filename,"ori#{i.id}",{:class => "ori"}]
end

@fields_for_dropdown = []
@ad_qry_flds = AdQryFld.all
@ad_qry_flds.each do |i|
  @fields_for_dropdown = @fields_for_dropdown << [i.qry_fieldname,i.id,{:class => "mod#{i.ad_qry_mod_id}"}]
end
@ad_ori_flds = AdOriFld.all
@ad_ori_flds.each do |i|
  @fields_for_dropdown = @fields_for_dropdown << [i.otb_fieldname,i.id,{:class => "ori#{i.ad_ori_tbl_id}"}]
end

フォームは次のようになります。

<%= content_for :head do %>
<script>
$(document).ready(function(){
 $('select#audit_function_database_1_id').chainedTo('select#audit_function_database_1');
 $('select#audit_function_field_1_id').chainedTo('select#audit_function_database_1_id');
 $('select#audit_function_database_2_id').chainedTo('select#audit_function_database_2');
 $('select#audit_function_field_2_id').chainedTo('select#audit_function_database_2_id');
});
</script>
<% end %>
<div class="grid-6-12">
  <%= f.input :database_1, label: I18n.t("field_label audit_function database_1"), hint: I18n.t("field_hint audit_function database_1"), as: :select, collection: @types_for_dropdown, include_blank: true %>
</div>
<div class="grid-6-12">
  <%= f.input :database_2, label: I18n.t("field_label audit_function database_2"), hint: I18n.t("field_hint audit_function database_2"), as: :select, collection: @types_for_dropdown, include_blank: true %>
</div>
<div class="grid-6-12">
  <%= f.input :database_1_id, label: I18n.t("field_label audit_function database_1_id"), hint: I18n.t("field_hint audit_function database_1_id"), as: :select, collection: @tables_for_dropdown, include_blank: true %>
</div>
<div class="grid-6-12">
  <%= f.input :database_2_id, label: I18n.t("field_label audit_function database_2_id"), hint: I18n.t("field_hint audit_function database_2_id"), as: :select, collection: @tables_for_dropdown, include_blank: true %>
</div>
<div class="grid-6-12">
  <%= f.input :field_1_id, label: I18n.t("field_label audit_function field_1_id"), hint: I18n.t("field_hint audit_function field_1_id"), as: :select, collection: @fields_for_dropdown, include_blank: true %>
</div>
<div class="grid-6-12">
  <%= f.input :field_2_id, label: I18n.t("field_label audit_function field_2_id"), hint: I18n.t("field_hint audit_function field_2_id"), as: :select, collection: @fields_for_dropdown, include_blank: true %>
</div>

これは本当に素晴らしいソリューションであり、すべての人にお勧めできます。

于 2013-11-22T09:28:52.277 に答える