Rails:使用“添加新”选项下拉,创建更多表单字段

时间:2012-08-19 23:39:37

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 ruby-on-rails-3.2

我希望在表单上放一个下拉菜单。例如,用户正在挑选设备类型。但如果它不在下拉列表中,我希望有一个“添加新”的选项,当点击它时会弹出一些用户必须填写的字段。

因此,基本上在提交表单时,它会创建两个新的模型对象:Equipment和EquipmentType。

这可能吗?

2 个答案:

答案 0 :(得分:2)

我不确定你到底需要什么,所以我指出两个解决方案:

  1. 点击“添加新内容”后,您需要填写多个字段。 这是此宝石的标准情况:nested_formcocoon

    它的外观示例:http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast

  2. 当您点击“添加新”并且只想添加其他选项时 has_many协会。在这种情况下,您可以改变标准 多重选择进入那种行为。看看那个 问题:https://stackoverflow.com/questions/2867795/best-jquery-multiselect-plugin,这里有几个插件。

    示例:http://odyniec.net/projects/selectlist/examples.html

答案 1 :(得分:1)

据我所知,它仍然没有宝石。我假设您有两个模型,EquipmentEqipmentType,每个模型都有:name,并且它们通过belongs_to/has_many关联连接。

我的解决方案会将attr_accessor :new_equipment_type添加到Equipment,并在提交表单后填充。{/ p>

然后,如果需要,它会创建一个新设备类型并将其连接到设备:

# app/models/equipment.rb
class Equipment < ActiveRecord::Base
  belongs_to :equipment_type
  attr_accessible :name, :equipment_type_id, :new_equipment_type
  attr_accessor :new_equipment_type

  def new_equipment_type=(val)
    if equipment_type_id.blank?
      write_attribute(:equipment_type_id, EquipmentType.create(name: val).id)
    end
  end

end

# app/models/equipment_type.rb
class EquipmentType < ActiveRecord::Base
  has_many :equipments
  attr_accessible :name
end

表单包含现有设备类型的下拉列表,当选择空白选项时,将显示新设备类型名称的新输入:

#app/views/equipments/_form.html.haml
= simple_form_for [@equipment] do |f|
  = f.input :name
  = f.association :equipment_type, include_blank: "Add new"
  = f.input :new_equipment_type, input_html: {value: "New equipment type name"}, wrapper_html: {style: "#{if @equipment.equipment_type_id.present? then 'display:none;' else '' end}"}

最后javascript显示/隐藏新设备类型字段:

#app/assets/javascripts/equipments.js.coffee:
@showOrHideNewEquipmentTypeField = (drop_down) ->
  new_equipment_type = $(drop_down).closest('form').find('div.input[class*=new_equipment_type]')
  if $(drop_down).val()
    $(new_equipment_type).slideUp()
  else
    $(new_equipment_type).slideDown()

$ ->
  $('[name*=equipment_type_id]').change ->
    showOrHideNewCategoryField(@)