我创建了一个组合框,显示供应商,因此当选择供应商时将更新显示购买的div,显示购买后将以组合框形式进行嵌套,因此当我选择购买时将显示所选购买的金额。
问题在于,当我选择购买时,仅在第一行中有效,当我选择另一个组合框线时,显示所选择的第一个组合框的数量。
这是我的表格
suppliers
|id| |name|
1 Supplier A
2 Supplier B
shopping_documents
|id| |supplier_id|
1 1
2 2
shopping_products
|id| |shopping_document_id| |qty| |purchase_product_id|
1 1 1 1
2 1 1 2
purchase_products
|id| |name| |price_sale|
1 XP 1000
2 VISTA 2000
supplier_products
|id| |supplier_id| |amount| |purchase_product_id
1 1 1000 1
2 1 2000 1
3 2 3000 2
这是控制器/app/controller/purchase_product_controller.rb
class ShoppingDocumentController < ApplicationController
def new
@document = ShoppingDocument.new
@suppliers= Supplier.all
@products = SupplierProduct.find(:all,:conditions=>['supplier_id =? ',params[:suppliers] ],:group=>['purchase_product_id'])
@purchases= SupplierProduct.find(:all,:conditions=>['supplier_id =? ',params[:suppliers] ],:group=>['purchase_product_id'])
4.times do
shopping_product = @document.shopping_products.build
end
end
def create
@document = ShoppingDocument.new(params[:shopping_document])
if @document.save
flash[:notice] = "Successfully created document."
redirect_to :action=>"index"
else
render :action => 'new'
end
end
def update_supplier_div
@products = SupplierProduct.find(:all,:conditions=>['supplier_id =? ',params[:suppliers] ],:group=>['purchase_product_id'])
end
def update_product_div
@purchases= SupplierProduct.find(:all,:conditions=>['purchase_product_id =? ',params[:product] ],:group=>['purchase_product_id'])
end
end
这里的型号:
class ShoppingDocument < ActiveRecord::Base
has_many :shopping_products
accepts_nested_attributes_for :shopping_products ,:allow_destroy => true
end
class ShoppingProduct < ActiveRecord::Base
belongs_to :shopping_document
belongs_to :purchase_product
end
class PurchaseProduct < ActiveRecord::Base
has_many :shopping_products
has_many :supplier_products
end
class SupplierProduct < ActiveRecord::Base
belongs_to :purchase_product
end
以下是视图:/app/view/purchase_product/new.html.erb
<% form_for @document, :url => {:controller=>"shopping_document",:action=>'create'} do |f| %>
Name: <%= select_tag 'suppliers',"<option value=\"\">Select</option>"+options_for_select(@suppliers.collect {|t| [t.name,t.id]} ),:onchange=>remote_function(:url=>{:controller=>"shopping_document",:action=>"update_supplier_div"},:with=>"'suppliers=' + $('suppliers').value"),:name=>"shopping_document[supplier_id]" %>
<% f.fields_for :shopping_products do |builder| %>
<%= render "shopping_product_fields", :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add Product", f, :shopping_products %></p>
<p><%= f.submit "Submit" %></p>
<% end %>
以下是部分视图:/app/view/shopping_document/_shopping_product_fields.html.erb
<div class="fields">
<table>
<tr><td><%= f.text_field :qty , :size=>"9" %></td>
<td><%= select_tag "product","<option value=\"\">Select</option>"+options_for_select(@products.map { |c| [c.amount, c.id] }),:onchange=>remote_function(:url=>{:controller=>"shopping_document",:action=>"update_product_div"},:before=>"load_close('loading_condition')",:success=>"load_off('loading_condition')",:with=>"'product=' + $('product').value"),:class=>"product" %></td>
<td><%= f.select :purchase_product_id,"<option value=\"\">Select</option>"+options_for_select(@purchases.map { |c| [c.amount, c.id] }), {}, :class => "helping" %></td>
<td><%= link_to_remove_fields image_tag("standard/delete.png",:border=>0,:size=>"14x14"), f %></td>
</tr>
</table>
</div>
以下是rjs:/app/view/shopping_document/_update_supplier_div.rjs
page.select('.product').each do |select_tag|
page.replace_html select_tag, "<option value=\"\">Select</option>"+options_for_select(@products.map{|c| [c.purchase_product.name, c.purchase_product_id]})
end
以下是rjs:/app/view/shopping_document/_update_product_div.rjs
page.select('.helping').each do |select_tag|
page.replace_html select_tag,"<option value=\"\">Select</option>"+options_for_select(@purchases.map { |c| [c.amount, c.id] })
end
在第一行中不更新其他行只是更新。
请有人帮我解决这个问题吗?
答案 0 :(得分:1)
问题是,在更新产品时,您始终会向控制器操作发送相同的值。
从/app/view/shopping_document/_shopping_product_fields.html.erb partial看看这一行:
<%= select_tag "product",
"<option value=\"\">Select</option>"+
options_for_select(@products.map { |c| [c.amount, c.id] }),
:onchange=> remote_function(
:url= {:controller => "shopping_document", :action=>"update_product_div"},
:before => "load_close('loading_condition')",
:success => "load_off('loading_condition')",
:with => "'product=' + $('product').value"),
:class=>"product" %>
根据我的记忆,在prototype.js中,当你使用$("something")
时,它会在你的DOM树中找到id = 'someting'
您在$('product')
子句中使用with
的事实使它始终将第一行的select标记值发送到服务器,这是错误的。
您应该使用$(this)
来确保它是正在发送的current
选择的值。所以你需要替换:
:with => "'product=' + $('product').value"
有了这个:
:with => "'product=' + $(this).value"
另一个问题是,当您更改产品时,它会立即更改所有价格,并且您只希望该产品的价格发生变化。因此,您需要更具体地了解rjs中要更改的行。
我们要做的就是改变你返回的rjs。这个rjs现在只分配一个javascript变量:
page.assign "prices_for_product", "<option value=\"\">Select</option>" + options_for_select(@purchases.map { |c| [c.amount, c.id] })
现在我们必须创建一个新的javascript方法,它将使用该变量中的值并将其设置为当前元素。为此,您需要在定义load_close
和load_off
的javascript文件中添加以下方法:
function update_prices_for_product(prices_select_tag){
prices_select_tag.innerHTML = prices_for_product;
}
但是当AJAX调用成功时我们仍需要调用此方法,因此我们将把它添加到:success
参数。
:success => "load_off('loading_condition'); update_prices_for_product($(this));"
还有一些让我很困惑的事情。您将来自嵌套表单的supplier_product_id
发送到您的控制器,并将其作为purchase_product_id
注入您的查询,所有这些都在SupplierProduct表上调用。从我在数据模型上看到的不正确的东西,我必须承认我真的很困惑。请参阅update_product_div
操作:
SupplierProduct.find(:all,:conditions=>['purchase_product_id =? ',params[:product] ],:group=>['purchase_product_id'])
您正在寻找的是为产品完成的所有购买。那会更像是:
PurchaseProduct.find(:all,:conditions=>['supplier_product_id =? ', params[:product]])
您显然错过了supplier_product_id
表格中的purchase_products
列。
这就像我能为你做的那样,让我们希望别人跳进来......
我必须说这不是一个好习惯,你应该一直使用unobstrusive javascript并升级到jquery。此外,使用更新的Rails版本,因为没有多少人仍然可以帮助您使用Rails 2.3 ...
这个答案唯一的好处是它可能会起作用......