I made an application that has a project
model. The model has some information stored in it, and a user can add comments to the project
(using the comment
model). In the show view of a project I want the user to be able to switch between an "info" partial (containing the project information, and a "comment" partial (containing the comments wrote on the project). I want to do this using AJAX. So I will have two buttons: Information & Comments.
Now I know how to render a partial based on a "remote link", but I'll also have to find out which link was clicked. So far I can render one partial when one link is clicked like so:
// In show.html.haml
= link_to("Information", :project, :id => "link_one", :remote => true)
= link_to("Comments", :project, :id => "link_two", :remote => true)
#partial_window
// In show.js.haml
$("#partial_window").html("#{j(render("comments"))}")
Now this renders the _comment.html.haml
partial when I click on one of the links. What I need to know is how to check which link was clicked, and then render the appropriate partial: _info.html.haml
or _comments.html.haml
.
Thanks in advance for your help!
Rails Guides describes partials this way: Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
2.2. By default, if you use the :plain option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option and use the . text. erb extension for the layout file.
remote: true is really just telling the browser to not refresh the page. Do the action that you would normally do, but don't do anything to the page.
The most popular way to add Ruby code inside Rails views is with embedded Ruby (ERB). Files with embedded Ruby have the extension . html. erb and these files can have any amount of regular html markup.
Something like this should work. We are going to use nested routes. Check out ryan's screencast (a little old, but it gets the point across) or this more updated version about nested forms (uses the same principles). You'll have to pay for the updated version, but I find my RailsCast subscription to be more than worth the $9/month. Also, here are the docs for examples.
config/routes.rb
resources :projects do
resources :comments
end
comments_controller.rb
class CommentsController < ApplicationController
def index
project = Project.find params[:project_id]
@comments = project.comments
respond_to do |format|
format.html #responds with default html file
format.js #this will be the javascript file we respond with
end
end
end
views/comments/index.js.erb
$('#holderDiv').empty().append('<ul> <%= j render @comments %> </li>')
This uses a nifty thing of rails that looks for a comment
partial and renders it for each comment in @comments
. The j helper escapes javascript and pretty much inserts the rendered partial into the append
function.
views/comments/_comment.html.erb
<li> <%= @comment.description %> </li>
So we've now cleared the #holdingDiv
and inserted our comments. For information
, maybe something like this:
projects_controller.rb
class ProjectsController < ApplicationController
def index
@project = Project.find params[:id]
respond_to do |format|
format.html
format.js
end
end
end
views/project/index.js.erb
$('#holderDiv').empty().append('<%= j render 'information', information: @project.information %>')
views/project/_information.html.erb
<h2>
<%= information.title %>
</h2>
<p>
<%= infomration.details %>
</p>
Then, your remote links would be something like:
= link_to("Information", @project, :remote => true)
= link_to("Comments", project_comments_url(@project), :remote => true)
I had to make some assumptions about what your data structures were. Let me know where I've confused you.
Also, I am sure I have some typos, sorry for that. I did not test this, just went off the top of my head.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With