我正在为单个集合生成一个复选框列表,如下所示:
= f.input :parts, as:check_boxes, collection: @parts_list
我希望集合中的一些复选框消失/重新出现,具体取决于表单中较高的选择窗口小部件的值。 (例如,从机器人选择中选择“跟踪器机器人”意味着“腿”部件复选框消失,并出现“轮子”复选框等。)
我想要做的是将计算数据属性附加到每个单独的部件复选框,其属性值列出可以使用该部件的机器人;然后一些JS会做隐藏/显示复选框的工作。但是,我不知道如何使用simple_form生成这些数据属性。
我通常会创建一个自定义的“部件”输入,但是制作自定义集合输入时似乎存在问题;它在form_builder.rb中寻找一个命名方法(collection_parts),它不会存在,如果我尝试扩展FormBuilder,它会让我失去一个主要的兔子洞。
我可以编写一些JS来将数据加载到生成的HTML中,但是我必须根据我的Rails数据生成自定义JS,这感觉就像是错误的方法。
答案 0 :(得分: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'} |
在parts
文件中添加名为route.rb
的新操作。
resources :orders do
collection do
get :parts
end
end
将新操作添加到控制器
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
添加帮助
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
为操作添加js视图(orders/parts.js.erb
)
$('#parts-check-box-list').replaceWith('<%= j(parts_collection(@order, @parts_list)) %>');
在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'));
});
});
答案 1 :(得分: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
答案 2 :(得分:1)
这可能更简单。
<强>假设强>
@robots - an array containing the list of robots
@parts - a hash containing a list of parts for each robot
示例代码
# controller
@robots = %w[tracker nontracker]
@parts = { tracker: %w[wheels lcd resistor], nontracker: %w[lcd resistor] }
# view
= f.input :robots, as: :select, collection: @robots, input_html: { id: 'robot-select' }
#parts-list
:javascript
var parts = #{@parts.to_json};
$(document).ready(function() {
$('#robot-select').change(function() {
$('#parts-list').html('');
$(parts[$(this).val()]).each(function(index, text) {
$('#parts-list').append('<input type="checkbox" value=' + text + '>' + text + '</input>')
})
})
})
如果你克隆https://github.com/jvnill/simple_form_search_app并转到/robots
答案 3 :(得分:0)
SimpleForm中的一些输入选项接受为集合中的每个项调用的lambda:
f.input :role_ids, :collection => (1..10).to_a,
:label_method => :to_i, :value_method => :to_i,
:as => :check_boxes, :required=> true,
:disabled => ->(item){ item.even? }
但input_html
似乎不是其中之一。
解决方案可能是创建一个自定义SimpleForm集合输入,该输入应用数据属性本身。也许不那么灵活,但我认为这是现在唯一的方法。