Jonovono
Jonovono

Reputation: 3425

Rails: Drop down with 'Add new' option which creates more form fields

I want to have a drop down on a form. So for example a user is picking an equipment type. But if it is not in the dropdown I want there to be an option for 'Add New' and when this is clicked some more fields pop up that the user must fill in.

So essentially when the form is submitted it creates two new model objects: Equipment and EquipmentType.

Is this possible?

Upvotes: 1

Views: 3632

Answers (2)

mirelon
mirelon

Reputation: 4996

As far as I know, there is still no gem for it. I assume you have two models, Equipment, and EqipmentType, each of them has :name and they are connected via belongs_to/has_many association.

My solution will add an attr_accessor :new_equipment_type to Equipment, which is populated after the form is submitted.

Then, it creates a new equipment type if needed and connects it to the equipment:

# 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

The form has a dropdown with existing equipment types and when a blank option is selected, new input is shown for a new equipment type name:

#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}"}

And finally javascript to show/hide the new equipment type field:

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

Upvotes: 1

Mik
Mik

Reputation: 4187

I'm not sure what you exactly need, so I point you to two solutions:

  1. When you clicks "Add new" and you need to fill more then one field. This is the standart situation for this gems: nested_form and cocoon.

    Example of how it looks: http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast

  2. When you clicks "Add new" and just want to add another option to has_many association. In this case you can transform the standart multiple select into that kind of behavior. Take a look at that question: https://stackoverflow.com/questions/2867795/best-jquery-multiselect-plugin, there are a couple plugins for this.

    Example: http://odyniec.net/projects/selectlist/examples.html

Upvotes: 2

Related Questions