Ruby on Rails -- multiple selection in f.select
I have the following select box in my form:
Related Type: <%= 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?
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.
In case of collection, try
<%= f.select(:TYPE, Categories.collect {|p| [ p.name, p.id ] },
{ :prompt => "Please select"},
{ :multiple => true, :size => 5 }) %>
I have a fully working example (including preselection when editing the object), when:
Object
is the considered objectsimilar_ids
is the key to relations, and is astring
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:
- Select tag with multiple values pre-selected - Values inserted manually in database
- Ruby on Rails: Submitting an array in a form
Hope it helps
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
{ :prompt => "Please select"}, { :multiple => true, :size => 5 } {} is important when f.select
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, inlcude_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
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
<%= f.select :tag_ids, Tag.all.collect {|t| [t.name, t.id]}, { :prompt => "Please select"}, { :multiple => true, :size => 5 } %>
精彩评论