Как нацелиться на отдельный новый элемент ввода в виде вложенного кокона - PullRequest
0 голосов
/ 27 сентября 2019

У меня возникла проблема с отображением набора параметров во вложенном поле.Коллекция зависит от заполненного значения в существующей форме.

Я считаю, что исправление будет заключаться в нацеливании на новое поле ввода с уникальным идентификатором для каждого нового вложенного поля ввода, но, пожалуйста, исправьте меня, если я ошибаюсь.

Контекст

При рендеринге формы заказа программа автоматически создает первое поле '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>');
      }
    }
  });
});
...