将值依赖的数据属性添加到simple_form复选框集合

yoz*_*yoz 6 forms ruby-on-rails custom-data-attribute simple-form

我正在为单个集合生成一个复选框列表,如下所示:

= f.input :parts, as:check_boxes, collection: @parts_list
Run Code Online (Sandbox Code Playgroud)

我希望集合中的一些复选框消失/重新出现,具体取决于表单中较高的选择窗口小部件的值.(例如,从机器人选择中选择"跟踪器机器人"意味着"腿"部件复选框消失,并出现"轮子"复选框等)

我想要做的是将计算数据属性附加到每个单独的零件复选框,其属性值列出可以使用该零件的机器人; 然后一些JS会做隐藏/显示复选框的工作.但是,我不知道如何使用simple_form生成这些数据属性.

我通常会创建一个自定义的"部件"输入,但是在制作自定义集合输入时似乎存在问题; 它在form_builder.rb中查找一个命名方法(collection_parts),它不会存在,如果我尝试扩展FormBuilder,它会向我发送一个主要的兔子洞.

我可以写一些JS来将数据加载到生成的HTML中,但是我必须根据我的Rails数据生成自定义JS,这感觉就像是错误的方法.

Har*_*tty 9

假设表单是用于Order模型的,并且您正在parts根据被调用字段的值更改集合region.

更新表单视图.指定表单,region字段和parts字段的ID .

= simple_form_for(@order, :html => { :id => "order-form"}) do |f|
  = f.input :region, :wrapper_html => { :id => "order-form-region",                      |
      "data-parts-url" => parts_orders_path(:id => @order.id, :region => @order.region)} |

  = f.input :parts, as: check_boxes, collection: @parts_list,                            |
      :wrapper_html => { id' => 'parts-check-box-list'}                                  |
Run Code Online (Sandbox Code Playgroud)

添加一个名为新动作partsroute.rb的文件.

resources :orders do
  collection do
    get :parts
  end
end
Run Code Online (Sandbox Code Playgroud)

将新操作添加到控制器

class OrdersController < ApplicationController

  # expects id and region as parameters
  def parts
    @order =  params[:id].present? ? Order.find(params[:id]) : Order.new
    @parts_list = Part.where(:region => params[:region])
  end
end
Run Code Online (Sandbox Code Playgroud)

添加帮助器

def parts_collection(order, parts_list)
  "".tap do |pc| 
    # to generate the markup for collection we need a dummy form
    simple_form_for(order) do |f| 
      pc << f.input(:parts, as: check_boxes, collection: parts_list, 
        :wrapper_html => {:id => 'parts-check-box-list'})
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

为动作添加js视图(orders/parts.js.erb)

$('#parts-check-box-list').replaceWith('<%= j(parts_collection(@order, @parts_list)) %>');
Run Code Online (Sandbox Code Playgroud)

region您的字段注册数据更改事件处理程序application.js

$(document).ready(function() {
  $('#order-form').on("change", "#order-form-region", function () {
    // Access the data-parts-url set in the region field to submit JS request
    $.getScript($(this).attr('data-parts-url'));
  });
});
Run Code Online (Sandbox Code Playgroud)


Shu*_*hen 7

我想你可以这样做:

= f.input :parts do
  = f.collection_check_boxes :parts, @parts_list, :id, :to_s, item_wrapper_tag: :label, item_wrapper_class: :checkbox do |b|
    - b.check_box(data: { YOUR DATA ATTRIBUTES HERE }) + b.text
Run Code Online (Sandbox Code Playgroud)