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 链接到无效输入后表单失败的上一页