I have a select with options filled in from a collection
<%= select('task', 'person_id', Person.where(:job_id => #job.id).order(:name).collect {|p| [p.name, p.id]}, {:include_blank => true}, :required => true) %>
I'd like to add a 'Not Applicable' option to this select but am unsure how. I have it set to add a blank and I also have it set to required. With both of those true, someone can't just choose the blank. I have the required set because I want my staff to think about the option they select.
Thanks for the help!
I'd create a helper method something like this
def person_options(options = {})
options_for_select([["Not Applicable", ""]] + Person.where(:job_id => #job.id).order(:name).collect {|p| [p.name, p.id]}, options)
end
Then you can call it from erb like so
<td><%= f.select :person_id, person_options(selected: #person. person_id, include_blank: true), {}, {style: 'width:auto'} %></td>
might need to tweak for your project
Related
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'd like to add an "Other" option with the value -1 in this select:
<%= f.select :id, options_from_collection_for_select(#vehicles, :id, :model, "#used_vehicles[i]") %>
Should I replace #vehicles with something else?
If you can, you should use the already existant behaviour in Rails, which is to use the include_blank option:
<%= f.select(:id, #vehicles.collect {|p| [ p.name, p.id ] }, {include_blank: 'Other'}) %>
You can check the documentation also.
I am editing a Rails 2 application. In it, a user submits a form that includes a dropdown menu, and that information creates a record in my database. When the user goes to edit the record, I want to show the saved "selected" option in the dropdown menu. I keep getting errors, however. Here is my set-up:
View Select Field
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.select :start, options_for_select(#itinerary.locations), {:include_blank => true}, {:id=>"startdrop" } %>
Form Helper
def options_for_select(locations)
locations.map do |l|
content_tag "option", l.masterlocation.name, location_option_attributes(l)
end.join("\n")
end
private
def location_option_attributes(location)
{
:value => "#{location.masterlocation.street_address}, #{location.masterlocation.city}, #{location.masterlocation.state}, #{location.masterlocation.zip}",
:id => location.masterlocation.id,
:"data-masterlocation-name" => location.masterlocation.name,
:"data-masterlocation-id" => location.masterlocation.id,
:"data-masterlocation-latitude" => location.masterlocation.latitude,
:"data-masterlocation-longitude" => location.masterlocation.longitude
}
end
I have tried making the view look like this:
<%= f.select :start, options_for_select(#itinerary.locations, #newsavedmap.start), {:include_blank => true}, {:id=>"startdrop" } %>
But I get wrong number of arguments (2 for 1)) for that line. Also tried
<%= f.select :start, options_for_select(#itinerary.locations), {:selected => #newsavedmap.start, :include_blank => true}, {:id=>"startdrop" } %>
But nothing is preselected when I go to edit the saved map. I've tried following these links, and keep striking out. Appreciate any help you have to offer!
Rails select helper - Default selected value, how? , Rails form_for select tag with option selected , Rails select helper - Default selected value, how?
You could try something like this in your helper
def options_for_select(locations, selected=nil)
locations.map do |l|
tag_options = location_option_attributes(l)
if l == selected
tag_options[:selected] = "selected"
end
content_tag "option", l.masterlocation.name, tag_options
end.join("\n")
end
then call field like you were trying before.
<%= f.select :start, options_for_select(#itinerary.locations, #newsavedmap.start), {:include_blank => true}, {:id=>"startdrop" } %>
You can pass one more parameters to select the value like this:
<%= f.select :start, options_for_select(#itinerary.locations), :selected => #newsavedmap.start, {:include_blank => true}, {:id=>"startdrop" } %>
I'm trying to create a select box that takes data from my db. I'm having trouble setting this up. I tried this code:
<%= f.fields_for :unit do |u| %>
<%= u.label :name %>
<%= u.select :name, :class => "ingredient_unit", :prompt => "Please Select" %>
<% end %>
but I'm missing the part of the choices, I don't know how to pull them out of the database. I tried using collection_select, which worked, but then the class option wasn't working... collection_select went like this:
<%= u.collection_select :unit, Unit.all, :id, :name, :class => "ingredient_unit", :prompt => "Please Select" %>
I also don't understand what the first symbol means (:unit), it seems to be setting the html id and name, so that can be anything I want it to be?
You should look at the documentation for collection_select and select. But to answer your question, for the select part, you forgot to pass the list of options to choose from. You also need to swap the order for prompt and class since prompt is an option for the helper and class is an html option
<%= u.select :unit_id, Unit.all.map { |u| [u.name, u.id] }, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
For the collection select
<%= u.collection_select :unit_id, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
The first parameter passed to both helper is the column name where you want the selected answer to be saved. The 2 codes above just shows 2 different ways to generate the same select tag.
The first symbol tells it which field to populate with the id returned from the user selection.
Also, you should wrap your class section in {}
:unit refers to the model attribute that you're using for the select element. Yes, it will setup the name/id of the element (and name is the most important for the params hash).
To set a class in the collection_select, specify it as a hash as that helper takes it as an html_option.
<%= u.collection_select :unit, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
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