OK. So I am so close . . . and 开发者_如何学Pythonso frustrated. Please help. Here is are the two drop down lists which are part of the products/new page
<p>
<%= f.label :category_id %>:
<%= f.select("category", Category.find(:all).collect {|c|[c.name, c.id]})%>
</p>
<%= observe_field :product_category, :url => {:controller => 'products', :action => 'get_subcategories'}, :update => "subcategory_div" %>
Subcategory: <div id="subcategory_div"></div>
I have code in the products controller like this:
def get_subcategories
@subcategories = Subcategory.find_all_by_category_id( params[:id]).sort_by{ |k| k['name'] }
render :partial => "subcategories", :locals => {:subcategories => @subcategories}, :layout => false
end
This is the partial:
<select id="product_subcategory" name="product[subcategory]">
<% for subcategory in subcategories %>
<option value="<%= subcategory.id %>"><%= subcategory.name %></option>
<% end %>
</select>
When I hit the first drop down, the observe does fire, but it doesn't sent the parameter. I have tried adding :with => a variety of different ways, but it always posts just localhost:3000/products/get_subcategories. If I go directly to URL localhost:3000/products/get_subcategories/1 the partial renders fine. Similarly, if I replace the :url in the observe_field with localhost:3000/products/get_subcategories/1 it works fine (of course not dynamically).
This is the header that is posted:
http://localhost:3000/products/get_subcategories POST /products/get_subcategories HTTP/1.1 Host: localhost:3000 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 Accept: text/javascript, text/html, application/xml, text/xml, */* Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive X-Requested-With: XMLHttpRequest X-Prototype-Version: 1.6.0.3 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: Content-Length: 69 Cookie: _Customer_Portal_session=BAh7BzoQX2NzcmZfdG9rZW4iMWFmeGFqaXo0T0t3MkJqSG9ONjRDaWpROVdzWDc1K0Jtd1hYZldtcGh5ems9Og9zZXNzaW9uX2lkIiU2M2E3OWNjNDU4NTdhOTQ2ZDgyMGQyOWUyYWM1MGRiOA%3D%3D--c8fc61c71a851b22183015150365b2eb1df0d356 Pragma: no-cache Cache-Control: no-cache 1&authenticity_token=afxajiz4OKw2BjHoN64CijQ9WsX75%2BBmwXXfWmphyzk%3D HTTP/1.1 200 OK Connection: close Date: Thu, 19 Aug 2010 21:20:23 GMT Etag: "0799f242edbcaef2390601b55aaa04c2" Content-Type: text/html; charset=utf-8 X-Runtime: 55 Content-Length: 74 Cache-Control: private, max-age=0, must-revalidate ----------------------------------------------------------
This is what it looks like in the source:
//<![CDATA[
new Form.Element.EventObserver('product_category', function(element, value) {
new Ajax.Updater('subcategory_div', '/products/get_subcategories',{
asynchronous:true,
evalScripts:true,
parameters:value + '&authenticity_token=' + encodeURIComponent('afxajiz4OKw2BjHoN64CijQ9WsX75+BmwXXfWmphyzk=')
})
})
//]]>
If you read the resulting JavaScript you'll see that the parameter in the select simple isn't there. And why would it be? How should it know? You'll get it working using the :with
key in the options to observe_field
.
<%=
observe_field(
:product_category,
:url => {
:controller => 'products',
:action => 'get_subcategories'
},
:with => 'id',
:update => "subcategory_div"
)
%>
OK. I figured out my problem, and it was silly. The reason I didn't include the :with is because according to the documentation by default the observed value was sent in. Well, after looking at the logs, I did add the :with back in (:with => "value") and it still didn't work. But the problem was in the get_subcategories method of the products_controller. As soon as I changed the params to Subcategory.find_all_by_category_id( params[:value]).sort_by{ |k| k['name'] }, Doh! and voila, it worked.
To all who have responded to this post and others, I thank you for putting up with a new Ruby user who assumed it was some arcane Rails syntax problem, rather than a simple name change.
精彩评论