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 ) %>
Related
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") %>
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.
I have select
<%= f.select :visibility, collection_for_visibility_select, :include_blank => false %>
And a helper with values for select:
def collection_for_visibility_select
[
[l(:label_crm_contacts_visibility_project), Contact::VISIBILITY_PROJECT],
[l(:label_crm_contacts_visibility_public), Contact::VISIBILITY_PUBLIC],
[l(:label_crm_contacts_visibility_private), Contact::VISIBILITY_PRIVATE]
]
end
I want to add default select value to the select, and this is what I tried:
<%= f.select :visibility, collection_for_visibility_select, :selected => Contact::VISIBILITY_PUBLIC, :include_blank => false %>
it gave me default select value, but when i want to edit record and switch visibility to something else,i still got VISIBILITY_PUBLIC
How do I fix it?
You can try this:
<%= f.select :visibility, collection_for_visibility_select, :selected => (f.object.visibility.nil? ? Contact::VISIBILITY_PUBLIC : f.object.visibility), :include_blank => false %>
It will read the value from the model first, and if it is nil, will use the default value.
I'm trying to disable a dropdown from being updated on a form.
Currently i have this line in my form:
<%= f.select :permission, options_for_select([['Admin', 'admin'], ['Read Only', 'readonly'], ['Editable', 'editable']], {:disabled => #permissions_disabled}) %>
With my edit controller method containing:
#permissions_disabled = params[:id].to_i == current_user.id.to_i
p #permissions_disabled
I can clearly see in my log that 1#permissions_disabled1 is true, but when i edit the form, i can still select new values in the dropdown.
What am i doing wrong here?
select accepts 5 parameters, the 4th one is a set of options for the helper. the 5th one is the html options like class and id. I think you need to pass it to that
<%= f.select :permission, options_for_select([['Admin', 'admin'], ['Read Only', 'readonly'], ['Editable', 'editable']], {}, {:disabled => #permissions_disabled}) %>
UPDATE: didn't see the options_for_select in your code. you don't need that if you're using select, you'd only want to use that when you're using select_tag
<%= f.select :permission, [['admin', 'Admin'], ['readonly', 'Read Only'], ['editable', 'Editable']], {}, {:disabled => #permissions_disabled} %>
I tried :include_blank => true, but it didn't work.
<select>
<%= options_for_select Model.all.collect{|mt| [mt.name, mt.id]} %>
</select>
If I need to add it to the collection, how would you do that?
I think you want this format:
select("model_name", "model_id", Model.all.collect {|mt| [ mt.name, mt.id ] }, {:include_blank => 'name of your blank prompt'})
BTW: was assuming Modle was suppose to be Model. To use using collection_select:
collection_select(:model, :model_id, Model.all, :id, :name, :prompt => true)
I believe the :include_blank options only exist for select fields tied to a model.
Assuming you want to use a plain <select> tag instead of a <%= select(...) %> tied to a model, you can insert a blank entry at the front of your results:
<%= options_for_select Modle.all.collect{|mt| [mt.name, mt.id]}.insert(0, "") %>
Since you have tagged as select-tag you can use the option include_blank with select_tag.
From the documentation:
select_tag "people", options_from_collection_for_select(#people, "id", "name"), :include_blank => true
# => <select id="people" name="people"><option value=""></option><option value="1">David</option></select>
Or you can use options_for_select:
<%= select_tag column.name, options_for_select(Model.all.collect{|mt| [mt.name, mt.id]}), :include_blank => true %>
<%= options_for_select Model.all.collect{|x| [x.name,x.id]}.unshift(["",nil]) %>
= select_tag "some_value", options_for_select(Model.all.collect{ |x| [x.name, x.id]}.prepend([t('helpers.some_name'), nil]), :selected => params[:some_value])
If you want a slick solution you can use my gem rearmed_rails which has a feature in it that safely monkey patches options_for_select and options_for_collection_select
rails g rearmed_rails:setup
Open config/initializers/rearmed_rails.rb and change the following values to true
options_for_select_include_blank: true,
options_from_collection_for_select_include_blank: true
Now whenever you need a blank included simply do the following:
<%= options_for_select(Model.all.map{|x| [x.name,x.id]}, include_blank: true) %>
You can use the following monkey patch to add the include_blank argument to options_for_select
module OptionsForSelectIncludeBlankPatch
def options_for_select(container, selected = nil)
if selected.is_a?(Hash)
include_blank = selected[:include_blank] || selected['include_blank']
end
options = super
if include_blank
include_blank = '' if include_blank == true
if Rails::VERSION::MAJOR >= 5 && Rails::VERSION::MINOR >= 1
str = tag_builder.content_tag_string(:option, include_blank, {value: ''})
else
str = content_tag_string(:option, include_blank, {value: ''})
end
options.prepend(str)
end
options
end
end
ActiveSupport.on_load(:action_view) do
ActionView::Base.send(:include, RearmedRails::RailsHelpers)
end