Simple_form - how to create radio buttons with embedded text input fields

I use simple_form to render my forms and try to get the following behavior: I want the client to choose from 3 options. In each case, he delivers an extra field or two.
So I would 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 switches as follows, but I cannot add nested fields to 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 nested text fields?
As for the fields, I do not need to send them to different controllers (for one type of payment), it is normal if I send them to all one method and read the corresponding values ​​in accordance with the type of payment chosen by him.

Thanks! Zach

+4
source share
2 answers

OK .. I managed to somehow solve this, not sure if this is the best alternative, but I send it like this if someone needs it in the future, at least he has something to start with.

I went with creating a β€œregular” form using simpleform and then using jQuery to move the internal input fields (which were created regularly) next to the radio buttons.

Add jQuery support to your rails application:

  • add gem "jquery-rails" to your gemfile
  • bundle install
  • rails generate jquery:install

The form I used (regular simple form):

Pay attention to the class that is connected to the switches and identifiers attached to the input fields. I will use it later to move items.

 <%= 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 %> 

On the same page is 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 this is pretty understandable, it just looks for what will be the internal input fields (by id) and moves them to the appropriate place under the span , which simpleform creates for each switch.
I had to play a little with css to make it look the way I wanted (e.g. display:block ), but this is more or less.

Hope this helps .. Zach

+1
source

Simple_form collection_radio_buttons is most likely what you want. Its options parameter accepts a block that allows you to customize what will be displayed with each radio button. Take a look at the example in rdocs here .

Edited by:

Here is basically what you need to do in a relatively general way (not tested, but I am running something similar). Put your additional controls in a 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 does not need additional controls, along with :locals if your partial does not need it. There are also ways to simplify this code for your situation, but this example illustrates how to add more complex control structures for each switch button, if necessary.

+5
source

Source: https://habr.com/ru/post/1442094/


All Articles