У меня возникла проблема с отображением набора параметров во вложенном поле.Коллекция зависит от заполненного значения в существующей форме.
Я считаю, что исправление будет заключаться в нацеливании на новое поле ввода с уникальным идентификатором для каждого нового вложенного поля ввода, но, пожалуйста, исправьте меня, если я ошибаюсь.
Контекст
При рендеринге формы заказа программа автоматически создает первое поле 'order_options' (таблица, связывающая ордера и опции, учитывая, что их много-много).Форма предоставляет поле для выбора bike_type, в котором есть определенные опции, связанные с типом велосипеда.Основываясь на выбранном типе bike_type, форма предоставляет список выбора с опциями.Эта часть моей программы отображается правильно.
Моя проблема
При добавлении другой опции через link_to_add_association кокона, пользователь должен снова увидеть тот же список выбора с опциями, что и у bike_typeостается такой же.Кроме того, ранее заполненный вариант должен остаться (например, не очищаться снова).Однако в моей текущей программе
- ранее заполненный код удаляется (потому что мне нужно очистить список выбора в случае изменения bike_type)
- вновь добавленная вложенная форма не содержитлюбые варианты (я предполагаю, но не уверен, потому что он использует только параметры bike_type для первого поля формы)
форма
<%= simple_form_for [@bike_store, @order] do |f|%>
<%= f.simple_fields_for :order_bikes do |order_bike| %>
<%= order_bike.simple_fields_for :bikes do |bike| %>
<%= bike.input :bike_type_id, collection: @bike_type_list, input_html:{
value: @bike_type_list.object_id,
id: "bike_type"
}%>
<% end %>
<%= f.input :arrival %>
<%= f.input :departure %>
<%= order_bike.association :bike, collection: @bikes, input_html:{
value: @bikes.object_id,
id: "dynamic-bikes"
} %>
<% end %>
<!-- test -->
<%= f.simple_fields_for :order_options do |order_option| %>
<%= render 'order_option_fields', f: order_option %>
<% end %>
<div>
<%= link_to_add_association 'add option', f, :order_options, id:'add-option' %>
</div>
<!-- test -->
<%= f.submit %>
<% end %>
JS / AJAX
<script >
// dynamic bikes
$(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);
// dynamic bikes
var bikes = response["bikes"];
$("#dynamic-bikes").empty();
$("#dynamic-bikes").append('<option>Select bike</option>');
for(var i=0; i< bikes.length; i++){
$("#dynamic-bikes").append('<option value="' + bikes[i]["id"] + '">' + bikes[i]["name"] + '</option>');
}
// dynamic options after 1st build
var options = response["options"];
$("#dynamic-options").empty();
$("#dynamic-options").append('<option></option>');
for(var i=0; i< options.length; i++){
$("#dynamic-options").append('<option value="' + options[i]["id"] + '">' + options[i]["name"] + '</option>');
}
}
});
});
// test dynamic options for nested form
$(document).on('click', '#add-option', function(){
console.log('test')
var bike_type = $('#bike_type').val();
console.log(bike_type)
$.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);
var options = response["options"];
// $("#dynamic-options").empty();
$("#dynamic-options").append('<option></option>');
for(var i=0; i< options.length; i++){
$("#dynamic-options").append('<option value="' + options[i]["id"] + '">' + options[i]["name"] + '</option>');
}
}
});
});
</script>
вложенная форма
<div class="nested-fields">
<%= f.association :option, collection: @options, input_html:{
value: @options.object_id,
id: "dynamic-options",
} %>
</div>
контроллер заказов
class OrdersController < ApplicationController
# skip_before_action :authenticate_user!
def new
@bike_store = Bike_store.find(params[:bike_store_id])
@order = Order.new
@order.order_bikes.build
@order.order_options.build
@bike_type_list = @bike_store.bike_types
@bikes = []
@options = []
# Display bikes/options for type
if params[:bike_type].present?
@bikes = BikeType.find(params[:bike_type]).bikes
@options = BikeType.find(params[:bike_type]).options
end
if request.xhr?
respond_to do |format|
format.json {
render json: {bikes: @bikes, options: @options}
}
end
end
authorize @order
end
def create
@order = Order.new(order_params)
@bike_store = Bike_store.find(params[:bike_store_id])
@order.bike_store = @bike_store
authorize @order
@order.save
redirect_to root_path
end
private
def order_params
params.require(:order).permit(:arrival, :departure,
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
end
Обратный вызов, который я также пробовал:
// dynamic options for nest form
$(document).on('cocoon:after-insert', function(){
// $(document).on('cocoon:after-insert', function(){
console.log('test')
var bike_type = $('#bike_type').val();
console.log(bike_type)
$.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);
var options = response["options"];
// $("#dynamic-options").empty();
$("#dynamic-options").append('<option></option>');
for(var i=0; i< options.length; i++){
$("#dynamic-options").append('<option value="' + options[i]["id"] + '">' + options[i]["name"] + '</option>');
}
}
});
});