使用 CoffeeScript 或 jQuery 以 Rails 形式显示对象地址 grouped_collection_select

Displaying object address with CoffeeScript or jQuery in Rails Form with grouped_collection_select

我有一个 Rails 3.2.20 应用程序,我有一个表单设置,selects 设施模型中有 facility_namefacility_address 字段.这是 CallFacility 模型之间的关系,允许将设施分配给呼叫。

目前我可以select 一个设施并通过select使用select2 从dropdown/search 中输入名称来毫无问题地分配它。但我希望能够做的是,当 select 设施旁边有一个小的 div 显示器时,facility_address 用于特定的 facility.id。所以当我 select 24 小时急诊室时,一个小 div 会显示设施的地址。

我不确定如何使用 jQuery 或 CoffeeScript 执行此操作,因为我有点生疏。附件是我的表格的截图。下面是我目前处理 jQuery 的方法,但我需要想出一种方法将数据属性传递给 grouped_collection_select,这样我就可以得到 address 数据字段来显示jQuery。每当我 select 一个设施时 div 就会弹出 "undefined"

我不确定我是否可以传递像 data: {address: :facility_address} 这样的数据属性。尝试这样做会产生错误。会有一些方法可以做到这一点。或者也许将其重组为 select 表单助手并使用 group_options_for_select

我正在搜索如何使用 jQuery 或 CoffeeScript 显示表单字段中的数据,但到目前为止我还没有找到任何具体的内容。

如果您需要我的表单的代码示例或有关我的模型关系的更多数据,请告诉我。但基本上我只需要在表单中 facility.id 被 select 后显示一个设施地址。

_form.html.erb

<%= f.grouped_collection_select :transfer_from_id, Region.order(:area), :active_facilities, :area, :id, :facility_name, {include_blank: true}, class: 'select' %><div id ="transfer-from-address"></div>

region.rb

class Region < ActiveRecord::Base
  attr_accessible :area
  has_many :calls
  has_many :facilities

  def active_facilities 
    self.facilities.active
  end
end

calls.js.coffee

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

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

    if options
      # Set the options and include a blank option at the top
      $('#call_transfer_from_id').html("<option value=''></option>" + options)
      # Ensure that the blank option is selected
      $('#call_transfer_from_id').attr("selected", "selected")
    else
      $('#call_transfer_from_id').empty()

  $('#call_region_id').change ->
    update_facilities()

  update_facilities()

  jQuery ->
  $("#call_transfer_from_id").on "change", (e) ->
    selected = $("#call_transfer_from_id option:selected")
    $("#transfer-from-address").html("""
    <h3>#{selected.data("address")}</h3>
    """)

作为js.erb :

faciltiy_address = { <%= Facility.all.map { |e| "'#{e.id}': '#{e.address}'" }.join(', ') %> }

$('your_select').change(function() { $('your_address_wrapper').html(facility_address[$(this).val()])
)}

编辑:

作为js.coffee

$ ->
  faciltiy_address = { <%= Facility.all.map { |e| "#{e.id}: '#{e.address}'" }.join(', ') %> }
  $('#facility_transfer_from_id').change -> 
    $('#transfer-from-address').html(facility_address[parseInt($(this).val())])

备注:

- 不确定 css id

-咖啡浏览量会将 erb 解析为

-取决于设施的数量,您希望 ajax 调用

我遇到了类似的问题。我所做的修复是访问此站点 http://coffeescript.org/。并将我的 Coffescript 编译为 Javascript,然后在我需要的视图页面中包含一个脚本标记,并将我的 Complied Coffescript 放置到 Javascript 中并且它起作用了。

此外,Railscast 部分讨论了此问题 #88 动态 Select 菜单(已修订)- RailsCasts。 (如果您没有帐户,您可以在 youtube 上免费观看专业剧集!对不起 Ryan Bates)

有几种方法可以完成此操作,但 none 使用默认 grouped_collection_select。该方法同时采用 option_key_methodoption_value_method,但它们旨在作为集合成员的基本 getter 来填充选项标签的内容,而不是完全替换选项标签。我看到三个主要选项

创建您自己的 select 标签生成器

编写您自己的 select 构建器,使用 content_tag 在 select 中构建您自己的选项标签,类似于:

content_tag(:option, facility.name, value: facility.id, data: {address: facility.address})

[编辑] - 按照 OP 的要求添加一个简单的 select 构建器。

假设有一个已定义的助手。

  def select_with_data_attributes(addys)
    content_tag(:select, {}) do
      raw addys.map {|a| content_tag(:option, value: a[1], data: {address: a[0]}) { a[0] } }.join
    end
  end

您可以通过以下方式在您的视图中呈现:

<%= select_with_data_attributes(@addresses.map{|a| [a.address, a.id]}) %>

这将构建如下所示的 html:

<select>
  <option data-address="123 elm st" value="1">123 elm st</option>
  <option data-address="345 elm st" value="2">345 elm st</option>
</select>

虽然我非常不同意这种方法,因为您最终会与 simple_form 和 rails 的内置帮助器等表单构建器库一起工作。

对地址进行 ajax 请求

这将是一个更好的选择(尤其是如果它是一个非常长的列表),因为将这些东西推入选项元素感觉有点丑陋,而且渲染那么多可能需要很长时间 html.您可以向服务器端点发出完整的 GET 请求。

$.get("/facilities/#{selectedOption}/address").done(...etc)

当用户选择选项时通过服务器请求动态填充您的 selects 是唯一可取的方法,一旦您获得相当数量的设施和位置,因此这个方向将是您当前代码的最大重构,但可能是最好的长期解决方案。

在视图中呈现数据以支持您的表单

这是我对少量动态数据的选择。这个想法是呈现一个自定义脚本标签,地址序列化到一个数据结构中。

基于 api 文档中的示例 html:http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/grouped_collection_select

我整理了一些 jsbin,展示了一个粗略的方法。

http://jsbin.com/kuwivuxipu/1/edit?html,js,console,output

从那个 jsbin,下面的重要部分:

update_facilities = (e)->
    selectedValue = $(e.currentTarget).val()
    continent = data[selectedValue]
    $('#address').text(continent)

$('select').on 'change', update_facilities

html在头

  <script> 
    // I'm just making up a data structure here
    // and obviously scoping this poorly, but you get the idea
    window.data = {
     1: 'Africa', 
     2: 'Europe', 
     3: 'Africa', 
     7: 'Europe'
    }
  </script>

您可以通过执行 @facilities.to_json 之类的操作并提供适当的序列化程序(建议)来创建您需要的数据,或者通过创建一个设施助手(可能更容易)来将这些数据渲染到您的视图中为您构建数据:

def facilities_json
  # could also use Enumerable#inject instead of each_with_object
  data = @facilities.each_with_object({}) do |item, memo|
    memo[item.id] = memo.address
  end
  data.to_json
end