How do I use Rails to create a drop-down selection box? Say if I have done the query:
#roles = Role.all
Then how do I display a box with all the #roles.name's ?
EDIT: After implementing the dropdown box. How do I make it respond to selections? Should I make a form?
use the collection_select helper
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#M001593
This will allow you to write something like:
collection_select(:user, :role_id, #roles, :id, :role_title, {:prompt => true})
And get
<select name="user[role_id]">
<option value="">Please select</option>
<option value="1" selected="selected">Administrator</option>
<option value="2">User</option>
<option value="3">Editor</option>
</select>
This will create a drop down that displays the role name in the drop down, but uses the role_id as the value passed in the form.
select("person", "role_id", #roles.collect {|r| [ r.name, r.id ] }, { :include_blank => true })
The form helper has a group of methods specifically written to create dropdown select boxes. Usually you'll use the select_tag method to create dropdown boxes, but in your case you can use collection_select, which takes an ActiveRecord model and automatically populates the form from that. In your view:
<%= collection_select #roles %>
Find out more about the Rails form helper here: http://guides.rubyonrails.org/form_helpers.html
Display role name as comboBox showing text (1st pluck argument) and it represents the role id
Controller
#roles = Role.pluck(:name, :id)
View
<%= select("role", "role_id", #roles) %>
params[:role][:role_id] passed to controller from view.
Related
This is my biblios_helper.rb:
def main_language
[["français","frenchLit"],["latin","latinLit"],["ancien français","froLit"],["néerlandais","dutchLit"]]
end
the form for adding a new bibliography contains :
<%= f.select(:langue_main) do %>
<% options_for_select(main_language, selected: params[:biblio] ? params[:biblio][:langue_main] :"") %>
<% end %>
This results in this html :
<select name="biblio[main_language]" id="biblio_main_language"><option value="frenchLit">français</option>
<option value="latinLit">latin</option>
<option value="froLit">ancien français</option>
<option value="dutchLit">néerlandais</option></select>
That works fine. However, I have the same code in the form that allows for the updating of the bibliography.
when in the database, the language is 'froLit', I want the default to show up in the select menu to be 'ancien français'. How do I do that?
On edit form it will automatically select the corresponding option as default which options is saved in database for this object -
<%=f.select :langue_main, options_for_select(main_language) %>
However if you want to be default selected as always to be ["ancien français","froLit"] Then try this one -
<%=f.select :langue_main, options_for_select(main_language, "froLit") %>
maybe just:
= f.select :langue_main, options_for_select(main_language, params.dig(:biblio, :langue_main))
I have this with simple form:
= simple_form_for(Note.new, remote: true) do |f|
= f.collection_select :dance_id, current_user.dances.includes(:style).all,
:id, :style_name, {prompt: "Please select dance"}, {class: "form-control"}
Code generated:
<select class="form-control" name="note[dance_id]" id="note_dance_id">
<option value="">Please select dance</option>
<option value="39">Adowa Dance (Ghana)</option>
<option value="38">Adowa Dance (Ghana)</option>
<option value="37">Tango (Argentina)</option>
</select>
which works fine as it is displaying all dances by style_name as i want it. But i want to make a difference between two dances and want to also show level and date right next to each dance in the collection because there are many dances with same name bc of the style which is the same!
please help. any better way to do it with simple form helpers?
As stated in the discussion, you needed to declare a method in your model's rb file like this:
def custom_name
"#{style.name}. #{date}"
end
And change the :style_name parameter to :custom_name
I have this lines in my form
<%= f.fields_for :attached_vehicles do |av| %>
<p>Select make</p>
<%= av.select :make, options_for_select(#makes.collect { |make|[make.make_name, make.id] }), { include_blank: "Select make" }, {} %>
...
<% end %>
which renders this in html
<select name="diy[attached_vehicles_attributes][0][make]" id="diy_attached_vehicles_attributes_0_make">
<option value="">Select make</option>
<option value="1">ACURA</option>
<option value="2">ALFA ROMEO</option>
<option value="3">AM GENERAL</option>
<option value="4">AMERICAN IRONHORSE</option>
<option value="5">AMERICAN LAFRANCE</option>
...
</select>
So now it saves the value of selected option to database, and i need it to save content of selected option.
Also I can't just replace make.id with make.make_name in "options_for_select", because I need value to be id so my other dynamic select box gets right options depending on selected option.
------------------------------------------------------------------------------------------------------------------------------------EDIT
So I did as Dharam suggested
...
def diy_params
params[:diy][:attached_vehicles_attributes].each_with_index do |make_id, index|
params[:diy][:attached_vehicles_attributes][index][:make] = Make.find(make_id).make_name
end
params.require(:diy).permit(:title, :summary, :tip, :warning, attached_vehicles_attributes: [:make, :model, :start_year, :end_year], steps_attributes: [:step_content, add_images_to_steps_attributes: [:image]])
end
...
And I keep getting this error
Couldn't find all Makes with 'id': (0, {"make"=>"12", "model"=>"XPEDITOR", "start_year"=>"2002", "end_year"=>"2010"}) (found 0 results, but was looking for 2)
So i have tried
...Make.find(make_id.first.make).make_name
and multiple other things but didn't get it working, what i'm doing wrong?
------------------------------------------------------------------------------------------------------------------------------------EDIT2
The value of make_id seems to be
(0, {"make"=>"12", "model"=>"XPEDITOR", "start_year"=>"2002", "end_year"=>"2010"})
because it tries to find Make with it as id.
And parameters in console looks like
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Kr4yvJUPCzUagUaW1glt69HEychEz+6QyHpGjKVKQ883rTUl0pZD+9SZSaQujHgM9k7jRt0vP1WTV5fMp8xyJw==", "diy"=>{"attached_vehicles_attributes"=>{"0"=>{"make"=>"12", "model"=>"XPEDITOR", "start_year"=>"2002", "end_year"=>"2010"}}, "title"=>"afaf", "summary"=>"AFSfAS", "tip"=>"FAF", "warning"=>"fdsgfsd", "steps_attributes"=>{"0"=>{"step_content"=>"gsdgsdg"}}}, "commit"=>"Create Diy"}
Before processing the params in your controller, you can do the following:
params[:diy][:attached_vehicles_attributes].each do |index, make_attributes|
params[:diy][:attached_vehicles_attributes][index]['make'] = Make.find(make_attributes['make']).name
end
You can replace Make model with the actual model that is backing the #models.
I've got this problem where I get the dropdown showing but the selected option is not showing up. Here's the code I have to generate the selection dropdown in the .erb:
<%= collection_select("url", "source_type_id", #source_types, :id, :name, {:prompt => "Please select..."}) %>
The #source_types is populated in the controller from a lookup table that is tied to the model. #url_object is the model:
#source_types = SourceType.all
Because of the way the model is tied to the lookup table:
belongs_to :source_type
#url_object.source_type_id returns the numeric value, and #url_object.source_type returns the associated name from the lookup table.
<select id="url_source_type_id" name="url[source_type_id]"><option value="">Please select...</option>
<option value="1">Dictionary/Thesaurus</option>
<option value="2">Encyclopedia</option>
<option value="3">Magazine</option>
<option value="4">Map/Atlas</option>
<option value="5">Newspaper</option>
<option value="6">Reference Tools</option></select>
I read the API for this method and the implication is that if the source_type_id is present the collection_select will automagically pick it up and set the selected value, but this is clearly not happening.
I'm hoping someone will see what obvious mistake I've made here...
Hope this will help
<%= f.select :source_type_id, #source_types.collect{|p| [p.name, p.id] }, params[:source_type_id] %>
I have a settings model with a column options, and set it to serialize with serialize :options. In my view, I have a multiple selection box, using select("settings", "options", ['option1','option2','option3'], {}, :multiple => true) which works fine so long as the user selects at least one option. However, if they don't select any options, no options are submitted and so the options aren't updated.
How do I allow the user to select zero options from a multiple selection box in rails?
That has nothing to do with rails: html form won't send such parameter to server if nothing is chosen in 'select' element. But you should be able to fix it in controller. Something like this
if params[:settings] == nil
params[:settings] = [];
end
Not sure if there's more elegant solution.
Add a hidden field after the select box, that posts an empty value to "settings[options]"
It's same trick that rails uses to make sure unchecked checkboxes get posted as false.
I do not like assuming a value is empty if the attribute is not posted. It breaks the way Rails expects to update attributes, and it can present problems if you are using your controller actions also for APIs as well as HTML. My preferred way of handling this is by adding a hidden input field before multiselects.
<input type="hidden" value="" name="parent_model[my_attribute_ids][]">
If you use JQuery you can automate the addition of these hidden input fields:
$('select[multiple="multiple"]').each(function(i){
$(this).before('<input type="hidden" name="'+this.name+'" value="" />')
});
I realize this answer is not very timely, but I hope this will help someone with a similar question.
You could provide a "None" option.
Example from: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:include_blank => 'None'}, {:multiple => true})
Would become
<select name="post[person_id]" multiple="multiple">
<option value="">None</option>
<option value="1">David</option>
<option value="2" selected="selected">Sam</option>
<option value="3">Tobias</option>
</select>