从嵌套形式发布组合框中的更新类 [英] Issue updating class in combobox from nested form

查看:73
本文介绍了从嵌套形式发布组合框中的更新类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建的组合框,显示供应商,以便当供应商选择将更新表示购买一个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_closeload_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