I have an array like this:
['New York', 'Los Angeles']
And I want to be able to generate a select/option with those values in a form like this:
<%= form_tag filter_city_path, :method=> get do %>
<%= select_tag "city", #list_of_cities %>
<% end %>
But this is not working. As you can see I want to pass the selection as city in the url.
You need to use options_for_select helper like
<%= select_tag "city", options_for_select([['New York' ,'New york'], ['Los Angeles', 'Los Angeles']]) %>
My method for this is to build the array as a constant in the model, force confirmation to options listed in the constant, and call it from the view
class Show < ApplicationRecord
DAYS = [ "monday", "tuesday", "wednesday", "thursday","friday", "saturday","sunday"]
validates :day, inclusion: DAYS
end
If you want the option for that field to be submitted without content you'll have to call `allow_blank: true' in the validation as well. Once that is set up you can call the constant to populate the view in the form as so:
<%= select_tag "day", options_for_select(Show::DAYS) %>
or
<%= select_tag "day", options_for_select(Show::DAYS.sort) %>
if you want it presorted (which makes no sense with days of the week...)
It looks like your array doesn't have enough argument. Please refer to this guide.
The options typically needs to be formatted in this way:
[['Lisbon', 1], ['Madrid', 2], ...]
Take note the value 1, 2, etc.
Related
I am working on the rails 5 application. I need to display dropdown of project.
I have #projects on controller and its values are
[["Company Team Meeting", 25], ["BuildEffective", 1], ["VCF ", 86], ["StomerijCollectief", 114], ["StomerijCollectief - Enhancement", 130], ["Stomerij Mobile App", 135], ["Blog Writing", 138], ["Stomerij Design Enhancements", 139]]
On view side I am using following code
<%= f.options_for_select(#projects.map {|p| [p.name, p.id]})%>
this gives me following error
undefined method `name' for ["Company Team Meeting", 25]:Array
Please help me
Please note: I am not in the projects controller
You can use <%= f.options_for_select(#projects, object.id) %>.
object_id will auto populate dropdown on edit.
Since you already have an array of pairs you can just pass it straight to options_for_select:
<%= options_for_select(#projects) %>
But if you have a collection of records instead (instead of two plucked columns or wherever this data comes from) with you can use the collection_select helper instead of manually building the option tags and select tag.
<%= f.collection_select(:project_id, Project.all, :id, :name) %>
# or
<%= f.collection_select(:project_ids, Project.all, :id, :name, multiple: true) %>
your #projects object is an Array type and so it don't have attributes like name and id.
you can place it like <%= f.select :projects, options_for_select(#projects) %>
I am trying to pass to my select_tag both fixed values and loop values. I can perfectly write something like :
<%= select_tag "", options_for_select(session[:user_hotel_list].collect{ |hotel| [hotel["name"], hotel["id"]] }) %>
Here hotel["name"] will be the displayed value and hotel["id"] the "real value" of the field.
But if I try to add extra fixed values to my options_for_select I dont get the desired output. Let's say I want to add a select with "all hotels" with a value of "all". I would try something like that :
<%= select_tag "", options_for_select([["all hotels", "all"], session[:user_hotel_list].collect{ |hotel| [hotel["name"], hotel["id"]] }]) %>
But here I would get an array as output for the collection...
How can I correctly add extra fixed data to an options_for_select with a collection in rails ?
EDIT
For example this code :
<%= select_tag "dash_select", options_for_select( [["all hotels", "all"], ["other", "value"]] << session[:user_hotel_list].collect{ |hotel| [hotel["name"], hotel["id"]] }) %>
outputs this :
and obviously ["plaze", 31] isnt good !
Do you really need to add multiple items? Or is your example with just "All hotels" sufficient. Because in that case you could just do:
<%= select_tag "", options_for_select(...), { include_blank: "all hotels" } %>
I have a form built with the bootstrap_form gem for ruby. within the form I have some radio buttons. the form renders perfectly with the correct labeling in the edit page of the form, however once I save the form and go to the "show" page to see the results, the inputs for the radio buttons are only showing the value of the radio button (which are numbers) and not the custom label name I have assigned. How can I make the custom label appear instead of the value in the show page?
Here is my code:
_form.html.erb:
<%= f.form_group :gender, label: { text: "Gender" } do %>
<%= f.radio_button :gender, 0, label: "Female", checked: true, inline: true %>
<%= f.radio_button :gender, 1, label: "Male", inline: true %>
<% end %>
<%= f.form_group :nationality, label: { text: "Nationality" } do %>
<%= f.radio_button :nationality, 0, label: "Kuwaiti", checked: true, inline: true %>
<%= f.radio_button :nationality, 1, label: "Non-Kuwaiti", inline: true %>
<% end %>
show.html.erb
<p><strong>Full Name:</strong> <%= #profile.name %></p>
<p><strong>Civil ID no:</strong> <%= #profile.civil %></p>
<p><strong>Gender:</strong> <%= #profile.gender %></p>
<p><strong>Nationality:</strong> <%= #profile.nationality %></p>
<p><strong>Mobile no:</strong> <%= #profile.mobile %></p>
<p><strong>Personal Email:</strong> <%= #profile.personal_email %></p>
Thanks for the help in advance!
Update:-
New form code:-
<%= f.form_group :gender, label: { text: "Gender" } do %>
<%= f.radio_button :gender, 1 %>
<%= f.label 'Female', inline: true, checked: true %>
<%= f.radio_button :gender, 0 %>
<%= f.label 'Male', inline: true %>
<% end %>
Tried this suggestion but still getting the same problem, only the the radio buttons are no longer in line and have incorrect formatting.
You need a lookup table
You have saved numeric values that correspond to the radio button. So, when you display the variable in the show.htm.erb it is showing the numeric values retrieved from the database record. This makes sense. But you need the string associated with the number, which requires a lookup table
Creating labels in the form does not create custom labels for your field. To create custom field labels, you would need to setup i18n localizations for your activerecord models, which is a good solution, but also one that will take some time and learning curve.
Creating a hash-based lookup table.
Active Hash gem
You could write your own lookup helper or use this gem which simplifies implementing hash-based lookup tables.
Example
# in app/models/person.rb
class Gender < ActiveHash::Base
self.data = [
{:id => 0, :gender => "Female"},
{:id => 1, :gender => "Male"}
]
end
From their spec
We wrote ActiveHash so that we could use simple, in-memory, ActiveRecord-like data structures that play well with Rails forms...
Build error in gem (Update)
I just checked an it seems their build has an error. Probably best to avoid for now.
Using view helpers to translate boolean values to strings (Added)
You could implement helpers your /helpers/profile_helper.rb. I call them "lookups," but that is probably not standard.
For each of the boolean you need to translate to strings create a helper
#profile_helper.rb
# Each of your booleans
def gender_to_s(value)
value ? "Male" : "Female"
end
def nationality_to_s(value)
value ? "Kuwaiti" : "Non-Kuwaiti"
end
# Generic true/false conversion
def boolean_to_s(value)
value ? "Yes" : "No"
end
Note: I would name the helpers consistently to match the field name, so in your view it is very obvious which "to_s" to invoke.
In your view
<p><strong>Gender:</strong> <%= gender_to_s(#profile.gender) %></p>
Note: If you wanted a single view helper, this could be implemented in application_helper.rb and include a passed parameter "type" as a switch control, but I think the most straightforward solution is to create a view helper for each field.
You want a separate tag for the labels. Instead of:
<%= f.radio_button :gender, 1, label: "Male", inline: true %>
You need:
<%= f.radio_button :gender, 1 %>
<%= f.label 'Male, inline: true %>
Might also be worth looking at this answer: Bootstrap 3: does form-horizontal work for radio buttons with a control-label?
It doesn't use the form label helper, but it looks like it does what you need.
OK one more approach so that you have a full set to choose from. In Rails 4.1, enum data types were implemented in ActiveRecord as described in section 2.5 of the release notes. If you are running Rails 4.1+, you can take advantage of this new feature.
Essentially, you will need to write migrations to change your boolean and other data types to enum. For instance, for the gender example, rather than having gender of 0 signify female and 1 signify male, and maintain a mapping for that, you could simply have:
enum gender: [:female, :male]
and likewise for your other attributes.
This should ultimately be easier to maintain and will help keep your application code as transparent as possible.
<label><%= form.radio_button :gender, 1, hide_label: true, inline: true%>Female</label>
<label><%= form.radio_button :gender, 0, hide_label: true, inline: true%>Male</label>
worked for me Bootstrap 4.1
I'm using rails 4 and I'd like to list categories in a select drop down menu. How can I do that? I have a form that looks like so:
<%= f.select (:category_id),
options_for_select([
["Maths", 1],
["Physics", 2]
])
%>
but of course, the content has to be dynamic from database, so I tried the following:
options_for_select([
#categories.each do |c|
[c.title, c.id]
end
])
but that outputs #<Category:randomdigetshere> if I try to get the same output outside of that options_for_select it works and the title / id is being displayed as it should.
What's the right way of doing it?
You could do
<% categories_array = Category.all.map { |category| [category.title, category.id] } %>
<%= options_for_select(categories_array) %>
or
<%= options_from_collection_for_select(Category.all, :id, :title) %>
You can make it even shorter using collection_select
Assuming your #categories's format is:
#categories = Category.all
You can do:
options_for_select(#categories.map { |category| [category.title, category.id] })
I cannot tell you how many times I've looked this up and fat fingered my way around it. Here's my take on it which includes:
default text displayed in select drop down
a method call on the instance which merges first_name and last_name attributes
sets :selected so it is available when editing
sets a class (useful for simple_form integration)
select_tag(:doctor_id, options_for_select(["Select doctor"] + #doctors.map{ |doctor| [doctor.full_name, doctor.id] }, :selected => :doctor_id), :class => 'form-control')
Remember that this needs to be wrapped in outputting tags i.e. <%= and %>
What options_for_select does is take an array and format into the native html options tag format along with the selected attribute, etc. What's going on here is that we initialize the array with a element titled "Select doctor" and then we append to that an array of items which look like ["Bob Smith", 1]
I have a complex form (like Ryan B's Complex Form Railscasts) where I have a few levels of database tables being altered at the same time.
The code for this dropdown box works in that it delivers the correct integer to the database. But, despite numerous attempts I cannot get it to correctly reflect the database's CURRENT value. How can I sort out this code?
<%= o.select :weighting, options_for_select([
["Correct", "4", {:class=>"bold"}],
["Good", "3"],
["Average", "2"],
["Poor", "1"],
["Incorrect", "0", {:class=>"bold"}] ], :weighting), {},
html_options = {:class => "listBox", :style=>"float:left;"} %>
Thanks.
You're on the right track, but not quite there.
While the final argument to options_for_select should be the value of the selected option. The value you supply :weighting is a symbol that does not match the value of any of your given options.
You will need to give the actual value. If you used an instance object to build the form as in
<%form_for #whatever do |o|%>
...
You can simply used #whatever.weighting.to_s as in:
<%= o.select :weighting, options_for_select([
["Correct", "4", {:class=>"bold"}],
["Good", "3"],
["Average", "2"],
["Poor", "1"],
["Incorrect", "0", {:class=>"bold"}] ], #whatever.weighting.to_s), {},
html_options = {:class => "listBox", :style=>"float:left;"} %>
Otherwise, there's a way to get the object off the form block variable o. But that's messing with internals which may change with an upgrade.
Edit: In the case where you're working with fields for and multiple partials, you can get the particular object off of the form builder block variable.with the object accessor.
Reusing the above example something like this to use the current weighting of each child instance in that instance's section of the form.
<% form_for #parent do |p| %>
...
<% p.fields_for :children do |c| %>
...
<%= c.select :weighting, options_for_select([
["Correct", "4", {:class=>"bold"}],
["Good", "3"],
["Average", "2"],
["Poor", "1"],
["Incorrect", "0", {:class=>"bold"}] ], c.object.weighting.to_s), {},
html_options = {:class => "listBox", :style=>"float:left;"} %>
...
<% end %>
<% end %>
This can also be used in partials.
Second try =)
<%= f.label :priority %>
<%= f.select(:priority, options_for_select({"Stat" => "1", "Urgent" => "2", "Regular" => "3", "Safety" => "4"}, #servicerequest.priority), :prompt => "Choose") %>