58

I have the following select box in my form:

Related Type: &nbsp; <%= f.select(:TYPE, [['Type A', 'Type A'],
                                  ['Type B', 'Type B'],
                                  ['Type C', 'Type C'],
                                  ['Type D', 'Type D'],
                                  ['Type E', 'Type E']
                                 ],{ :prompt => "Please select"}
                                 ) %>

I want to allow the user to make multiple selections and also make the size of the select box 5.

How to do that for the code above?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Kim
  • 2,070
  • 5
  • 33
  • 46

9 Answers9

84

After your { :prompt => "Please select"} add another hash with html options e.g.

<%= f.select(:TYPE, [['Type A', 'Type A'],
                                  ['Type B', 'Type B'],
                                  ['Type C', 'Type C'],
                                  ['Type D', 'Type D'],
                                  ['Type E', 'Type E']
                                 ],{ :prompt => "Please select"},
                                   { :multiple => true, :size => 5 }
                                 ) %>

Once you've done this you might want to move your :prompt option (keep the empty {} though so that html attributes don't get treated as Rails options.)

Also you'll need to ensure your controller code is correctly accepting and handling multiple values.

mikej
  • 65,295
  • 17
  • 152
  • 131
11

In case of collection, try

    <%= f.select(:TYPE, Categories.collect {|p| [ p.name, p.id ] }, 
                                           { :prompt => "Please select"}, 
                                           { :multiple => true, :size => 5 }) %>
Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
Swathi
  • 131
  • 1
  • 4
10

I have a fully working example (including preselection when editing the object), when:

  • Object is the considered object
  • similar_ids is the key to relations, and is a string

In the form:

form_for(@object) do |f|
  = f.select :similar_ids, options_from_collection_for_select(Object.all, :id, :name, {:selected => @object.similar_ids.split(';')}), {}, {:multiple => true, :size => 4, :name => 'object[similar_ids][]'}

And in the Object.rb model:

class Object < ActiveRecord::Base
  before_save :handle_similars

  def handle_similars
    self.similar_ids = self.similar_ids.select(&:present?).join(';') 
    # .select(&:present?) is necessary to avoid empty objects to be stored
  end

  def similars
    self.class.find(self.similar_ids.split(';'))
  end

end

These posts helped me out:

Hope it helps

Community
  • 1
  • 1
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206
  • 3
    It's important that the name ends in `[]` so that rails interprets the params as an array of values – Josh Jun 11 '15 at 02:08
2

HTML

<%= form.select(:product_ids, Product.all.collect {|p| [ p.name, p.id ] }, 
                                                   { :prompt => "Please select"}, 
                                                   { :multiple => true, :size => 5  }) %>

Controller

@category = Category.new(category_params) 

def category_params
    params.require(:category).permit(:name, product_ids: [])
end
Community
  • 1
  • 1
0
{ :prompt => "Please select"}, { :multiple => true, :size => 5 } {}

is important when f.select

LinFelix
  • 1,026
  • 1
  • 13
  • 23
Vaisakh VM
  • 1,071
  • 11
  • 9
0

with bootstrap selectpicker and pre selected values:

    = simple_form_for [:backend, @user], html: { autocomplete: 'off' } do |f|
      = f.select :role_ids, options_for_select(Role.all.map{|role| [role.name, role.id]}, @user.role_ids), {},  {:multiple => true, include_blank: false, class: "form-control input-sm selectpicker"}

in controller:

def user_params
      params.require(:user).permit(:id, role_ids: [])
end

# only if you havent build in new action
def new
  # set user
  @user.roles.any?
end
OuttaSpaceTime
  • 710
  • 10
  • 24
0

Multiple select:

= form_with url: ui_dashboard_diagrams_path, method: :get, local: true do |f|
  .row
    .col.form-group
      = f.select :our_organization_ids,
                 options_for_select(OurOrganization.pluck(:name, :id), params[:our_organization_ids]),
                 { include_blank: '' },
                 { multiple: true, class: 'form-control form-select-multiple' }


javascript:
  $(document).ready(function() {
    $('.form-select-multiple').select2({
      allowClear: true,
      multiple: true
    });
  });

Add permit array our_organization_ids to your controller:

private

def diagrams_params
  params.permit([our_organization_ids: []])
end
shilovk
  • 11,718
  • 17
  • 75
  • 74
0

Aside from the solutions above, I also had to change the name of the input, so Rails will parse the parameters as array. here the input created with simple form:

= f.input :my_ids, collection: ['A', 'B'], include_blank: false, input_html: { name: 'form[my_ids][]', multiple: 'multiple' }
Motine
  • 1,638
  • 18
  • 18
-1
<%= f.select :tag_ids, Tag.all.collect {|t| [t.name, t.id]}, { :prompt => "Please select"}, { :multiple => true, :size => 5 } %>
mousetail
  • 7,009
  • 4
  • 25
  • 45
rizwan ali
  • 11
  • 1
  • Please consider adding some explanation so the OP and future readers will know why and how your code solves the problem at hand. – mousetail Feb 04 '21 at 09:52