简体   繁体   English

Rails动态更改集合基于表单字段在表单中选择

[英]Rails Dynamically Changing Collection Select In Form Based on form field

I have a Rails 3.2.14 app that tracks calls and each call has a pickup and dropoff facility from the Facility model which is an association. 我有一个跟踪呼叫的Rails 3.2.14应用程序,每个呼叫都有一个来自设施模型的关联的代答和下车设施。

In the call model there is an association for the Region model (ie Houston, Dallas, Austin, etc) where we select a region based on where the call is coming from. 在呼叫模型中,存在区域模型的关联(即,休斯顿,达拉斯,奥斯丁等),我们根据呼叫的来源来选择区域。

What I'd like to do is be able to select a specific region (ie Houston) and in the pickup facility collection only show Houston region facilities. 我想做的是能够选择特定区域(即休斯顿),并且在接送设施集合中仅显示休斯顿地区的设施。

I'm assuming to start off with I'd need to setup a relationship between Facility and Region as such: 我假设首先要在Facility和Region之间建立一个关系,如下所示:

facility.rb facility.rb

attr_accessible :region_id
belongs_to :region

region.rb region.rb

has_many :facilities

Then I'd need to set each facility with a region_id that matches the respective region (ie Houston, Dallas, etc) so the association works properly. 然后,我需要为每个设施设置一个与各自区域(例如,休斯顿,达拉斯等)相匹配的region_id,以便关联正常运行。

What I'm unsure of is how to select the specific region and only have the facilities in that region display in the form. 我不确定的是如何选择特定区域,并且仅以表格形式显示该区域中的设施。 I'm assuming I would use some jQuery/JS/Ajax here to make it happen but not sure how to make it work. 我假设我会在这里使用一些jQuery / JS / Ajax来实现它,但不确定如何使它工作。

Here's an excerpt of what my call, facility, and region models currently look like: 以下是我的呼叫,设施和区域模型当前的摘要:

call.rb call.rb

belongs_to :transferred_from, :foreign_key => :transfer_from_id, :class_name => 'Facility'
belongs_to :transferred_to, :foreign_key => :transfer_to_id, :class_name => 'Facility'
belongs_to :region

facility.rb facility.rb

has_many :calls_transferred_from, :foreign_key => :transfer_from_id, :class_name => 'Call'
has_many :calls_transferred_to, :foreign_key => :transfer_to_id, :class_name => 'Call'

region.rb region.rb

has_many :calls

Here's an excerpt of what my call form partial looks like: 这是我的部分呼叫表格的摘录:

_form.html.erb _form.html.erb

<%= form_for(@call) do |f| %>
  <%= f.label :region %>
  <%= f.collection_select(:region_id, Region.all, :id, :area, {:include_blank => true}, {:class => 'select', required: true}) %>
  <%= f.label :Transfer_From %>
  <%= f.collection_select(:transfer_from_id, Facility.active.order("facility_name ASC"), :id, :facility_name, {:include_blank => true}, {:class => 'select'}) %>
 <%= f.button "Submit", class: 'btn btn-info btn-large', data: {disable_with: "<i class='icon-spinner'></i>Processing..."} %> 
<% end %>

If any of this is confusing or needs clarification, please let me know. 如果有任何混淆或需要澄清的地方,请告诉我。 To summarize, I'm trying to select a region (Houston) and only show the Facilities that are in the Houston region in the form when that region is selected. 总而言之,我试图选择一个区域(休斯顿),并且仅在选择该区域时以表格形式显示休斯顿区域中的设施。

Thanks in advance for any help or tips you can provide. 在此先感谢您提供的任何帮助或提示。

For things like this, I typically keep it real simple by loading a dictionary in the client, and just reference that. 对于这样的事情,我通常通过在客户端中加载字典并引用它来使其保持简单。

So in your view, you can build out something like this: 因此,在您看来,您可以构建如下所示的内容:

<script>
  var facilitiesForRegion = {};
  <% Facility.all.each do |facility| %>
    var region = facilitiesForRegion[<%= facility.region_id %>];
    var object = { id: <%= facility.id %>, name: '<%= facility.facility_name %>'};
    if (region) {
      region.push(object);
    }
    else {
      facilitiesForRegion[<%= facility.region_id %>] = [object];
    }
  <% end %>

  $("#call_region_id").on("change", function (e) {
    var id = parseInt($(this).val());
    var facilities = facilitiesForRegion[id];
    $('#call_transfer_from_id').children().remove();
    for (var i = 0; i < facilities.length; i++) {
      $('#call_transfer_from_id').push('<option value="'+ facilities[i].id +'">'+ facilities[i].name +'</option>');
    }
  });
</script>

It's a little ugly. 这有点丑陋。 I'm not the biggest fan of building out an array of data in the view like that, but it works and avoids waiting ajax requests. 我不是在这样的视图中构建数据数组的最大支持者,但是它可以正常工作,并且避免了等待ajax请求。

Be sure to double check the ids of the drop downs. 请务必仔细检查下拉菜单的ID。 I was guessing on that, based on field names and the for_for. 我在猜测,基于字段名称和for_for。

Based off of the Railscasts dynamic select menus I've come up with the following: 基于Railscasts动态选择菜单,我提出了以下内容:

calls.js.coffee Calls.js.coffee

jQuery ->
  facilities = $('#call_transfer_from_id').html()

  $('#call_region_id').change ->
    region = $('#call_region_id :selected').text()
    options = $(facilities).filter("optgroup[label=#{region}]").html()

    if options
      $('#call_transfer_from_id').html(options)   
    else
      $('#call_transfer_from_id').empty()

_form.html.erb _form.html.erb

<%= f.grouped_collection_select :transfer_from_id, Region.order(:area), :facilities, :area, :id, :facility_name, {include_blank: true}, class: 'select' %>

The problem with the above grouped_collection_select is that it's calling :facilities which lists all the facilities, I need to call the equivalent of Facility.active (scope I created on Facility to only list active facilities). 上面的grouped_collection_select的问题在于它调用:facilities列出了所有设施,我需要调用Facility.active的等效项(我在Facility上创建的范围仅列出了活动设施)。 How can I call this from within grouped_collection_select? 如何在grouped_collection_select中调用它?

So far in a new call I'm able to select the region then the facilities for that region show up only in the from field (transfer_from_id being called). 到目前为止,在一个新呼叫中,我能够选择区域,然后仅在from字段中显示该区域的设施(被调用transfer_from_id)。 When editing the call and trying to change the facility I'm presented with a full list of facilities grouped by region instead of just the facilities for that region. 在编辑呼叫并尝试更改设施时,系统会向我显示按地区分组的设施的完整列表,而不仅仅是该地区的设施。 If I want to narrow it down I have to change region then change it back to the original for the specific region's facilities to show up solely. 如果要缩小范围,则必须更改区域,然后将其更改回原始,以使特定区域的设施仅显示出来。

I think I'm making progress with this, but it's not working out the way I want it. 我认为我在此方面取得了进展,但并没有达到我想要的方式。 I'm really open to answers that make more sense and are more clear. 我很乐于接受更有意义,更清晰的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM