问题
Context A user can fill in an order form where a bike_type can be chosen and consequently the options belonging to that bike_type.
Current situation Based on user input ('bike_type') in a simple_form column, I would like to include a checkbox with all potential options ('options) where multiple options can be selected. Currently, I am able to:
(Situation 1) Display all the options for the respective bike_type via Ajax in the view, but unfortunately these are not being sent in the params.
(Situation 2) Display all options for all bikes, these are inserted into the params and correctly saved, but this is not correct as users should only be able to select options that belong to the bike_type.
HTML I think the bug is in the JS inserting the options in the checkbox list. I tried mimicking the html shown below, but I cannot seem to get it right. Therefore, please find some printscreens of the HTML differences below.
Incorrect html that is not inserted properly in the params below:
Correct html that is inserted (As it renders all options incl. different bike options in the view) below:
form
<%= 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
<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
回答1:
If the problem is only in rendering the proper input fields, then you may follow this approach:
This is a code snippet to render select options for events based on the user's age group..quite similar to yours:
.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 );
}
});
来源:https://stackoverflow.com/questions/58165753/how-to-add-dynamic-checkboxes-based-on-form-input