如何根据表单输入添加动态复选框?
How to add dynamic checkboxes based on form input?
上下文
用户可以填写订单,其中可以选择 bike_type,因此属于 bike_type 的选项。
现状
根据 simple_form 列中的用户输入 ('bike_type'),我想包含一个包含所有可能选项 ('options) 的复选框,其中可以 selected 多个选项。目前,我能够:
(情况 1)在视图中通过 Ajax 显示相应 bike_type 的所有选项,但不幸的是,这些选项未在参数中发送。
(情况2)显示所有自行车的所有选项,这些是插入参数并正确保存, 但这是不正确的,因为用户应该只能 select 属于 bike_type.
的选项
HTML
我认为错误在于 JS 在复选框列表中插入选项。我试着模仿下面显示的 html,但我似乎无法做到正确。因此,请在下面找到一些 HTML 差异的打印屏幕。
不正确 html 未正确插入以下参数:
更正下面插入的 html(因为它在视图中呈现所有选项,包括不同的自行车选项):
形式
<%= simple_form_for [@bike_store, @order] do |f|%>
<%= f.collection_check_boxes :option_ids, Option.all, :id, :name do |b| %>
<div class="collection-check-box", id='test-options'>
<%= b.check_box %>
<%= b.label %>
</div>
<% end %>
<%= f.submit %>
<% end %>
脚本
<script >
$(document).on("change", "#bike_type", function(){
var bike_type = $(this).val();
$.ajax({
url: "/bike_stores/<%= @bike_store.id %>/orders/new",
method: "GET",
dataType: "json",
data: {bike_type: bike_type},
error: function (xhr, status, error) {
console.error('AJAX Error: ' + status + error);
},
success: function (response) {
console.log(response);
// test
$("#test-options").html("");
$("#test-options").append("");
for(var i=0; i< options.length; i++){
$("#test-options").append('<input type="checkbox" value="' + options[i]["id"] + '">' + options[i]["name"] + '');
}
// test
}
});
});
</script>
controller.rb
def new
@bike_store = BikeStore.find(params[:bike_store_id])
@order = Order.new
@orders = @bike_store.orders
@order.order_options.build
@options = []
# Display options for bike_type
if params[:bike_type].present?
@options = BikeType.find(params[:bike_type]).options
end
if request.xhr?
respond_to do |format|
format.json {
render json: {options: @options}
}
end
end
# test
authorize @order
end
def create
@order = Order.new(order_params)
@bike_store = BikeStore.find(params[:bike_store_id])
@order.bike_store = @bike_store
@order.order_contact = @order_contact
authorize @order
@order.save
redirect_to root_path
end
private
def set_order
@order = order.find(params[:id])
end
def order_params
params.require(:order).permit(:arrival, :departure, :order_contact_id,
order_bikes_attributes: [:id, :bike_id, :bike_quantity, :_destroy,
bikes_attributes: [:id,:name, :bike_type_id,
bike_types_attributes: [:id, :name]]],
order_options_attributes: [:id, :option_id, :option_quantity, :_destroy,
options_attributes: [:id, :name, :bike_type_id, :description,
bike_types_attributes:[:id, :name]]])
end
如果问题仅在于呈现正确的输入字段,那么您可以采用以下方法:
这是一个代码片段,用于根据用户的年龄段为事件呈现 select 选项。与您的非常相似:
.done(function (events){
var select = document.getElementById( "events-dropdown" );
while(select.length >0){
select.remove(select.length-1);
}
var option;
if( Object.keys( events ).length > 0){
events.forEach(function( event ) {
option = document.createElement( 'option' );
option.value = event.id;
option.textContent = event.title;
select.add( option );
});
}
// no events found for particular gender AND age group
else{
option = document.createElement( 'option' );
option.value ='';
option.textContent= 'Sorry! No events found for your age group';
option.disabled = true;
select.add( option );
}
});
上下文 用户可以填写订单,其中可以选择 bike_type,因此属于 bike_type 的选项。
现状 根据 simple_form 列中的用户输入 ('bike_type'),我想包含一个包含所有可能选项 ('options) 的复选框,其中可以 selected 多个选项。目前,我能够:
(情况 1)在视图中通过 Ajax 显示相应 bike_type 的所有选项,但不幸的是,这些选项未在参数中发送。
(情况2)显示所有自行车的所有选项,这些是插入参数并正确保存, 但这是不正确的,因为用户应该只能 select 属于 bike_type.
的选项
HTML 我认为错误在于 JS 在复选框列表中插入选项。我试着模仿下面显示的 html,但我似乎无法做到正确。因此,请在下面找到一些 HTML 差异的打印屏幕。
不正确 html 未正确插入以下参数:
更正下面插入的 html(因为它在视图中呈现所有选项,包括不同的自行车选项):
形式
<%= simple_form_for [@bike_store, @order] do |f|%>
<%= f.collection_check_boxes :option_ids, Option.all, :id, :name do |b| %>
<div class="collection-check-box", id='test-options'>
<%= b.check_box %>
<%= b.label %>
</div>
<% end %>
<%= f.submit %>
<% end %>
脚本
<script >
$(document).on("change", "#bike_type", function(){
var bike_type = $(this).val();
$.ajax({
url: "/bike_stores/<%= @bike_store.id %>/orders/new",
method: "GET",
dataType: "json",
data: {bike_type: bike_type},
error: function (xhr, status, error) {
console.error('AJAX Error: ' + status + error);
},
success: function (response) {
console.log(response);
// test
$("#test-options").html("");
$("#test-options").append("");
for(var i=0; i< options.length; i++){
$("#test-options").append('<input type="checkbox" value="' + options[i]["id"] + '">' + options[i]["name"] + '');
}
// test
}
});
});
</script>
controller.rb
def new
@bike_store = BikeStore.find(params[:bike_store_id])
@order = Order.new
@orders = @bike_store.orders
@order.order_options.build
@options = []
# Display options for bike_type
if params[:bike_type].present?
@options = BikeType.find(params[:bike_type]).options
end
if request.xhr?
respond_to do |format|
format.json {
render json: {options: @options}
}
end
end
# test
authorize @order
end
def create
@order = Order.new(order_params)
@bike_store = BikeStore.find(params[:bike_store_id])
@order.bike_store = @bike_store
@order.order_contact = @order_contact
authorize @order
@order.save
redirect_to root_path
end
private
def set_order
@order = order.find(params[:id])
end
def order_params
params.require(:order).permit(:arrival, :departure, :order_contact_id,
order_bikes_attributes: [:id, :bike_id, :bike_quantity, :_destroy,
bikes_attributes: [:id,:name, :bike_type_id,
bike_types_attributes: [:id, :name]]],
order_options_attributes: [:id, :option_id, :option_quantity, :_destroy,
options_attributes: [:id, :name, :bike_type_id, :description,
bike_types_attributes:[:id, :name]]])
end
如果问题仅在于呈现正确的输入字段,那么您可以采用以下方法:
这是一个代码片段,用于根据用户的年龄段为事件呈现 select 选项。与您的非常相似:
.done(function (events){
var select = document.getElementById( "events-dropdown" );
while(select.length >0){
select.remove(select.length-1);
}
var option;
if( Object.keys( events ).length > 0){
events.forEach(function( event ) {
option = document.createElement( 'option' );
option.value = event.id;
option.textContent = event.title;
select.add( option );
});
}
// no events found for particular gender AND age group
else{
option = document.createElement( 'option' );
option.value ='';
option.textContent= 'Sorry! No events found for your age group';
option.disabled = true;
select.add( option );
}
});