Reputation: 21
I am pretty new to JS, but I hope I am missing something simple. I am trying to reload a partial that displays an image asynchronously. When a user clicks on the link below, it registers their vote, then (it should) render the pins partial with a new image from the database.
index.html.erb (The link)
<%= link_to 'Less', {:controller => "pins",
:action => "create_view",
:rank => 0,
:user_id => current_user.id,
:pin_id => @pins.id
},
:method => "post", :remote => true %>
pins_controller.rb (Method called by link)
def create_view
@view = View.new
@view.user_id = params[:user_id]
@view.pin_id = params[:pin_id]
@view.rank = params[:rank]
if @view.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
render action: "new"
end
end
pins_controller.rb (Method that generates @pins)
def index
seen = Array.new
max_pins = 20
sex = current_user.sex
views = View.user_views(current_user)
seen = views.map(&:pin_id)
@pins = Pin.new_pin(seen, sex)
models/pins.rb
def self.new_pin(pin_ids, sex)
b = TRUE
self.find(:first, :conditions => ["sex = ? AND active = ? AND id not in (?)", sex, b, pin_ids], :order => "created_at desc" )
end
index.html.erb (The DIV and partial)
<div id="main_well">
<%= render @pins %>
</div>
create_views.js.erb (The javascript triggered on click)
$('#main_well').html("<%= escape_javascript(render (partial: "pin", :locals => { pin: @pins})) %>");
_pin.html.erb (The partial to be reloaded by JS)
<div class="row">
<div class="center_well">
<div class="well" style="background-image: url('<%= pin.image %>')" onclick="window.open('<%= pin.product_url %>','mywindow');"></div>
</div>
</div>
I have been at this for a while. Here's what I know. Clicking the link does remotely update the database. And if I change the JS to $('#main_well').remove(), clicking the link does remove the image asynchronously. However, I cannot for the life of my get the image to update onclick without refreshing the page. Thanks in advance for your help.
EDIT
As in the answer below, the instance variable @pins was not leading in the create_views method. Thus, regenerating the instance variable link this seemed to solve the problem.
pins_controller.rb
def create
seen = Array.new
max_pins = 20
sex = current_user.sex
views = View.user_views(current_user)
seen = views.map(&:pin_id)
@pins = Pin.new_pin(seen, sex)
@view = View.new
@view.user_id = params[:user_id]
@view.pin_id = params[:pin_id]
@view.rank = params[:rank]
if @view.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
render action: "new"
end
end
However, this solution only serves to reload the partial successfully once. If I click the link, it reloads the image. However, if I click the link again, nothing happens. However, if I change the function like so it works perfectly:
pins_controller.rb
def create
seen = Array.new
max_pins = 20
offset = rand(Pin.count)
@pins = Pin.first(:offset => offset)
@view = View.new
@view.user_id = params[:user_id]
@view.pin_id = params[:pin_id]
@view.rank = params[:rank]
if @view.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
render action: "new"
end
end
It seems that the local variable "view" is not being reloaded the second time I click the link. I have no idea why. Any help would be greatly appreciated.
views.rb
def self.user_views(user)
self.find(:all, :conditions => ['user_id = ?', user])
end
Upvotes: 2
Views: 325
Reputation: 76784
Update
In reference to the comments, this worked:
def index
seen = Array.new
max_pins = 20
sex = current_user.sex
views = View.user_views(current_user)
seen = views.map(&:pin_id)
@pins = Pin.new_pin(seen, sex)
end
def create
seen = Array.new
max_pins = 20
sex = current_user.sex
views = View.user_views(current_user)
seen = views.map(&:pin_id)
@pins = Pin.new_pin(seen, sex)
@view = View.new
@view.user_id = params[:user_id]
@view.pin_id = params[:pin_id]
@view.rank = params[:rank]
if @view.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
render action: "new"
end
end
Original Answer
From looking at your code, it seems it should work, but I imagine there are syntax problems preventing it from doing so
@pins
You're calling @pins
in a completely new action
The problem is that your ajax
request is a new request (your instance is concluded after the initial HTTP request ends). This means your @pins
instance variable is not persisting through the ajax call, and is likely why your partial won't render correctly
Try:
#app/controllers/pins_controller.rb
def index
@pins = Pin.new_pin(seen, sex)
end
def create
@pins = Pin.find(params[:id])
end
Partial
When calling your partial, you can then try this:
$('#main_well').html("<%=j render partial: "pin", :locals => { pin: @pins} %>");
This should work if your @pins
variable is called properly
Update
def self.user_views(user)
where(user_id: user.id)
end
Upvotes: 1
Reputation: 11429
Try changing this:
$('#main_well').html("<%= escape_javascript(render (partial: "pin", :locals => { pin: @pins})) %>");
to this (add html_safe to the end of the escape_javascript call):
$('#main_well').html("<%= escape_javascript(render :partial => 'pin', :locals => { pin: @pins}).html_safe %>");
EDIT
The problem is probably related to how the partial is being rendered. Does this work?
$('#main_well').html("<%= escape_javascript("#{image_tag pin.image}").html_safe %>")
Upvotes: 0