Ruby on Rails 表单添加带有文本框的“其他”选项以选择下拉菜单

Posted

技术标签:

【中文标题】Ruby on Rails 表单添加带有文本框的“其他”选项以选择下拉菜单【英文标题】:Ruby on Rails Form Add an "Other" Option with Text Box to Select Dropdown 【发布时间】:2021-10-16 21:02:12 【问题描述】:

我有一个包含以下代码的 ruby​​ 表单

        <%= form.label(:emitter_type, class: "form-label") %>
        <%= form.select(:emitter_type, BoilerPlant.emitter_type , include_blank: true) %>

        <% if boiler_plant.emitter_type != "Other" %>
        <div id="emitter_other", style="display:none;">
          <% else %>
          <div id="emitter_other">
            <% end %>


          <%= form.label(:emitter_type_other, class: "form-label") %>
          <%= form.text_field(:emitter_type_other , autocomplete: "off", autocapitalize: "on", class: "form-input") %>

          </div>

BoilerPlant.emitter_type 是对我模型中的一个函数的以下调用,该函数会生成我在下拉列表中使用的选项数组:

  def self.emitter_type
    ["Baseboard", "Fan Coil", "Heat Pump", "Other"]
  end

我使用javascript在选择“其他”时显示文本字段emitter_type_other。下面是我用来将我的选择字段的值设置为我在文本字段中键入的值的 javascript(忽略奇怪的命名约定)。

var toggleRevertValues = document.getElementById("plant_submit_button");
var deleteEmitterType = document.getElementById("boiler_plant_emitter_type");
var deleteEmitterOther = document.getElementById("boiler_plant_emitter_type_other");

toggleRevertValues.addEventListener("click", function(e)  

 if ( deleteEmitterType.value == "Other" ) 
                deleteEmitterType.value = deleteEmitterOther.value;
            


如果我输入数组中已存在的选项之一的确切名称(例如“底板”),下拉列表中会填充一个值。但是,如果我输入一个新选项,它在数据库中显示为 null,并且我的下拉列表在无效提交时显示为空白。有什么方法可以更改我的代码,以便它允许选择一个新值?

【问题讨论】:

【参考方案1】:

为了在用户选择“其他”并键入新的发射器类型时添加新的发射器类型,需要创建几个新模型:EmitterType' and 'BoilerEmitterType。第二个只是一个连接表。

class Boiler < ActiveRecord::Base
  has_many :boiler_emitter_types, dependent: :destroy
  has_many :emitter_types, through: :boiler_emitter_types
end

class BoilerEmitterType < ActiveRecord::Base
  belongs_to :boiler
  belongs_to :emitter_type
end

class EmitterType
  has_many :boiler_emitter_types, dependent: :destroy
  has_many :boilers, through: :boiler_emitter_types
end

然后响应表单提交,您可以将现有的EmitterType 分配给Boiler 实例,或者创建一个新的EmitterType 并将其分配给Boiler 实例。

ActiveRecord 有一个很好的方法可以帮您完成:

# boilers_controller.rb
def update
  @boiler = Boiler.find(boiler_params(:id))
  @emitter_type = EmitterType.find_or_create_by(name: boiler_params(:emitter_type_name)
  @boiler.emitter_types << @emitter_type
  if @boiler.save
    # do something
  else
    # do something else
  end
end

private
def boiler_params
# create the 'strong parameters' here
end

请注意,我们正在按名称而不是 id 查找发射器类型,这将是选择选项的典型响应。

【讨论】:

以上是关于Ruby on Rails 表单添加带有文本框的“其他”选项以选择下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章

如何使用用户定义的字段数制作表单? - Ruby on Rails

不允许用户在 ruby​​ on rails 中提交带有空字段的表单

如何控制 Ruby on Rails 3 中选择框的大小?

Ruby on Rails 链接到无效输入后表单失败的上一页

如何根据 Ruby on Rails 中的表单选择创建文本框警报/悬停弹出文本?

如何在 Ruby-on-Rails 中生成 PDF 表单