从嵌套表单发出combobox中的更新类
我创建了一个combobox,显示供应商,因此当选择供应商时将更新显示购买的div,显示购买后将以comboboxforms进行嵌套,因此当我选择购买时将显示所选购买的金额。
问题是,当我选择购买时,仅在第一行中工作,当我选择另一个combobox线时,显示所选择的第一个combobox的数量。
在这里我的表
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 ['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 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
{:controller=>"shopping_document",:action=>'create'} do |f| %> Name: <%= select_tag 'suppliers',"Select"+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]" %> builder %>
以下是部分视图:/app/view/shopping_document/_shopping_product_fields.html.erb
"9" %> <%= select_tag "product","Select"+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" %> <%= f.select :purchase_product_id,"Select"+options_for_select(@purchases.map { |c| [c.amount, c.id] }), {}, :class => "helping" %> 0,:size=>"14x14"), f %>
这是视图rjs:/app/view/shopping_document/_update_supplier_div.rjs
page.select('.product').each do |select_tag| page.replace_html select_tag, "Select"+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,"Select"+options_for_select(@purchases.map { |c| [c.amount, c.id] }) end
不在第一行中更新其他行只是更新。
请有人帮我解决这个问题吗?
问题是您在更新产品时始终向控制器操作发送相同的值。
从/app/view/shopping_document/_shopping_product_fields.html.erb partial看这一行:
<%= select_tag "product", ""+ 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'
的第一个元素
您在with
子句中使用$('product')
的事实使它始终将第一行的select标记值发送到服务器,这是错误的。
您应该使用$(this)
来确保它是正在发送的current
选择的值。 所以你需要更换:
:with => "'product=' + $('product').value"
有了这个:
:with => "'product=' + $(this).value"
另一个问题是,当您更改产品时,它会立即更改所有价格,您只希望该产品的价格发生变化。 因此,您需要更具体地了解rj中要更改的行。
我们要这样做的方法是改变你返回的rjs。 这个rjs现在只需分配一个javascript变量:
page.assign "prices_for_product", "" + 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]])
您显然缺少purchase_products
表上的supplier_product_id
列。
这就像我能为你做的那样,让我们希望别人跳进去……
我必须说这不是很好的做法,你应该一直使用不引人注目的javascript并升级到jquery。 此外,使用更新的Rails版本,因为没有多少人仍然可以帮助您使用Rails 2.3 …
这个答案唯一的好处就是它可能会起作用……