Multiple attribute in collection_select in Rails - ruby-on-rails

I am trying to allow for multiple value selection from a collection in a Rails form. The field is working but does not allow for multiple selections (once an alternative option is selected the previously selected is unselected). I am using Bootstrap CDN, which I don't presume is causing issues, but I may be wrong?
Can you see anything wrong with this code?
<div class="field form-group row">
<%= f.label :industry_ids, class:"col-sm-3"%>
<%= f.collection_select(:industry_ids, Industry.all, :id, :name, {:multiple => true}, size: Industry.all.length) %>
</div>
Thanks for your help.

I believe your problem is that you're putting {:multiple => true} in the wrong options hash. The method signature for collection_select looks like this:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
multiple is an html attribute of the select tag itself (here's a doc), so you want to pass that to html_options, not options. Your code looks like this:
f.collection_select(:industry_ids, Industry.all, :id, :name, {:multiple => true}, size: Industry.all.length)
Where Industry.all is the collection, :id is the value_method, and :name is the text_method, which means { :multiple => true } is getting passed to options, not html_options. Move it to the second hash and you should be fine.

Related

ruby on rails - drop down list from model

I would like to create a drop down list with Ruby on rails from the model "Company" which has a item call "name". I would like to length of the dropdown list to be as long as Company.count (dynamic)
For example for 3 element in "Company":
<%= f.select :company_brand, [[Company.find(1).name, Company.find(1).id],[Company.find(2).name, Company.find(2).id],[Company.find(3).name, Company.find(3).id]]%>
collection_select (documentation) will provide what you need:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
Returns and tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made without including :prompt or :include_blank in the options hash.
The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.
For your use case, this would mean changing the code to:
<%= f.collection_select(:company_brand, Company.all, :id, :name) %>
You can do like this:
<%= select(:company_brand, Company.all.collect {|c| [ c.name, c.id ] }, { include_blank: true }) %>
#League - form.html.erb
<%= f.collection_select(:game_id, Game.order(:title), :id, :title, {prompt: true}, {class: 'form-control col-md-7 col-xs-12', required: "required"})%>
#.html_output
<select class="form-control col-md-7 col-xs-12" required="required" name="league[game_id]" id="league_game_id"><option value="">Please select</option>
<option value="2">csgo</option>
<option value="1">dota2</option>
</select>
You can try this i think this will help you.
<%= f.select :company_brand, options_from_collection_for_select(Company.all, "id", "name") %>

Change the option selected on collection_select

I'm trying to change the option that is selected on collection_select on my form in rails.
My code look like this:
<%= f.collection_select :course_type_id, CourseType.where(:deleted => false), :id, :name, {}, {class: 'form-control m-b', :selected => #course_template.course_type.name } %>
However the option selected always shows the first one and never changes unless the user selects a different option.
The resulting html looks like this:
<select class="form-control m-b" selected="selected" name="course[course_type_id]" id="course_course_type_id">
<option value="1">Driving</option>
<option value="2">Pratical</option>
</select>
Any ideas on what I'm doing wrong?
It looks like you're putting the :selected key in the html_options argument attributes.
Here is the method definition for collection_select:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
Try this:
<%= f.collection_select :course_type_id, CourseType.where(:deleted => false), :id, :name, {:selected => #course_template.course_type.name}, {class: 'form-control m-b' } %>
<%= f.collection_select :course_type_id, CourseType.where(:deleted => false), :id, :name, { :selected => #course_template.course_type.id }, {class: 'form-control m-b' } %>
The selected parameter takes the value, and not the name of the option.
From collection_select definition, selected option and html_options are different params.
For further understanding, refer here.

HOw do I pre-select a value in my select menu if a cookie is set?

I’m using Rails 4.2.3. I have this select form field in my page …
<%= f.label :object %><br>
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}) %></div>
My question is, how do I pre-select a value if there is a cookie present named “object”? I would like to set the value of the select menu to be the value of the cookie. Note, I only want to pre-select the value if this view is served by my controller’s “index” action (The above is part of a partial view that is served by different controller methods).
Thanks, - Dave
Hey according to docs at APIdock:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:selected => current_book.authors.map(&:id)})
So You should write it like this:
In You controller specify you objects: #selected = cookies[:some_key]
collection_select(:user_object, :object, #objects, :id, :description, {:selected => #selected.map(&:id), :prompt => true})
You do not need whole objects, just the ids to check out selected ones. I think this should do the trick.
If you want some object to be selected by default, you can use :selected
assuming that your cookie object stores an id
{:selected => object}
<%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {:selected => object} ) %>
Get cookie value in your Index controller,
def index
#selected_object = cookies[:some_key]
end
In your Index.html.erb
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {selected: <%= #selected_object %> }) %></div>
Or you can get that cookie on the fly from View file,
<div class="styled-select"><%= collection_select(:user_object, :object, #objects, :id, :description, {:prompt => true}, {selected: <%= cookies[:some_key] %> }) %></div>
Note that value of cookie might be hash, make sure you get the correct value, also you can use conditional in controller to avoid getting nil and resulting no value selected in view by,
def index
#selected_object = cookies[:some_key]
if #selected_object.nil?
#selected_object = "default_selected"
end
end
If you want some object to be selected by default, be sure to use its id, not the whole object.
Try the following:
<%= f.collection_select(:user_object,:object,#objects ,:id, :description,:selected => cookies[:object])%>
Note:
Make sure cookies[:object] returns an id of the items in the select list
Source - http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select#632--selected
I like to use options_for_select. Options for select can take an array or a two dimensional array, in the latter case the first value is shown to the user and the second value is what is saved. It can also take an optional second argument that selects the default value:
if cookies[:whatever_key_is]
<%= f.select(:object, options_for_select(["array", "of", "options"], cookies[:whatever_key_is]) %>
end
I usually write a method for passing the array, especially if it's two dimensional, and then call that method as the first argument. I actually also usually write a method for the second argument.

Rails multi-select getting undefined method `to_i'

I'm trying to select multiple events in the invtime form.
Invtime
has_many :events
This is my form code:
<%= f.select :event_id, Event.all.collect {|x| [x.title, x.id]}, {}, :multiple => true %>
The display looks good! But, when I select the last event and submit, I get:
undefined method `to_i' for ["", "62"]:Array
The page inspection shows:
<select id="invtime_event_id" multiple="multiple" name="invtime[event_id][]">
<option value="66">Meeting</option>
<option value="62">Auto fill some fields on new workorder</option>
</select>
Thanks for the help!
The select helper doesn't know what to do with a collection like that, it assumes the first value is an ID and the second a string, you might be able to just reverse your method calls but this isn't really the right way to create a select tag, instead either use collection_select as dax suggests or use the options_from_collection_for_select helper:
<%= f.select :event_id, options_from_collection_for_select(Event.all, :id, :title), {}, :multiple => true %>
undefined method `to_i' for ["", "62"]:Array
from the docs:
:include_blank - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.
So try adding include_blank: true
<%= f.select(:event_id, Event.all.collect {|x| [x.title, x.id]}, {}, :multiple => true, include_blank: true ) %>
also, you might try collection_select, where #events = Event.all
<%= f.collection_select(:event_id, #events, :id, :title, include_blank: true ) %>

:disabled field not working in fields_for

I'm trying to add a disabled drop-down box to my table, which I will eventually make conditional.
However, disabled doesn't seem to be added to the line when it is run.
If I inspect the element in the page, manually adding disabled works, but it is not being added at run-time.
= f.fields_for(:targets, qualification.target_for(#grandfather.user)) do |builder|
%tr
%td
= builder.select :completed, qualification.level_options.map{|o| [o,o]}, :disabled => "disabled"
= builder.hidden_field :qualification_id, :value => qualification.id
= builder.hidden_field :id
Check out the API for Rails' Form Helper API
select(object, method, choices, options = {}, html_options = {})
It was adding :disabled => "disabled" to the options, instead of the html_options. This is the code to use instead (notice the empty hash for the options parameter):
builder.select(:completed, qualification.level_options.map{|o| [o,o]}, {}, {:disabled => "disabled"})

Resources