CoffeeScript 在更改和加载时动态选择表单字段

Posted

技术标签:

【中文标题】CoffeeScript 在更改和加载时动态选择表单字段【英文标题】:CoffeeScript to select form fields dynamically on change and on load 【发布时间】:2014-10-26 01:12:09 【问题描述】:

我有一个 Rails 应用程序,我试图根据在表单中选择的区域来选择设施列表。到目前为止,我已经实现了 group_collection_select 以及一些 CoffeeScript。

它在创建新记录和选择区域时起作用。行为是仅显示为所选区域列出的设施。不起作用的是在编辑记录时,选择设施会显示按区域分组的所有设施,而不是将设施限制在所选区域。

如果我选择另一个区域,然后选择原始原因,则会显示正确的设施列表。

我想了解如何将 CoffeeScript 重构为在编辑记录时该函数在页面加载(编辑时)和更改时触发的位置。

最后,有些用例将 transfer_from_id 设置为 nil/blank,我们使用名为 transfer_from_other 的文本字段。目前,如果我不选择设施并填写 transfer_from_other,因为 CoffeeScript 将设施加载到 transfer_from_id 中,它将通过范围内的第一个设施设置 transfer_from_id。如果没有选择任何设施,我想将其设置为,transfer_from_id 为 nil,因此我可以使用 transfer_from_other。

我的代码如下所示:

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()

region.rb

has_many :facilities

facility.rb

attr_accessible :region_id
belongs_to :region

_form.html.erb 摘录

      <%= f.label :region %>
      <%= f.collection_select(:region_id, Region.all, :id, :area, :include_blank => true, :class => 'select', required: true) %>
      <%= f.label :Transfer_From %>
      <%= f.grouped_collection_select :transfer_from_id, Region.order(:area), :active_facilities, :area, :id, :facility_name, include_blank: true, class: 'select' %>
      <%= f.label :Transfer_From_Other%>
      <%= f.text_field :transfer_from_other %>

如果我的问题和示例不清楚,请告诉我,我很乐意编辑。

【问题讨论】:

试试这个***.com/questions/11817496/… @rkp 谢谢,但这并不是我真正想要的。请查看问题,如果有不清楚的地方请告诉我。 【参考方案1】:

关于在页面加载和选择更改时更新选择,除非我遗漏了什么,否则将选择更新部分简单地分解为它自己的函数是不够的,然后在页面加载时调用一次,并且然后每次选择更改?

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

  update_facilities = ->
    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()      

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

  update_facilities()

关于第二部分,每次更新#call_transfer_from_id选择,都会丢失空白选项。第二个版本会在每次选择区域时添加并选择一个空白选项:

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
      $('#call_transfer_from_id').html(options)
      # Add in a blank option at the top
      $('#call_transfer_from_id').prepend("<option value=''></option>")
      # Ensure that the blank option is selected
      $('#call_transfer_from_id option:first').attr("selected", "selected");
    else
      $('#call_transfer_from_id').empty()      

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

  update_facilities()

【讨论】:

感谢您的参与。这适用于页面加载和选择更改。但是,如果我故意将 transfer_from_id 字段留空并使用 transfer_from_other 输入地址,则会使用 transfer_from_id 选择列表中的第一个设施来创建呼叫记录。除非我专门选择设施,否则如何将其设置为 transfer_from_id 保持空白/nil 的位置?到目前为止,我们正在取得进展,再次感谢您的帮助。 我已经更新了答案。如果我理解正确,您是说当您选择一个区域并更新设施时,会自动选择第一个设施,因为没有空白选项。假设我正确理解了问题,那么编辑后的答案应该可以满足您的需求。如果没有,我认为如果您可以创建一个演示问题的小提琴并在您的问题中链接到它,那将有很大帮助。 感谢您更新您的答案。我尝试了这一点,并在编辑呼叫时遇到了问题。编辑呼叫时,$('#call_transfer_from_id option:first').attr("selected", "selected"); 行导致设施 transfer_from_id 字段选择空白选项。编辑呼叫时,设施需要保持记录。所以我删除了那行$('#call_transfer_from_id option:first').attr("selected", "selected"); 并保留了你的代码,它似乎正在工作。我会进一步测试并让你知道。感谢您的努力! 我要问的一件事是为什么update_facilities() 会被调用两次?也许我不明白。只是好奇。 只是一个更新。我花了几分钟时间对此进行了测试,到目前为止,一旦我删除了$('#call_transfer_from_id option:first').attr("selected", "selected"); 行,它就可以工作了。我将进一步测试它,但它看起来像我最初想要的那样工作。我接受了你的回答并投了赞成票。如果我遇到任何问题,我会发表评论。非常感谢:)【参考方案2】:

所以我一直在解决这个问题,我想我已经找到了一个适用于 Chrome 和 Firefox 的解决方案。

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()

我能够重构并删除一行代码,并将选项和空白选项设置在一行中,而不是使用 prepend。出于某种原因,Firefox 不喜欢 prepend 方法。因此,通过调用这一行:$('#call_transfer_from_id').html("&lt;option value=''&gt;&lt;/option&gt;" + options) 我可以传递选项并在数组的开头插入一个空白选项。

到目前为止,我已经在 Chrome 和 Firefox 上进行了测试,它显示了以下行为。

创建新呼叫时,设施受地区限制,字段中会显示一个空白选项以供选择。如果您输入 transfer_from_other 地址并将 transfer_from_id 保留为 nil,则它会保留 nil 值。

在编辑已填写 transfer_from_other 地址的呼叫时,transfer_from_id 不再填充列表中的第一个设施,而是列出空白 (nil) 选项。

在编辑分配了 transfer_from_id 的呼叫时,它会保留记录的原始值并仍受区域限制。

你能看看我的代码,看看它是否有意义。我偶然发现这样做并以某种方式使它起作用。试图了解为什么这在两种浏览器上都有效,而您的答案只在 Chrome 上有效。

【讨论】:

我在 Safari 中测试了代码,因此可以肯定地说它可以在 Safari 和 Chrome 中运行,但 Firefox 存在问题。如果这里唯一的更改是替换名为 prepend 的一行,那么我建议对我的原始答案进行编辑。 我编辑了您的原始答案以反映我所做的更改。现在的问题是为什么 prepend 在 Firefox 中不起作用?我想它会工作得很好。可能是我正在运行的 jQuery 版本jquery-rails 2.1.4 gem?

以上是关于CoffeeScript 在更改和加载时动态选择表单字段的主要内容,如果未能解决你的问题,请参考以下文章

从动态表中选择时更改列名

在运行时动态更改 QML 主题

当我动态更改其框架时,即使重新加载后 UITableView 内容大小也不会更新

当下拉列表中的“选择”更改时,按 ID 填充表 TD

通过 Ajax PHP 动态加载下拉选择

springaop动态加载不同类