Here is a simple example of the problem.
http://gist.github.com/235729
In short, if you have a index.rhtml with:
<%= link_to_function "A link to insert a partial with nested insert_html" do |page|
page.insert_html :top, :with_a_nested_insert_html, :partial => 'example_partial_with_nested_insert_html'
end %>
And a _example_partial_with_nested_insert_html.rhtml
<%= link_to_function "A nested link to insert_html" do |page|
page.insert_html :top, :with_a_nested_insert_html, :partial => 'you_wont_see_this'
end %>
It breaks the "A link to insert a partial with nested insert_html". I am thinking something needs to be done to protect the javascript in the partial.
Any thoughts?
Here's how I do it.
<%= link_to_function( "insert it", :id => 'foo') do |page|
partial = escape_javascript(render :partial => "my_partial", :object => Object.new)
page << "$('#my_div').append(\"#{partial}\")"
end %>
Try using escape_javascript before rendering the partials - see this other question.
I didn't try but I strongly think the syntax should be more something like :
<% link_to_function "A link to insert a partial with nested insert_html" do |page|
<%= page.insert_html :top, :with_a_nested_insert_html, :partial => 'example_partial_with_nested_insert_html' %>
<% end %>
Related
On my Home#Index page, I have this:
<%= render 'home/popular_products', :collection => #products, :as => :product %>
In my Home#_popular_products view, I have this:
<div class="span2 recommended">
<%= image_tag product.image_url(:thumb).to_s %>
</div>
This is the error I keep getting:
undefined local variable or method `product' for #<#<Class:0x007f871c4f6848>:0x007f871cdb7e28>
As far as I understand it, I shouldn't even have to specify the :as attribute in my render statement - but I tried this to be explicit after just using the :collection => #products wouldn't work.
In my Home#Index Controller I have this:
#products = Product.all.sample(6)
Thoughts?
I believe you have to specify the :partial option if you want to pass in any other options. Ie:
<%= render :partial => 'home/popular_products', :collection => #products, :as => :product %>
Should work.
Do you put _popular_products.html.erb file in your app/views/home/? I think you're using partial not following convention of rails, so rails's not understood product variable. Your partial should be named _product.html.erb if you want to used like that. With that partial, you can write like this:
<%= render #products %>
Update
Solution 1
Index page:
<%= render 'popular_products', :collection => #products %>
Partial:
<%= image_tag popular_products.image_url(:thumb).to_s %>
Solution 2
Index page:
<% #products.each do |product| %>
<%= render :partial => "popular_products", :locals => { :product => product } %>
<% end %>
Partial:
<%= image_tag product.image_url(:thumb).to_s %>
I have Article(s), that has_many ArticleAssets. Fairly simple. On the edit form for the Article I just want to add new article assets. I don't need to edit the current ones, so I created a partial like this:
<% f.fields_for :article_assets, article_asset do |builder| -%>
<div class="article_asset">
<%= builder.file_field :image %>
<%= builder.check_box :is_flagged, :class => "isFlagged" %> isFlagged
</div>
<% end -%>
No collection, because I only need one object at a time and need no data from the existing article assets. In the form of edit.erb I render the following:
<%= render :partial => 'article_asset', :locals => {:f => f}, :object => ArticleAsset.new %>
This makes one new article asset show up that I can add information to, all cool so far. Important is that this field gets the name-form of article[article_assets_attributes][0][is_flagged]. All good since this will also group the hidden field that always comes with a checkbox in rails to the rest of the fields. Then I have an "Add item" link that does this:
page.insert_html :bottom, :article_assets_fields, :partial => "article_asset", :locals => {:f => f}, :object => ArticleAsset.new
Clicking on this link gives a new field under the created one, as expected, with the name-form of the checkbox field of article[article_assets_attributes][1][is_flagged]. Incremented, that's perfect! Adding another one with the same link however, also gives the same form (also with the identifier of 1, duplicate), which makes submitting the form only have 2 items instead of 3. Does anyone know why this happens and what I can do to solve it?
Ruby on Rails 2.3.11
Nested form 2.3 fail. This one was the bane of my existence for some time, even having watched the railscast etc. Here's my how to:
1) this goes in article.rb
after_update :save_article_assets
def new_article_asset_attributes=(article_asset_attributes)
article_asset_attributes.each do |attributes|
article_assets.build(attributes)
end
end
def existing_article_asset_attributes=(article_asset_attributes)
article_assets.reject(&:new_record?).each do |article_asset|
attributes = article_asset_attributes[article_asset.id.to_s]
if attributes
article_asset.attributes = attributes
else
article_assets.delete(article_asset)
end
end
end
def save_article_assets
article_assets.each do |article_asset|
article_asset.save(false)
end
end
2) In a helper somewhere:
def add_article_asset_link(name)
button_to_function name, :class => "new_green_btn" do |page|
page.insert_html :bottom, :article_assets, :partial => "article_asset", :object => ArticleAsset.new()
end
end
def fields_for_article_asset(article_asset, &block)
prefix = article_asset.new_record? ? 'new' : 'existing'
fields_for("article[#{prefix}_article_asset_attributes][]", article_asset, &block)
end
3) in your partial:
<% fields_for_article_asset(article_asset) do |aa| %>
<tr class="article_asset">
<td><%= aa.text_field :foo %></td>
<td><%= link_to_function "remove", "$(this).up('.article_asset').remove()" %></td>
</tr>
<% end %>
4) in the _form:
<table>
<%= render :partial => "article_asset", :collection => #article.article_assets %>
</table>
<%= add_article_asset_link "Add asset" %>
Here is the code in rfqs/_form_new.html.erb to add a selection box for standard.
<%= simple_form_for #rfq do |f| %>
<div id="std">
<%= render :partial => 'standards/standards', :collection => #rfq.standards, :locals => { :f => f } %>
</div>
<%= link_to_function "Add Std", nil do |page| %>
page.insert_html :bottom, :std, :partial => 'standards/standards'
<% end %>
<% end %>
The html source code has # after href and cause no reaction for clicking the link.
Add Std
The _standards.html.erb partial looks like:
<%= f.association :standards, :collection => Standard.active_std.all(:order => 'name'), :label_method => :name, :value_method => :id %>
Any thoughts about missing link after href? Thanks.
I don't believe 3.1's link_to_function works the same way as older versions; I don't see anything in the source that utilizes a block.
This seems in keeping with using unobtrusive JavaScript. The Rails pulls related to accepting a block seem more related to link text rather than injecting JS.
I am trying to create a tabbed interface using the prototype helper method "replace_html." I have three different partials I am working with. The first one is the 'main tab' and it is loaded automatically like so:
<div id = "grid">
<% things_today = things.find_things_today %>
<%= render :partial => "/todaything", :collection => things_today, :as =>:thing %>
</div>
...which works fine. Similarly, I have a _tomorrowthing partial which would replace the content in the 'grid' div like so:
<%things_tomorrow = things.find_things_tomorrow%>
<%= link_to_function('Tomorrow',nil, :id=>'tab') do |page|
page.replace_html 'grid' , :partial => '/tomorrowthing',:collection => things_tomorrow, :as => :thing
end %>
If I click on this tab nothing happens at all. Using firebug, the only errors I find are a missing ) after argument list which is contained in the Element.update block where the link_to_function is called. What am I doing wrong?
Hey Jack i try to reproduce the same but i can't i never used link_to_function before but
Following code may help to achieve the same you want
<%= link_to_remote "Today Thing", :url=>{:action=>"things", :id=>'today'}%>
<%= link_to_remote "Tomorrow Thing", :url=>{:action=>"things", :id=>'tomorrow'}%>
<div id = "grid">
<% #things = things.find_things_today %>
<%= render :partial => "/todaything", :collection => #things %>
</div>
in controller
def things
#things= (params[:id]=="today")? things.find_things_today : things.find_things_tomorrow
render :update do |page|
page.replace_html 'grid', :partial => (params[:id]=="today")? "/todaything" : '/tomorrowthing' , :objects=> #things
end
I'm trying to learn Rails better by looking at example applications, and while looking at this line of the source of railscasts.com, I noticed it does this:
<div class="episodes">
<%= render #episodes %>
</div>
What exactly is going on here? Why isn't this documented on the render function? Or is it?
This is a handy shortcut for doing
<%= render :partial => "episode", :collection => #episodes %>
which is another way of doing
<% for episode in #episodes do %>
<%= render :partial => "episode", :locals => { :episode => episode }
<% end %>
which is pretty obvious in what it does :)
Hope that makes sense :)
btw it's really surprising I couldn't find the docs for this too.
This is shorthand for
render :partial => "episode", :collection => #episodes
The form above is documented in the Rails API docs under render (ActionController::Base). The shorthand form is not documented as far as I can see except in the Rails Guides.
This is a new shortcut:
<%= render #episodes %>
# equivalent to
<%= render :partial => 'episode', :collection => #episodes %>
You can also do shortcuts with single items
<%= render 'comment', comment => #comment %>
# equivalent to
<%= render :partial => 'comment', :locals => {:comment => #comment} %>