Rails collection_select default select - ruby-on-rails

In Rails 4 in view I have
<%= form_for #person do |f| %>
<%= f.collection_select :country_id, Country.order(:name), :id, :name, include_blank: "Select your country" %>
...
<% end %>
I'd like "Select your country" to be selected as default whenever the page is loaded. One way is to use javascript (select it after the dom is loaded). Is there an easier way like adding an option to collection_select?
Thanks.

As per the docs, it's the prompt option in the options argument:
collection_select(:post, :author_id, Author.find(:all),
:id, :name_with_initial,
{:prompt => 'Please select the author of this post'})
With collection_select on a form builder we omit the first argument, so in this case:
f.collection_select :country_id, Country.order(:name), :id, :name, {prompt: 'Select your country'}
I've 100% confirmed this as working on my own app running Rails 4.1.6, where prompt and include_blank do the same thing.
The way this works is Rails injects a null-valued <option> as the first item in the generated <select> (this is because the HTML spec has nothing analogous to placeholder on text inputs for select inputs).
Reasons this may fail:
Rails does not mark the prompt option with the selected attribute, and I suspect some browsers may choose to render their own blank entry instead of the first in the list
If, for existing records, Rails determines that the current record's country_id matches an element in the list it will mark that one as selected. This is expected behaviour but can be a pain if you're doing anything non-standard.
If you're being bitten by these problems your options are to build the form manually (the method options_from_collection_for_select may be of use here) or do it in javascript. There is also an undocumented default attribute you can add to an <option> tag but it's not in the spec and browser support may be patchy, and you'd still have to build the form manually.

Related

How to make a collection_select in rails that only displays options with a specific attribute

I'm building an app where a user can customize components in a pc(system), based on components that are available in their respective tables (eg. motherboards table, cpus table.. etc)
I would like the user to be able to select the components via a dropdown select in the system form.
I have been able to achieve this by using collection_select like this
<%= collection_select(:system, :motherboard_id, Motherboard.all, :id, :model, prompt: true) %>
However, the collection_select displays all components in the table, and I wish to only display those components that have an available: true attribute.
I have tried
<%= collection_select(:system, :motherboard_id, Motherboard.any? {|mobo| mobo.available?} , :id, :model, prompt: true) %>
which results in undefined method 'map' for false:FalseClass screenshot:
I thought about adding a before_save callback that checks each items availability, but if that's not the only way to get it to work, I think that would be a poor decision in terms of UX
You can use
<%= collection_select(:system, :motherboard_id, Motherboard.where(available: true), :id, :model, prompt: true) %>

Rails Form Select Requirement with partial

I'm creating a form with a .select field that loads a list of states via partial. The requirement isn't being enforced on state and I'm not sure why. It lets you submit the form with the default blank value 'State'
Would appreciate any help figuring out where my syntax is wrong on this form? If this looks foreign, using SLIM instead of HTML.
= f.select :state, nil, include_blank: 'State', required: true # not working
= render partial: 'addresses/states'
= f.text_field :zip, placeholder: 'Zip', required: true, pattern:'[0-9]*' # works
The states partial looks like this:
option value="AL" AL
option value="AK" AK
option value="AZ" AZ
option value="AR" AR
...

How to implement multi select in a independent table in Rails?

