javascript - 以 simple_form 呈现动态选择列表

标签 javascript jquery ruby-on-rails ajax

我在 JS/Ajax 方面相对较新,并且我注意到如何根据先前以相同(简单_)形式插入的数据来呈现动态选项。

背景:通过应用程序,自行车链式店(“链式店”)可以出租

  • 名称为“bike 1”或“yellow bike”(“bikes”)的自行车,
  • 选择自行车类型,例如山地自行车、城市自行车等 ('bike_types) 和
  • 自行车选项,例如 Helm 等('bike_options')
  • 这取决于各个自行车商店('bike_stores')
  • 此次租赁的自行车和选项都将记录在订单(“订单”)中
  • 订单和自行车之间的关系是多对多的,因此 - 我创建了一个表来桥接此关系('order_bikes')

悬而未决的问题:我可以通过JS获取bike_type_id。如何使用 bike_type 的这个 id 以相同的形式显示属于该 bike_type 的自行车?

如前所述,不幸的是我不太熟悉 JS/Ajax 在 Rails 应用程序中的使用,因此如果可以在应编写建议代码的位置添加文件路径(例如应用程序),我将非常感激和帮助/javascript/components/order.js 等)

最终说明:

  • 在租赁过程之前,链式店所有者首先创建他/她的 (i) bike_stores、(ii) bike_types、(iii) bikes 和 (iv) bike_options,这部分应用程序正在运行。因此,他/她只需从之前创建的现有库存中选择 bike_types/bikes/options 即可。
  • 我通过省略 bike_options 来限制问题的范围,这主要是为了提供一些上下文以便理解数据库架构的构建。

型号

class Order < ApplicationRecord
  belongs_to :bike_store
  has_many :bike_types, through: :bike_store
  has_many :order_bikes, inverse_of: :order, dependent: :destroy
  accepts_nested_attributes_for :order_bikes, allow_destroy: true
end


class OrderBike < ApplicationRecord
  belongs_to :bike
  belongs_to :order
  accepts_nested_attributes_for :bike
end


class Bike < ApplicationRecord
  belongs_to :bike_type
  validates :name, presence: true
  has_many :order_bikes
  has_many :orders, through: :order_bikes
end


class BikeType < ApplicationRecord
  belongs_to :bike_store
  has_many :bikes, dependent: :destroy
  accepts_nested_attributes_for :bikes, allow_destroy: true
  has_many :bike_options, dependent: :destroy
  accepts_nested_attributes_for :bike_options, allow_destroy: true
  validates :name, :bike_count, presence: true
end

class BikeStore < ApplicationRecord
  has_many :bike_types, dependent: :destroy
  has_many :orders, dependent: :destroy
end

订单 Controller

class OrdersController < ApplicationController

  def new
    @bike_store = BikeStore.find(params[:bike_store_id])
    @order = Order.new
    @order.order_bikes.build
    @bike_type_list = @bike_store.bike_types
  end

  def create
    @order = Order.new(order_params)
    @bike_store = BikeStore.find(params[:bike_store_id])
    @order.bike_store = @bike_store
    @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_types_attributes: [:id, :name]]])
  end
end

View /订单/new.html.erb

<%= simple_form_for [@bike_store, @order] do |f|%>

  <%= f.simple_fields_for :order_bikes do |order_bike| %>
    <%= order_bike.input :bike_quantity %>

      <%= order_bike.simple_fields_for :bikes do |bike| %>

        #fist a bike_type will be classified, see below
        <%= bike.select :bike_type_id, options_for_select(@bike_type_list.collect{|type|[type.name, type.id]}) %>
      <% end %>

      #then a dropdown of bikes belonging to above chose bike_type need to be displayed below.
      <%= order_bike.association :bike, collection [bike_type.bikes] %>
  <% end %>

  <%= f.input :arrival %>
  <%= f.input :departure %>
  <%= f.submit %>
<% end %>

<script>
  // return id bike_type
  function selectType(){
  const bikeType = document.getElementById("order_order_bikes_attributes_0_bikes_bike_type_id").value;
  }
</script>

最佳答案

哇,弄清楚这个问题很痛苦/花了一些时间......对于看到这个的人,我找到了一个有效的答案,希望它可以节省你一些时间。

我很确定这不是最优雅的解决方案,所以请随意优化。我是用Ajax做的,请找到下面的解决方案:

在 View 中

<%= simple_form_for [@bike_store, @order] do |f|%>

  <%= f.simple_fields_for :order_bikes do |order_bike| %>
    <%= order_bike.input :bike_quantity %>

      <%= order_bike.simple_fields_for :bikes do |bike| %>

        #fist a bike_type will be classified, see below
        <%= bike.select :bike_type_id, options_for_select(@bike_type_list.collect{|type|[type.name, type.id]}) %>
      <% end %>

      #then a dropdown of bikes belonging to above chose bike_type need to be displayed below.
      <%= order_bike.association :bike, collection [bike_type.bikes] %>
  <% end %>

  <%= f.input :arrival %>
  <%= f.input :departure %>
  <%= f.submit %>
<% end %>

<script>

$(document).on("change", "#order_order_bikes_attributes_0_bikes_bike_type_id", 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);
      var bikes = response["bikes"];
      $("#order_order_bikes_attributes_0_bikes_bike_type_id").empty();

      $("#order_order_bikes_attributes_0_bike_id").append('<option>Select bike</option>');
      for(var i=0; i< bikes.length; i++){
        $("#order_order_bikes_attributes_0_bike_id").append('<option value="' + bikes[i]["id"] + '">' + bikes[i]["name"] + '</option>');
      }
    }
  });
});
</script>

订单 Controller

  def new
    @bike_store = BikeStore.find(params[:bike_store_id])
    @order = Order.new
    @order.order_bikes.build
    @bike_type_list = @bike_store.bike_types

    if params[:bike_type].present?
      @bikess = BikeType.find(params[:bike_type]).bikes
    end
    if request.xhr?
      respond_to do |format|
        format.json {
        render json: {bikes: @bikes}
      }
    end
  end
end
  end

关于javascript - 以 simple_form 呈现动态选择列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58105368/

相关文章:

mysql - 将数据从 excel 表存储到 ror 中的 db

javascript - jQuery 获取 HTML 内容 INSIDE div

用于迭代函数定义的 JavaScript 闭包

javascript - 将日期与 mm/dd/yyyy 进行比较会得到相反的结果

javascript - 如何在 Bootstrap 中加载页面时隐藏侧边栏?

jquery - 使用 Jquery 提交时,返回 False 对我来说永远不起作用?我究竟做错了什么?

javascript - 在脚本标签中使用 Ruby 变量

javascript - map 位置详细信息以及照片和其他详细信息

javascript - 等待 ajax 函数完成,直到使用间隔再次重新加载该函数

ruby-on-rails - database.yml 文件中的 Postgres 数据库用户名