I have a form on my Ruby on Rails3 Application with a drop menu, this is my current code for the select option:
<%= f.select :phone_type, options_for_select(["Select One", "Cell", "Work", "Office", "Home", "Other"],:disabled => ["Select One"]), :class => 'genForm_dropBox' %>
From my understanding this should have "Select One" as the default option when someone opens the page, but if they don't select one of the other options an error displays when they hit submit.
This is true in Browsers like Safari and Chrome and IE7, but in Firefox and IE8 it shows "Cell" as the first option as Select One is disabled.
I'd like it to display "Select One" by default, but have it as an unusable option when they submit the form. Do I need to script this into the controller, or model? or do I have this coded in the form wrong?
for those looking to incorporate this feature, I've taken a new approach from the model end of things. Being that all fields are required to be filled out in order for the user to submit and not receive an error alert, I gave the "Submit One" option a default value of nothing. You can take a look at the following code to see how I did that.
<%= f.select :phone_type, options_for_select([["Select One", ""], "Cell", "Work", "Office", "Home", "Other"]), :class => 'genForm_dropBox' %>
This is a little cleaner:
<%= f.select :phone_type, [ 'Cell', 'Work', 'Office', 'Home', 'Other' ], :prompt => 'Select One' %>
The :prompt argument generates an option with an empty value.
In Rails 4, this approach works well for me.
<%= f.select :status, options_for_status, prompt: 'Select One' %>
Meanwhile I have defined the options in a helper to keep the clutter out of my view.
def options_for_status
[
['First Option','first_option'],
['Second Option','second_option']
]
end
Thanks to everyone who contributed an answer.
I needed similar code for a project I'm working on and I really liked the approach Ryan Burnette took.
This is what worked for me using Rails 4.1.0.
<%= f.select :season, options_for_seasons, :prompt => 'Select One' %>
Then I defined the options in my helper.
def options_for_seasons
['Spring', 'Summer', 'Autumn', 'Winter']
end
I went with:prompt => 'Select One'because I only wanted the "Select One" option to be listed in the edit form if a season had not been previously selected.
Adding the ["Select One", ""] causes the edit screen to alway display "Select One" rather than the stored value.
Rails 3.1 (2012 Aug 17)
could be <%= f.select :phone_type, options_for_select(["Cell", "Work", "Office", "Home", "Other"]), :prompt => "Select One", :class => 'genForm_dropBox' %>
Related
I have several static pages (About, Contact, Help) that are mapped in the routes.rb file like this:
get 'about', to: 'static#about', as: 'about'
get 'contact', to: 'static#contact', as: 'contact'
get 'help', to: 'static#help', as: 'help'
They are accessed in the layout partial, _footer.html.erb from this code:
<%= link_to "About", 'about_path', :class => '' %>
<%= link_to "Contact", 'contact_path', :class => '' %>
<%= link_to "Help", 'help_path', :class => '' %>
Everything works fine until I click on the footer links while I'm in a nested route like /users/current/edit (where I might edit my user-profile). For example, when I click on the ABOUT link at the bottom of the page, I would expect to be taken directly to the static#about route at about_path.
However, I am getting an ActionController exception (in development) and a page not found in production. It's trying to map to /users/current/about_path.
Any ideas on how to fix this?
See Thorin's answer. Remove the quotes around the path method call.
I have a input with a collection that should display as a drop down but instead it's displaying as a select box. How do i make it a drop down?
<%= f.input :fund, collection: funds, prompt: 'Select Fund', label: false, input_html: { multiple: true } %>
Add as: :select to your HTML and remove the multiple: true attribute. The select tag as a dropdown list does not support multiple selections without a JavaScript library like Select2.
<%= f.input :fund, as: :select, collection: funds, prompt: 'Select Fund', label: false %>
Here is an example of each type of select: http://jsfiddle.net/scarver2/s1nckfq5/
CITE: https://github.com/plataformatec/simple_form#usage
I answered a similar question here but you don't say what context (web framework) you're using.
You can use SimpleForm, Bootstrap and Bootstrap-Select. There is a Rails Gem for it. See my other answer for details.
In simple_form view, the submit button is like this:
<%= f.button :submit, 'Save' %>
We are trying to pass a params subaction when clicking the Save button. The params[:subaction] should have value of 'update' after clicking the button. Here is what we tried in view but it did not work:
<%= f.button :submit, 'Save', :subaction => 'update' %>
Is there a way to pass a value in params[:subaction] when clicking the Save button?
Use name and value option.
<%= f.button :submit , name: "subaction",value: "update"%>
In your controller you will get params[:subaction] with the value "update"
as dax points out,
<%= hidden_field_tag(:subaction, 'update') %>
<%= f.button :submit, 'Save' %>
This will provide the string value 'update' to the routed controller action via the hidden field. It can then be retrieved by the controller with
params[:subaction]
By specifying f.button :button, type: 'submit', we can use the name and value attributes as follows to submit using a single param. Notably, the value submitted (e.g., 'cake') may be different from the button text (e.g., 'The Best Cake').
_form.html.erb
<%= f.button :button, 'The Best Cake', type: 'submit', name: 'dessert_choice', value: 'cake' %>
<%= f.button :button, 'The Best Pie', type: 'submit', name: 'dessert_choice', value: 'pie' %>
Controller
def controller_action
dessert_choice = params[:dessert_choice] # 'cake' or 'pie'
end
This approach avoids the need for hidden inputs as #dax mentioned in the comment above.
Tested on Simple Form 3.3.1 with Rails 4.2.
I'm trying to use capybara+rspec and get this error: Unable to find field "Name" (Capybara::ElementNotFound)
Here is my form:
%h2 Sign up
= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'form-vertical' }) do |f|
= f.error_notification
= display_base_errors resource
= f.input :name, :autofocus => true
= f.button :submit, 'Sign up', :class => 'btn-primary'
= render "devise/shared/links"
Here is my user_steps.rb
When /^I sign up with valid user data$/ do
create_visitor
sign_up
end
def create_visitor
#visitor ||= { :name => "Test visitor"}
end
def sign_up
visit '/users/sign_up'
fill_in "Name", :with => #visitor[:name]
click_button "Sign up"
end
What's wrong????
I encountered this issue and realized that Capybara filtered out hidden fields--my element belonged to a non-active tab (hidden) in a multi-tab page. I just passed the :visible arg and set it to false, and voila! the element was found.
fill_in "content", with: 'foo bar', visible: false
or
find('#item_content', visible: false).set 'foo bar'
It looks like to me that you are looking for a field label Name, but your name field does not have a label, so you probably need to use the ID of the field or the name which is probably:
"#{resource_name}[name]"
Also, as #nmott said in his comment, you should try using save_and_open_page so that you can actually look at the page, However, be aware you need the launchy gem to use this method.
Furthermore, what you might discover is you're not even on the right page. My usual problem when testing pages OTHER than the sign up page is that I've been redirected and didn't know it. So after using visit, you should also use assert_template to make sure you're on the right page.
I have the same problem myself and I had to stop using fill_in all together.
What I did was replacing all occurrences of fill_in with the following code :
element = page.find("Name")
element.set(#visitor[:name])
I guess you can encapsulate this into a method in order to make your tests more smooth
Try to narrow down your scope from within the form as such
within("form#whatever_form_id") do
fill_in "Name", :with => #visitor[:name]
click_button "Sign up"
end
Ok guys I found it out having the same issue , its very simple :
In capybara or rspec they need you to but "Name" and in your form or label field you need to write "name" in small....there you go works for me.
For me it was the next line of the spec that was causing the problem not the fill_in "name" line. It didn't matter whether or not name was "Name" or "name".
The next click_button line for me had click_button "Wrong Name" which was the wrong name for the button, and this did not give the expected error of "can't click on button "Wrong Name" but instead gave can't find field "name".
A bit verbose for my first even post on stack overflow. Bottom line. Consider the line below the line given in the capybara error message.
I'm using simple_form to render my forms and trying to get the following behavior: I want the client to choose from 3 options. In every option he supplies additional field or two.
So I'd like something like this:
Please set your preferences:
o Pay me on a specific day - [input field to get the day]
o Pay me a specific amount of money - [input field for the amount]
o Pay me on a regular basis - [radio buttons to choose between weekly/monthly basis]
I can create the radio buttons as follows, but can't add nested fields under them:
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.input :payment_type, label: 'Please set your preferences:',
collection: [ ['Pay me on a specific day', :specific_day],
['Pay me a specific amount of money', :specific_money],
['Pay me on a regular basis', :regular_basis]
], as: :radio_buttons %>
<%= f.button :submit, 'Submit' %>
<% end %>
What would be the best way to create the nested text boxes?
As for the fields, I don't need to send them to different controllers (per payment_type), it's fine if I send them all to one method and read the relevant values according to the payment type he chose.
Thanks! Zach
The simple_form collection_radio_buttons is likely what you want. Its options parameter accepts a block which allows you to customize what is rendered with each radio button. Take a look at the example in rdocs here.
Edited:
Here is basically what you need to do in a relatively generic way (hasn't been tested, but I'm running something similar). Put your additional controls in the partial for each radio button:
<% radio_buttons = [
{ :text => 'Pay me on a specific day', :value => :specific_day, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me a specific amount of money', :value => :specific_money, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me on a regular basis', :value => :regular_basis, :partial => "<radio_partial_name>", :locals => { :any_locals => :your_partial_needs} },
] %>
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.label t("account.update_payment_method.title") %>
<%= f.collection_radio_buttons :payment_type, (collection.collect do |r| [r[:text], r[:value], r[:partial].nil? ? "" : r[:partial], r[:locals].nil? ? {} : r[:locals]] end), :second, :first do |builder| %>
<%= builder.label{builder.radio_button(:class => 'payment_method_options') + builder.text} %>
<% unless builder.object[2].blank? %>
<%= render :partial => builder.object[2], :locals => builder.object[3] %>
<% end %>
<% end %>
<%= f.button :submit, 'Submit' %>
<% end %>
You can omit :partial for any radio button that doesn't need additional controls, along with :locals if your partial doesn't need it. There are also ways to simplify this code for your situation, but this example illustrates how to add more complex control structures to each radio button if needed.
OK.. I've managed to solve this somehow, not sure that it's the best alternative, but I'm posting it so if someone needs it in the future he at least has something to start with.
I went with creating a "regular" form using simpleform and then using JQuery to move the inner input fields (which were created regularly) next to the radio buttons.
Add JQuery support to your rails app:
add gem "jquery-rails" to your Gemfile
bundle install
rails generate jquery:install
The form I've used (regular simpleform):
Notice the class that is attached to the radio buttons and the ids that are attached to the input fields. I'll use it later to move the elements.
<%= simple_form_for #client, url: 'update_payment_data' do |f| %>
<%= f.input :payment_type, label: t('account.update_payment_method.title'),
input_html: { class: 'payment_method_options' },
collection: [ [t('account.update_payment_method.sum_based.title'), :amount],
[t('account.update_payment_method.days_in_month_based.title'), :days_in_month],
[t('account.update_payment_method.optout.title'), :optput]
], as: :radio_buttons %>
<%= f.input :payment_amount, label: "Payment amount threshold",
input_html: { id: 'payment_amount_box' } %>
<%= f.input :payment_days_in_month, label: "Payment days in month",
input_html: { id: 'payment_days_in_month_box' } %>
<%= f.button :submit, t('account.update_payment_method.update') %>
<% end %>
In the same page - the JQuery code:
<script>
$(document).ready(function() {
var amount_box = $("#payment_amount_box");
var amount_box_parent = amount_box.parent();
amount_box.detach().appendTo($(".payment_method_options:eq(0)").parent());
amount_box_parent.remove();
var dim_box = $("#payment_days_in_month_box");
var dim_box_parent = dim_box.parent();
dim_box.detach().appendTo($(".payment_method_options:eq(2)").parent());
dim_box_parent.remove();
});
</script>
I think it's pretty self-explanatory, it just looks for what is going to be the inner input fields (by id) and moves them into the appropriate place under the span that simpleform creates for each radio button.
I had to play a little bit with the css to make it look how I wanted (display:block for example), but that's more or less it.
Hope it helps.. Zach