Select onchange not being written - ruby-on-rails

Rails 2.3.5, Ruby 1.86
I haven't been able to figure this out. The 'onchange' in the select below is not being written (no onchange written in the HTML). I haven't seen a reference to the syntax being different except in some older examples the onchange is surrounded in brackets:
<%= f.select :directory_id, options_for_select(#directories, #directory_to_select), :onchange => 'folder_lookup()' %>
results in:
<select id="contact_directory_id" name="contact[directory_id]">
<option value="2">test_1</option>
<option value="4">test_2</option>
<option value="33" selected="selected">test_3</option>
</select>
If I simply change "f.select" to "select_tag" the onchange is written correctly (not that I want to do that though):
<%= select_tag :directory_id, options_for_select(#directories, #directory_to_select), :onchange => 'folder_lookup()' %>
results in:
<select id="contact_directory_id" name="directory_id" onchange="folder_lookup()">
<option value="2">test_1</option>
<option value="4">test_2</option>
<option value="33" selected="selected">test_2</option>
</select>
Am I missing a syntax difference for onchange between a select and select_tag helper?
Thanks!

This is what you want:
<%= f.select :directory_id, options_for_select(#directories, #directory_to_select), {}, :onchange => 'folder_lookup()' %>
With select the method signature looks like this select(object, method, choices, options = {}, html_options = {}). onchange is an html_option, since you don't have any options, you need an empty hash so that your last onchange is taken as an html_option.

Related

RoR - Select tag with include_blank disable

I want a result like this :
<select dir="rtl">
<option selected disabled>Choose a car</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
With the following code I can only end up with :
<%= f.select(:car, xxxxxx, {:include_blank => 'Choose a car', :disabled => 'Choose a car'}) %>
=>
<select id="xxx" name="xxx">
<option value="">Choose a car</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
The first option is not disabled...
Ito A's answer will not work in Rails 4.2 (Unsure about earlier versions).
From the documentation...
:disabled - can be a single value or an array of values that will be disabled options in the final output.
Therefore, the :disabled option should be given a value that matches the value of one of the options in the collection. So, :disabled => 'volvo' would disable the option with value='volvo'. However, it will not match the include_blank option, because that option is not part of the collection passed into the select method.
Rails select helper does not directly support the desired behavior. However, you can work around it by adding a blank option to the collection as follows.
Create the collection and then add a blank option to it.
car_names = %w(volvo saab mercedes audi)
car_names_with_blank = car_names.map{|c| [c, c]}.prepend(['Choose a car', nil])
In the view:
<%= f.select(:name, car_names_with_blank, {disabled: '', selected: ''}) %>
Here's a link to a Github repository with a working example. The example also shows that Ito A's answer and other answers to similar SO questions will not work.
UPDATED: I Have updated my answer with a solution and additional info.
I believe they add the functionality in Rails 6.
From the pull request:
Enable select tag helper to mark prompt option as selected and/or disabled for required field. Example:
select :post,
:category,
["lifestyle", "programming", "spiritual"],
{ selected: "", disabled: "", prompt: "Choose one" },
{ required: true }
Placeholder option would be selected and disabled. The HTML produced:
<select required="required" name="post[category]" id="post_category">
<option disabled="disabled" selected="selected" value="">Choose one</option>
<option value="lifestyle">lifestyle</option>
<option value="programming">programming</option>
<option value="spiritual">spiritual</option>
</select>
I believe what you are looking for is as below:
<%= f.select(:car, xxxxxx, {:include_blank => 'Choose a car', :disabled => 1}) %>
An application of the above noted solution follows.
create the application helper function
def build_selections(prompt: "Select One", selections: {})
selections.reverse!.push([prompt, nil]).reverse!
end
then use it in your view:
<%= f.select :category_id, build_selections(prompt: 'Select Category',
selections: #category.collect{|x| [x.name, x.id]}),
disabled: '' %>

Adding multiple data in select option rails 4

I am using bellow code and function options_from_collection_for_select for generating options for user.
<%= select_tag 'receiver', options_from_collection_for_select(#user, 'id', 'email') %>
Above code generate bellow html:
<select id="receiver" name="receiver" style="display: none;">
<option value="1">email1#yahoo.com</option>
<option value="2">email2#gmail.com</option>
<option value="3">email3#gmail.com</option>
</select>
But i want email with username, e.g <optionvalue="1">email1#yahoo.com(some_user)</option>
Suggestion any alternate function or customize current function will be appreciated.
In your User model add a method :
def user_dispay_name
"#{email}(#{full_name})"
end
Now do :
<%= select_tag 'receiver', options_from_collection_for_select(#user, 'id', 'user_dispay_name') %>
But without options_from_collection_for_select this function i'm using below code:
<%= select_tag 'receiver', options_for_select(#user.map{ |c| ["#{c.email} (#{c.display_name})", "#{c.id}"] }) %>

How can we set selected option in select_tag with option_for_select in ruby

I have a select_tag in ruby on rails. The syntax for this is,
<%= select_tag "iso_region", options_for_select(#all_regions.collect {|p| [ "#{p['cc']}-#{p['lr']}", p['cc'] ] }), class: "form-control selectpicker reg_name", :data => {:'live-search' => 'true'} %>
Sample Options generated is like this,
<option value="ET">ET-Africa</option>
<option value="NG">NG-Africa</option>
<option value="PG">PG-Pacific</option>
<option value="IT">IT-Europe</option>
And I want IT-Europe to be selected in the dropdown.
How can I do that with my select_tag?
Try this:
options_for_select(#all_regions.collect {|p| [ "#{p['cc']}-#{p['lr']}", p['cc'] ] }, "IT"),
The last arg you pass to options_for_select is the value to be marked selected when it's rendered.

Adding extra html attributes to a Rails collection_select

I'm using
f.collection_select :country_id, Country.all, :id, :name)
which generates
<select name="user[country_id]" id="user_country_id">
<option value="1">Canada</option>
<option value="2">United Kingdom</option>
<option value="3" >United States</option>
</select>
I would like to include a prov-val and code-val attribute to the select so I can dynamically update the province labels:
<select name="user[country_id]" id="user_country_id">
<option prov-val="Province / Territory" code-val="Postal Code" value="1">Canada</option>
<option prov-val="County" code-val="Postcode" value="158">United Kingdom</option>
<option prov-val="State" code-val="ZIP Code" value="2" >United States</option>
Is this possible using a collection_select ?
Not sure if it's possible using collection_select, but I think using select does what you want:
<%= f.select :country_id, Country.all.map {|c| [c.name, c.id, {:'prov-val' => c.prov_val, :'code-val' => c.code_val}]} %>
This assumes that your country object has the prov_val and code_val fields.
You shouldn't be calling the model right from the view.
It is better to use an instance variable instead:
<%= f.select :country_id, #countries.map {|c|
[c.name, c.id, {:'prov-val' => c.prov_val, :'code-val' => c.code_val}]
} %>

Selected attribute depending on params value with Rails

I have an action that renders a view which contains this:
<select id ='dynamic_select'>
<option value = "<%= activity_path %>">All</option>
<option value = "<%= activity_path(:type => 'enrolled') %>">Enrolled</option>
<option value = "<%= activity_path(:type => 'redeem') %>">Redeem</option>
<option value = "<%= activity_path(:type => 'social') %>">Social</option>
</select>
What would be the correct/Rails way of rendering that select and mark as selected one of the options depending on the type parameter:
If there is no type parameter, select "All" options, if there is type=enrolled parameter select Enrolled option, and so on...
I have managed to do that client side with Javascript, but I am wondering what would be the Rails way of doing so.
Rendered HTML:
<select id="dynamic_select" name="dynamic_select">
<option value="/activity">All</option>
<option value="/activity?type=enrolled">Enrolled</option>
<option value="/activity?type=redeem">Redeem</option>
<option value="/activity?type=social">Social</option>
</select>
Something like the following. I have displayed the select_options here, but you should probably generate them in your controller and pass them through to the view.
The key is using options_for_select.
<% select_options = {"All" => activity_path} %>
<% %w{Enrolled Redeem Social}.each {|opt| select_options[opt] = activity_path(:type => opt.downcase)} %>
<% form_for(resource) do |f| %>
<%= s.select :dynamic, options_for_select(select_option, :selected => select_options[#default || "All"]) %>
<% end %>

Resources