The navigation for my site is obviously stored in the application layout file. Part of that navigation is driven by the database. How to I render a partial in the layout and pass in the collection of objects for it to render?
EDIT:
I think my question revolves more around how to get data into the partial, is that done form the application controller or do I have to add the data in each action on each controller?
If you just wish to pass one object in then you can use the object key on render. The passed object will be accessible as an local variable of the same name as the partial. SO if the partial is called navigation the local variable will be navigation.
<%= render :partial => 'foo/navigation', :object => #my_collection
In the partial:
<% for obj in navigation %>
...
<% end %>
If you wish to pass multiple objects then you can use the locals key. The names of the local variables in your layout are then the keys of the passed hash.
<%= render :partial => 'foo/navigation', :locals => { :foo => 'Hello', :bar => 'World' }
In the partial:
<%= foo %>
<%= bar %>
Related
I have a Rails 3 application with simple navigation that contains links to controllers actions using link_to helper.
Now, I need to add a link which will refer to partial. Is it possible to combine the link_to and render: partial methods?
Generally, what I need is to combine somehow the following codes and have a link_to which is rendering the partial:
<%= link_to 'List', security_users_path , remote:true, class:'e-icon e-icon-camera' %>
<% #security_user = SecurityUser.new %>
<%= render partial: 'security_users/sign_in', :locals => {:security_user => #security_user} %>
If it is not possible, what other alternatives I have if I want to render a partial?
I have a property search page (:controller => 'properties', :action => 'index') that consists of a right sidebar that has a search form which displays the search results below the form. When the user clicks on a property in the right sidebar I want to display the details of that property in the main area of the index page on the left.
Right sidebar is a partial called properties/_property.html.erb:
<%= form_tag properties_path, :method => 'get' do %>
<%= text_field_tag 'location', (params[:location]) %>
<%= select_tag(:max, options_for_select([['No Max', ""], ['$100,000', 100000], ['$200,000', 200000], etc %>
more search fields for baths beds etc
<%= submit_tag "Search", :name => nil %>
<% end %>
<% #properties.each do |property| %>
<%= link_to([property.Address,property.City].join(", "), {:action => 'show', :id => property.id}) %>
<li><strong><%= number_to_currency(property.Price, :precision => 0) %></strong></li>
etc etc
<% end %>
The only way I know how to show the property details is with the 'show' action, but that takes the user to a new page, for example localhost:3000/properties/1865. I've made the 'show' view with the same layout as the 'index' view and have made the right sidebar a partial (properties/_property.html.erb) which appears on both 'show' and 'index' so when the user clicks on a property in the right sidebar and goes to localhost:3000/properties/1865 the property details are displayed correctly in the main area and the right sidebar is on the right.
But because localhost:3000/properties/1865 is a different page than localhost:3000/properties/index the search form in the right sidebar has forgotten it's parameters which means the list of search results in the right sidebar has changed back to the default list of all properties.
How can I display the 'show' action within a partial on the index page so the user's search parameters are remembered by the form in the right sidebar? Or if I have to go to the 'show' page how can I make the right sidebar stay exactly as it is?
Any ideas greatly appreciated, just a suggestion in the right direction would be good, have spent all day trying to figure it out and have got nowhere, thanks
I have made the show view with the same layout as the index view and
have made the right sidebar a partial (properties/_property.html.erb)
which appears on both show and index.
Yes but this will only get you a similar layout for both the pages. You want the list to persist between different requests.
You basically have two options. use session to remember the list which I wont recommend.
Other is you use form :remote => true or ajax and update the page partially.
EDIT:
What version of rails you are using? Do u have jquery loaded in your application?
Follow this SO POST.
You might have to change your show action a bit.
respond_to do |format|
format.js {render :partial => 'property_details' ,:layout => false}
format.html
end
Create a partial for property details and just put body content here.
And link will look like
<%= link_to "link name", {:action => :show, :id => item_id}, :remote => true ,:html => {:class => 'links_product'} %>
Also to update the view you may use(make sure you have rails.js in your page):
$(document).ready(
function(){
$("a.links_product").bind("ajax:success",
function(evt, data, status, xhr){
$("#response").html(data); // in case data is html. (_*.html.erb)
}).bind("ajax:error", function(evt, xhr, status, error){
console.log('server error' + error );
});
});
Have a div with id response or any valid id. Done!
I want to pass a local variable that contains the origin to come on a specific page, this variable contains just a symbol with the value.
When I use this code it works perfect, the origin variable is accessible in the partial :
render :partial => "products", :collection => #products, :locals => {:origin => :gallery}
But when I use this code, the origin is not set and not accessible in the partial :
render #products, :locals => {:origin => :gallery}
What is the difference here? Is the second line of code not render the partial like the first line?
<%= render #products %>
Is indeed the shorthand syntax for rendering a partial. But with the shorthand syntax, Rails will ignore the ":locals" variable. There's more on this in the Rails Guides.
So if you want to pass extra options to the render, you have to specify ":partial => ...". If you want to know why this happens, you can take a look at the Rails source.
There's a good explanation here: Rails: confused about syntax for passing locals to partials
The short version is that you can just omit :locals in the second example:
render #products, :origin => :gallery
I have a model named "Post". I want to use a modal form to create a new post while at the SHOW view of another post. Meaning while I am viewing the post named "John" in its show view, I would like to be able to create a new post from right there.
The problem I have is that the ID of the new post remains the same as the post I am viewing, and causes the update action to be fired instead of the create action. Any suggestions on how to handle this?
Build a new post with Post.new and use that in a form_for:
<%= form_for Post.new %>
<%= render "form" %>
<% end %>
Of course this means you'll need to remove the form_for from your form partial if you have it in there, but that's a small sacrifice to make.
However if you really don't want to do that then you will have to pass through a local variable to the form partial to indicate which post you want to display. On the show page you'd have this:
<%= render :partial => "form", :locals => { :post => Post.new } %>
In the new and edit views you'd do this:
<%= render :partial => "form", :locals => { :post => #post } %>
The line is a little bit longer, but that would allow you to keep the form_for tag inside the form partial and not clog up the three other views with it.
I have a partial with yeild blocks, which I set using content_for, when I render partial I am also trying to pass in locals. The locals never get picked up in the partial.
<%= render :partial => 'shared/block', :locals => { :cssclass => 'medium' } %>
When I try to access the partial using
<%= :cssclass %>
All I get is the bare "cssclass" as a string rather than the variable I have set it to. Can you not use content_for and render partial at the same time?
Update
I tried rendering a partial with locals, no yield or content_for and the the values I setup while rendering the partial are getting picked up. Is there something I am missing?
use <%= cssclass %> instead of symbol. locals set a variable, not a symbol, and when you output symbol it is just converted to string.