使用 ajax 操作预填充 Rails collection_select(Rails 5 和 jQuery)
Pre-populate Rails collection_select with ajax action (Rails 5 and jQuery)
我正在尝试构建一个发票应用程序,其中每个 发票 都有一个行发票 项目(例如产品名称、成本、金额)。
我想当我 select productname 来自发票项目的 下拉列表 时, ajax 被触发以使用 params[:product_id] 查询 产品数据库 table,获取产品cost 来自数据库,因此立即填充项目成本。
即当用户 select 产品名称时,该产品成本会在不输入的情况下立即显示。
在下面的附图中,我的 query_string returns JSON 符合预期,除了我不知道如何 pass/display 返回的 数据 到 cost_field。
如果我做 html(product.cost),我 get/return [对象,对象] 在#notification 和 undefind cost 也在 rails 控制台。
我的问题是,我该如何做这样的事情? $("#notification").html(product.cost)
型号:
class Invoice < ApplicationRecord
has_many :items, dependent: :destroy
accepts_nested_attributes_for :items, allow_destroy: true, reject_if: proc {|a| a[:product_id].blank?}
has_many :products, through: :item
end
class Item < ApplicationRecord
belongs_to :invoice, optional: true
belongs_to :item, optional: true
end
class Product < ApplicationRecord
has_many :items
end
控制器
class InvoicesController < ApplicationController
before_action :set_invoice, only: [:show, :edit, :update, :destroy]
def index
@invoices = Invoice.all
end
def new
@invoice = Invoice.new
2.times { @invoice.items.build }
end
def pricedata
@product = Product.select(:id, :cost, :productname).where('products.id = ?', params[:product_id])
respond_to do |format|
format.html { render html: @product.id }
format.js #{ render js: @product}
format.json { render json: @product }
end
private
def invoice_params
params.require(:invoice).permit(:name, :amount, items_attributes: [:qty, :price, :id, :product_id, :_destroy])
end
表格
<p id="notification"></p> # notice to keep my eyes on return obj
...
<%= f.fields_for :items do |item| %>
<span><%= item.label :product_id %> </span>
<span> // # collection begins here
<%= item.collection_select(:product_id, Product.all, :id, :productname,
{prompt: "Select a product"},
{class: 'selectors' multiple: true })
%>
</span> // # collection ends here
<span><%= item.label :qty %> </span>
<span><%= item.number_field :qty %> </span>
<span><%= item.label :price, class: "p_price" %> </span>
<span><%= item.number_field :price %> </span>
<span><%= item.check_box :_destroy %> Remove item</span>
...
JAVASCRIPT / 咖啡
$(document).ready ->
$('.selectors').on "change", ->
selectOptions= $('.selectors option:selected')
product_id = $(this).val()
if selectOptions.length > 0
selectOptions.each ->
$.ajax({
url: '/invoices/:id/pricedata?product_id=' + product_id,
type: 'GET',
dataType: 'html',
contentType: 'application/html'
success: (product)->
$("#noticification").html(product)
console.log(product)
})
你真的把它复杂化了。要获取产品的详细信息,您应该向 ProductsController
.
上的简单显示操作发送 ajax 请求
class ProductsController < ApplicationController
# GET /products/:id
def show
@product = Product.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @product }
end
end
end
此外,您不应在这种情况下使用倍数 select,因为这会使数量和价格不明确。而是为每个项目行创建一个字段集或 div。
fields_for 助手可用于为每个项目提供特定范围:
<%= form_for(@invoice) do %>
# ...
<%= fields_for(:items) do |item| %>
<!-- group each item in an element so you can find the associated inputs -->
<div class="item">
<!-- use a div to group inputs ands labels instead! -->
<span><%= item.label :product_id %> </span>
<span><%= item.collection_select(:product_id, Product.all, :id, :productname,
{prompt: "Select a product"},
{class: 'selectors' multiple: true }) %>
</span> // # collection ends here
<span><%= item.label :qty %> </span>
<span><%= item.number_field :qty %> </span>
<span><%= item.label :price, class: "p_price" %> </span>
<span><%= item.number_field :price %> </span>
<span><%= item.check_box :_destroy %> Remove item</span>
</div>
<% end %>
# ...
<% end %>
我正在尝试构建一个发票应用程序,其中每个 发票 都有一个行发票 项目(例如产品名称、成本、金额)。
我想当我 select productname 来自发票项目的 下拉列表 时, ajax 被触发以使用 params[:product_id] 查询 产品数据库 table,获取产品cost 来自数据库,因此立即填充项目成本。
即当用户 select 产品名称时,该产品成本会在不输入的情况下立即显示。
在下面的附图中,我的 query_string returns JSON 符合预期,除了我不知道如何 pass/display 返回的 数据 到 cost_field。
如果我做 html(product.cost),我 get/return [对象,对象] 在#notification 和 undefind cost 也在 rails 控制台。
我的问题是,我该如何做这样的事情? $("#notification").html(product.cost)
型号:
class Invoice < ApplicationRecord
has_many :items, dependent: :destroy
accepts_nested_attributes_for :items, allow_destroy: true, reject_if: proc {|a| a[:product_id].blank?}
has_many :products, through: :item
end
class Item < ApplicationRecord
belongs_to :invoice, optional: true
belongs_to :item, optional: true
end
class Product < ApplicationRecord
has_many :items
end
控制器
class InvoicesController < ApplicationController
before_action :set_invoice, only: [:show, :edit, :update, :destroy]
def index
@invoices = Invoice.all
end
def new
@invoice = Invoice.new
2.times { @invoice.items.build }
end
def pricedata
@product = Product.select(:id, :cost, :productname).where('products.id = ?', params[:product_id])
respond_to do |format|
format.html { render html: @product.id }
format.js #{ render js: @product}
format.json { render json: @product }
end
private
def invoice_params
params.require(:invoice).permit(:name, :amount, items_attributes: [:qty, :price, :id, :product_id, :_destroy])
end
表格
<p id="notification"></p> # notice to keep my eyes on return obj
...
<%= f.fields_for :items do |item| %>
<span><%= item.label :product_id %> </span>
<span> // # collection begins here
<%= item.collection_select(:product_id, Product.all, :id, :productname,
{prompt: "Select a product"},
{class: 'selectors' multiple: true })
%>
</span> // # collection ends here
<span><%= item.label :qty %> </span>
<span><%= item.number_field :qty %> </span>
<span><%= item.label :price, class: "p_price" %> </span>
<span><%= item.number_field :price %> </span>
<span><%= item.check_box :_destroy %> Remove item</span>
...
JAVASCRIPT / 咖啡
$(document).ready ->
$('.selectors').on "change", ->
selectOptions= $('.selectors option:selected')
product_id = $(this).val()
if selectOptions.length > 0
selectOptions.each ->
$.ajax({
url: '/invoices/:id/pricedata?product_id=' + product_id,
type: 'GET',
dataType: 'html',
contentType: 'application/html'
success: (product)->
$("#noticification").html(product)
console.log(product)
})
你真的把它复杂化了。要获取产品的详细信息,您应该向 ProductsController
.
class ProductsController < ApplicationController
# GET /products/:id
def show
@product = Product.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @product }
end
end
end
此外,您不应在这种情况下使用倍数 select,因为这会使数量和价格不明确。而是为每个项目行创建一个字段集或 div。 fields_for 助手可用于为每个项目提供特定范围:
<%= form_for(@invoice) do %>
# ...
<%= fields_for(:items) do |item| %>
<!-- group each item in an element so you can find the associated inputs -->
<div class="item">
<!-- use a div to group inputs ands labels instead! -->
<span><%= item.label :product_id %> </span>
<span><%= item.collection_select(:product_id, Product.all, :id, :productname,
{prompt: "Select a product"},
{class: 'selectors' multiple: true }) %>
</span> // # collection ends here
<span><%= item.label :qty %> </span>
<span><%= item.number_field :qty %> </span>
<span><%= item.label :price, class: "p_price" %> </span>
<span><%= item.number_field :price %> </span>
<span><%= item.check_box :_destroy %> Remove item</span>
</div>
<% end %>
# ...
<% end %>