Front end validation for rails select field - ruby-on-rails

Select Field:
<%= f.select :study_material_type, StudyMaterial::TYPES.map{|v| [v,v]}, selected: f.object.try(:study_material_type) , required: true,include_blank: "Please select a Study Material"%>
I want to validate the presence of :study_material_type select field. How can I do this?

Select takes in 5+ options while required validation is a html_option
i.e
select(object, method, choices = nil, options = {}, html_options = {}, &block)
put the html arguments in { } as a html_options. This should work for you.
<%= f.select :study_material_type, StudyMaterial::TYPES.map{|v| [v,v]}, {include_blank: "Please select a Study Material"}, {required: true } %>
Here is a good material for you to understand better.

Related

Unpermitted params customer_ids

Super simple, dumb thing, which I can't figure out for more, than an hour now:
def user_params
params.require(:user).permit(customer_ids: []) # pg array column
end
My form:
= f.select :customer_ids,
options_from_collection_for_select(customers, 'id', 'name', user.customer_ids),
{ include_blank: 'Select customer', multiple: true, size: 15 },
class: 'form-control'
And while updating user I'm getting
Unpermitted parameter: customer_ids
How the heck in the world is that possible?
Parameters: {"utf8"=>"✓", "authenticity_token"=>"oCkUEi2pNajM0ydHUH2w6iYIq5eKjfCY5ig9U2qDTXxMqECCgQ2Dn9YtqkMqXlTmLl5q/OO8x23o/P50SnmgUg==", "user"=>{"customer_ids"=>"84"}, "commit"=>"Assign selected customer to user", "id"=>"2"}
Your form isn't sending in the customer_ids parameters as an array.
"user"=>{"customer_ids"=>"84"}
This is why. It should be (notice the square brackets):
"user"=>{"customer_ids"=>"[84]"}
If you declare the param as an array, it should be posted as an array. This is likely an issue in your form.
Usually, I would use checkboxes for something like this, but this depends on your user interface. Here's something similar I have done in the past.
= f.collection_check_boxes :customers, customers, :id, :name do |cb|
= cb.label
span.pull-right = cb.check_box
Look at the collection form helpers in Rails. A multiselect should work, but I have not used one this way.
Try changing your select tag like this
= f.select(:customer_ids, customers.collect { |c| [ c.name, c.id ] },
{ prompt: "Select Customer"},
{ multiple: true, size: 5, class: 'form-control' })

Rails grouped_options_for_select not populating edit action

I have a form with two fields where the second depends on what was selected in the first dropdown, if I select 'Asia' in the first, then 'Japan' and 'China' appear as options in the second dropdown.
.field
= f.label :country
= f.select :country, ['Asia', 'Europe'], :prompt => 'Select One'
.field
= f.label :category
= f.select :category,grouped_options_for_select(MyModel::CATEGORIES, nil, "Please Select")
The CATEGORIES variable looks like;
CATEGORIES = {
'Asia'=> [ 'Japan','China'],
'Europe'=> [ 'Ireland', 'France']
}
This works but when I go the edit page the second dropdown is not pre-populated with the stored value, how do I do this?
#dax is right but you need to explicitly set the selected value and not just the attribute. From the api
selected_key - A value equal to the value attribute for one of the tags, which will have the selected attribute set. Note: It is possible for this value to match multiple options as you might have the same option in multiple groups. Each will then get selected="selected".
Your code should be
= f.select :category, grouped_options_for_select(MyModel::CATEGORIES, f.object.category)
EDIT
The last argument passed to grouped_options_for_select should be passed to select instead and should be the value of either the prompt or include_blank option.
= f.select :category,
grouped_options_for_select(MyModel::CATEGORIES, f.object.category),
{ prompt: 'Please select' }, # here goes the select tag options
{ class: 'my-class' } # here goes the html options
you've set the selected key to nil -
MyModel::CATEGORIES, # nil #, "Please Select"
Try changing your code to this:
= f.select :category,grouped_options_for_select(MyModel::CATEGORIES, :country, "Please Select")

Validates the presence of an option