My problem is that I have, for example, Product, Category and ProductCategory.
ProductCategory makes possible for a Product have several Categories
I would like to implement this using Select2 (http://ivaynberg.github.io/select2/) using the select2-rails gem (https://github.com/argerim/select2-rails)
I already know how to relate the models but I can't figure out how to implement the Select2 specific code.
EDIT:
Now I see that my problem was not much about select2, so I added this comment and changed the title hoping that it can help somebody else
Now I see that my problems were not about select2 but to do a multi select.
The code in the _form.html.erb that make it work is this one:
<%= f.label :category_id %>
<%= f.collection_select :category_ids, Category.order(:name), :id, :name, {:selected => #product.category_ids, :include_blank => true}, {:class => 'col-xs-12 col-md-7 padding_15', :multiple => true} %>
I also included :category_ids in the attr_accessible on models/product.rb
And the select2 specific, I included in a .js file
$(document).ready(function() {
$('#product_category_ids').select2();
});
I'm including these links as they helped me but pay attention on the differences depending on the Ruby/Rails versions
http://www.dzone.com/snippets/using-mutiple-collection
http://www.alethe.com/brad/2009/10/multiple-select-list-in-rails/
Just to let you know, unexpectedly, if this collection_select is the last line in my form, some form fields are disabled although there is nothing that states this in the source. Changing the order this problem doesn't exist.
I also don't know why the look is a little different than the other fields (I'm using Bootstrap 3)

Rails - binding versus not binding a rails collection select

So I was experiencing an error when I was attaching a collection_select to my form_for object like so:
<%= f.collection_select(:city_id, #cities, :id, :name, {:prompt => "Select a City"}, {:id => 'cities_select', multiple: true}) %>
and getting the error:
undefined local variable 'city_id'
But when I don't bind the select like so:
<%= collection_select(nil, :city_id, #cities, :id, :name, {:prompt => "Select a City"}, {:id => 'cities_select', multiple: true}) %>
It works fine.
I just want to understand the theory behind why one works and the other doesn't?
I think what's tripping you up, primarily, is the concepts you have of what's going on here.
Nothing is “binding” anything to anything by calling a method on a form helper object. There are form helper methods, like collection_select, that can be used to build HTML elements. There are form builders that have methods, like collection_select that build HTML form elements for a form tied to an object.
The issue you're having here is that the FormOptionsHelper#collection_select method and the FormBuilder#collection_select method are not the same method and do not accept the same arguments:
FormOptionsHelper#collection_select vs FormBuilder#collection_select
Pay particular attention to the arguments provided. It's also worth noticing that FormBuilder essentially delegates this work to the template (i.e. FormOptionsHelper) and adjusts the arguments as needed.

How to use :selected with grouped_collection_select

Is it possible to somehow use the :selected option that you'd use on a normal select view helper with the grouped_collection_select function? I'd like to set the value that gets pre-selected in my list. I've tried passing in :selected as an option with no luck!
Here's some code snippts of my tests:
grouped_collection_select 'user[subscription_attributes]', :subscription_plan_id, Trade.order(:name).all, :subscription_plans, :name, :id, :display_name, { :include_blank => true, :selected => 5 }
grouped_collection_select 'user[subscription_attributes]', :subscription_plan_id, Trade.order(:name).all, :subscription_plans, :name, :id, :display_name, :include_blank => true, :selected => 5
Neither version works. No selected is set. I'm using this to set a value for a nested model. I'm using the railscasts dynamic select list methods: http://railscasts.com/episodes/88-dynamic-select-menus-revised
I couldn't get formtastic to play nicely with the group selects so I had to do it by hand but I don't keep this value selected when a user fails validations. I'd like to keep this set when they fix validation errors.
I just ran across the same problem and solved it using the option_groups_from_collection_for_select helper and the select helper documented at: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html.
The first step is to create the grouped options. Taking your example, it should look like:
<% options = option_groups_from_collection_for_select(Trade.order(:name).all,
:subscription_plans, :name, :id, :display_name, 5) %>
Then I created the select object like:
<%= select('user[subscription_attributes]', :subscription_plan_id, options,
include_blank: true) %>
You could write it all out in one line, I just broke out the options into a separate variable to illustrate the two different methods.
Maybe too late, but the API documentation of grouped_collection_select states:
'The value returned from calling method on the instance object will be selected.'
So, you don't even have to specify a :selected option, since Rails will automatically select based on the current value of your attribute.
If subscription_plan_id has value 5, then that's what will be selected.
If that's supposed to be a default value, then you can set it with an after_initialize in your model.
Actually you need to send in options include_blank for example
<%= grouped_collection_select :id, model.all, options = {:include_blank => 'Selecione'}%>

Resources