Reputation: 1115
So I have a sidebar in my rails application. Basically, I have a grid full of images. When someone clicks on an image in the grid, I basically want the show view to be displayed in the sidebar. I'm clueless on how to do this.
I've tried copying and pasting the show view's html and erb into my _sidebar.html.erb
partial. But I get variable errors. My partial is located in my layout folder. But I can move it if needed.
Here is an image of the application for a better idea of what I'm talking about.
Upvotes: 3
Views: 2549
Reputation: 76774
Here's how to do it:
1) Include the sidebar
partial in your layout:
#app/views/layouts/application.html.erb
<%= render "shared/sidebar" %>
This calls the _sidebar.html.erb
partial in /app/views/shared
:
2) Populate the "default" sidebar partial:
#app/views/shared/_sidebar.html.erb
...
The important thing to note here is that partials should never have @instance
variables inside.
Partials have locals
, which you can pass with the following command:
<%= render "shared/sidebar", locals: { variable: "value" } %>
Partials are meant to run on any part of your web application, and since @instance
variables are present for a single "instance" of an object (IE @post
won't be available in /users
), you can ensure partials are always populated by passing local variables to them.
This is why you received errors when copying your post#show
code to your sidebar
partial -- the instance variables present for the show
action will not be present in other parts of the app.
3) Use JS to pull image objects
When someone clicks on an image in the grid, I basically want the show view to be displayed in the sidebar.
You need to be more specific - do you really want the "show" action to appear, or do you want parts of its functionality?
Either way, you'll be best using JS & ajax to pull the data:
#app/controllers/images_controller.rb
class ImagesController < ApplicationController
layout Proc.new { |controller| !controller.request.xhr? }
end
#app/assets/javascripts/application.js
$(document).on("click", "img", function(e) {
e.preventDefault();
$.get($(this).attr("href"), function(data){
$(".sidebar .image").html(data);
});
});
This will take the rendered images#show
action (without layout), and append it to your sidebar partial. This is what you asked for - I can change it if required.
Upvotes: 2
Reputation:
Lets say that your model is called "Image".
In your "images/show.html.erb":
# This is a handy shortcut that will call the 'images/_image' partial.
# Those two lines are exactly the same.
<%= render @image %>
<%= render "images/image", image: @image %>
In your "_sidebar.html.erb":
<div id="sidebar-img"></div>
In your "images/_image.html.erb":
# Code displaying your image, don't use any global variable.
# 'image' is the name of the local variable
In your grid:
# remote: true allows you to do an AJAX call
<%= link_to image, remote: true do %>
# Something like that, I don't know your code
<%= image_tag image.url %>
<% end %>
Create "images/show.js.erb", when clicking on a 'remote :true' link it will call this file.
# set @image to Image.find(params[:id]) in your controller
$("#sidebar-img").html("<%= render @image %>");
Upvotes: 1