I have a form that I want to validate if an option has been selected.
I do not want to accept the default starting option, "Please Select a Product"
I using this now and get a uninitialized contant error. I believe I am writing the syntax wrong.
Controller:
validates :product_name, :presence => { :unless => (product_name = "Please Select a Product")}
View:
<span class="span5 pagination-right">
<%= f.label "Product" %>
<%= f.select :product_name, options_for_select([ ["Please Select a Product"] ]) %>
</span>
How am I supposed to have the option written?
Thank you
The product_name is changed like this:
<script>
$(document).ready(function() {
$('#ticket_product_name').html("<option>Please Select a Product</option>");
$('#ticket_firmware_version_string').html("<option>Please Select a Firmware</option>");
$('#category').change(function(){
$('#ticket_product_name').html("<option>Please Select a Product</option>");
$('#ticket_firmware_version_string').html("<option>Please Select a Firmware</option>");
if ($('#category').val() == "blah")
{
$('#ticket_product_name').append("<option>blah</option>");
$('#ticket_product_name').append("<option>blah</option>");
}
else if ($('#category').val() == "another category")
{
$('#ticket_product_name').append("<option>blah product</option>");
}
until end of options, end script.
I think what you are looking for is a placeholder for this select. In this case, I used a disabled option:
<% options = options_for_select(["Select an option", ["Product #1",1], ["Product #2",2]], disabled: "Select an option") %>
<%= f.select :product_name, options %>
You should use include_blank from the select helper, like this:
<%= f.select :product_name, options_for_select([["opt1",1],["opt2",2]]), include_blank: true %>
and then, on model
validates :product_name, :presence => true
#MrYoshiji commented something truthful in my answer - if you are not allowing it to be blank, the easy way is simply not add a blank option in the select
I would recommend to use the :prompt option for your select helper (the documentation on this isn't quite straight forwward, but it's ok in this version of the same thing: http://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag). This allows you to define a helper string of text to encourage the user to select an option, but will submit a nil value back when the form is submitted.
<%= f.select :product_name, PRODUCT_NAME_OPTIONS, prompt: 'Select an option' %>
The next thing I'd recommend is... instead of validating presence of on the model, do a validates_inclusion_of. This way you can define the set of options in the model and then use that same set of options in the select helper, above, as well is in your validation. This way you know the form wasn't manipulated to include a different option and it actually keeps things a bit DRYer.
Product
PRODUCT_NAME_OPTIONS = {'opt 1' => 'opt1', 'opt 2' => 'opt2'}
validates_inclusion_of :product_name, :in => PRODUCT_NAME_OPTIONS.values, :message => 'choose from the available options'
Instead of making this too complicated, I just added a length validation since the default is much longer then the product names. Simple is best, however there should be a string validator option.
validates :product_name, presence: true, length: {
maximum: 21,
too_long: ": Must select a product"
}

How to set a default attribute on Rails select form helper?

I am trying to override Rails' select method with a custom form helper, so that all select boxes get a disabled attribute by default:
class LabelFormBuilder < ActionView::Helpers::FormBuilder
def select(method, choices, options = {}, html_options = {})
html_options.reverse_merge! :disabled => true
super(method, choices, options = {}, html_options = {})
end
end
The problem is that the code is not working and that it doesn't change anything in the way the select boxes are rendered. It doesn't throw an error either.
This would be the view code that I use to call the function:
<%= f.select(:person_id, current_user.person_names, {:prompt => 'Please select...'}) %>
What am I missing here?
Thanks for any help...
Try it maybe with
<%= f.select(:person_id, current_user.person_names, {}, {:prompt => 'Please select...'}) %>

How to preselect a country with the `country_select` helper?

How is it possible to preselect a country in the dropdown list generated by the country_select or localized_country_select helpers? The following code nicely creates a list of countries, but the :selected => :ch part does not have the expected effect of preselecting Switzerland (ch):
<%= localized_country_select(:user, :country, [], :selected => :ch) %>
Update: the following seems to be a better choice for achieving this.
localized_country_select_tag(name, selected_value = nil, priority_countries = nil, html_options = {})

Resources