从嵌套形式发布组合框中的更新类 [英] Issue updating class in combobox from nested form
问题描述
我创建的组合框,显示供应商,以便当供应商选择将更新表示购买一个div,示出的购买将在组合框之后但在嵌套形式,以便当我选择购买会告诉我所选择的购买数额.
I created a combobox that show suppliers so when supplier is selected will update a div showing purchases , after showing purchases will be in combobox but in a nested form so when I select a purchase will show me the amount of the purchase selected.
问题在于,当我选择购买时,仅在第一行有效,而当我选择另一组合框时,则显示选择的第一个组合框的金额.
The problem is that when I select a purchase only works in the first line and when I select another combobox line show the amount of the first combobox selected.
这是我的桌子
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
Here is the controller /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
Here is the view: /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
Here is the partial view: /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
Here is the view 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
Here is the view 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
不是在其他行中更新,而是仅在第一行中更新.
Is not updating in other lines just updating in the first line.
请有人可以帮助我解决这个问题吗?
Please somebody can help me with this issue?
推荐答案
问题是,在更新产品时,您总是向控制器操作发送相同的值.
The problem is that you always send the same value to your controller action when updating products.
在您的/app/view/shopping_document/_shopping_product_fields.html.erb部分中查看以下行:
Look at this line from your /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")
时,它将使用id = 'someting'
From what I remember, in prototype.js, when you use $("something")
, it will find the first element in your DOM tree with id = 'someting'
您在with
子句中使用$('product')
的事实使它总是将第一行的选择标记值发送到服务器,这是错误的.
The fact you're using $('product')
in the with
clause makes it always send the select tag value of the first row to the server, which is wrong.
您应该使用$(this)
来确保它是正在发送的current
选择的值.因此,您需要替换:
You should be using $(this)
instead to make sure it's the value of the current
select that is being sent. So you need to replace:
:with => "'product=' + $('product').value"
有了这个:
:with => "'product=' + $(this).value"
另一个问题是,当您更改产品时,它会立即更改所有价格,而您只希望更改该产品的价格.因此,您需要更加明确地更改rjs中的哪一行.
Also another problem is that when you change the product, it changes all the prices at once, and you only want that product's price to change. So, you need to be more specific about what line to change in your rjs.
我们要这样做的方法是更改返回的rjs.现在,这个rjs只会分配一个javascript变量:
The way we are going to do that is by changing the rjs you return. This rjs will now just assign a javascript variable:
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文件中添加以下方法:
And now we have to create a new javascript method that will use the values in that variable and set it to the current element. For that you need to add the following method in the javascript file where you defined load_close
and load_off
:
function update_prices_for_product(prices_select_tag){
prices_select_tag.innerHTML = prices_for_product;
}
但是当AJAX调用成功后,我们仍然需要调用此方法,因此我们将其添加到:success
参数中.
But we still need to call this method when the AJAX call succeeds so we're going to add it to the :success
parameter.
:success => "load_off('loading_condition'); update_prices_for_product($(this));"
还有一些让我感到困惑的事情.您会将嵌套表单中的supplier_product_id
发送到控制器,并将其作为purchase_product_id
注入到您的查询中,所有在SupplierProduct表上调用的内容.从您的数据模型上我看到的是不正确的,我必须承认我真的很困惑.在您的update_product_div
操作中看到此内容:
There is also something that is really confusing me. You are sending the supplier_product_id
that comes from your nested form to your controller, and injecting it in your query as a purchase_product_id
, all that called on the SupplierProduct table. From what I can see on your data model that's not correct and I must admit I'm really confused. See this in your update_product_div
action:
SupplierProduct.find(:all,:conditions=>['purchase_product_id =? ',params[:product] ],:group=>['purchase_product_id'])
您要寻找的是针对某个产品完成的所有购买.那会更像:
What you're looking for are all the purchases done for a product. That would be something more like:
PurchaseProduct.find(:all,:conditions=>['supplier_product_id =? ', params[:product]])
您显然丢失了purchase_products
表上的supplier_product_id
列.
You're clearly missing the supplier_product_id
column on your purchase_products
table.
这就是我能为您做的事,希望其他人跳进来...
That's as much as I can do for you, let's hope someone else jumps in...
我必须说这确实不是一个好习惯,您应该使用不引人注目的JavaScript 一直升级到jquery.此外,请使用最新版本的Rails,因为仍然有很多人可以在Rails 2.3上为您提供帮助...
I must say that this is really not good practice and you should use unobstrusive javascript all the time and upgrade to jquery. Moreover, use a more up-to-date version of Rails because not many people can still help you with Rails 2.3...
此答案的唯一好处是,它可能会使它起作用...
The only thing good with this answer is that it might make it work...
这篇关于从嵌套形式发布组合框中的更新类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!