simple_form - 如何使用嵌套输入文本框创建单选按钮

时间:2012-10-25 15:17:50

标签: ruby-on-rails-3 simple-form

我正在使用simple_form来呈现我的表单并尝试获得以下行为:我希望客户端从3个选项中进行选择。在每个选项中,他都会提供额外的一两个字段 所以我想要这样的事情:

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]

我可以按如下方式创建单选按钮,但不能在它们下面添加嵌套字段:

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

创建嵌套文本框的最佳方法是什么? 至于字段,我不需要将它们发送到不同的控制器(每个payment_type),如果我将它们全部发送到一个方法并根据他选择的支付类型读取相关值,那就没问题了。

谢谢!扎克

2 个答案:

答案 0 :(得分:5)

simple_form collection_radio_buttons很可能就是你想要的。它的options参数接受一个块,允许您自定义每个单选按钮呈现的内容。请查看rdocs here中的示例。

<强>编辑:

这基本上是你需要以相对通用的方式做的事情(尚未经过测试,但我正在运行类似的东西)。将其他控件放在每个单选按钮的部分控件中:

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

对于任何不需要其他控件的单选按钮,您可以省略:partial,如果您的部分不需要,则可以省略:locals。还有一些方法可以根据您的情况简化此代码,但此示例说明了如何在需要时为每个单选按钮添加更复杂的控制结构。

答案 1 :(得分:1)

好的..我已经设法以某种方式解决了这个问题,不确定它是最好的替代方案,但是我发布它,所以如果有人在将来需要它,至少他有一些东西可以开始。

我使用simpleform创建一个“常规”表单,然后使用JQuery移动单选按钮旁边的内部输入字段(定期创建)。

向您的rails应用添加JQuery支持:

  • gem "jquery-rails"添加到您的Gemfile
  • bundle install
  • rails generate jquery:install

我使用过的表单(常规simpleform):

请注意附加到单选按钮的类和附加到输入字段的ID。我稍后会用它来移动元素。

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

在同一页面中 - JQuery代码:

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

我认为这是非常不言自明的,它只是寻找内部输入字段(通过id)并将它们移动到span创建的simpleform下的适当位置每个单选按钮。
我不得不在css上玩一点,让它看起来像我想要的那样(例如display:block),但这或多或少都有。

希望它有所帮助..扎克