2
votes

Trying to figure out how to get ajax working with my Acts_As_Votable buttons.

Here is what I have right now.


post_controller.rb

def favorite
  @post = Post.find(params[:id])
  @post.upvote_from current_user
  respond_to do |format|
    format.js
  end 
end

def unfavorite 
  @post = Post.find(params[:id])
  @post.unvote_by current_user
  respond_to do |format|
   format.js
  end 
end

_post.html.erb

<% if current_user.voted_on? post  %>
  <%= link_to '<i style="color: red" class="fa fa-star"></i> Favorited'.html_safe, unfavorite_post_path(post), method: :put, remote: true, id: "unfavorite" %>
<% else %> 
  <%= link_to '<i class="fa fa-star"></i> Favorite'.html_safe, favorite_post_path(post), method: :put, remote: true, id: "favorite" %>
<% end %>

favorite.js.erb & unfavorite.js.erb

$('#favorite').html("<i style='color: red' class='fa fa-star'></i> Favorited");

$('#unfavorite').html("<i class='fa fa-star'></i> Favorite");

Right now I have it partially working. I have two problems.

  1. Each page contains multiple posts. How can I tell the format.js.erb file to target that spectific post's favoirte button. Right now, the jQuery only changes the first posts button, no matter where I click on the page. I've tried setting the link_to ids to favorite<%= post.id %> and then using favorite<%= post.id %> in the format.js file but that didn't work.
  2. I want to change the format.js files to put the actual button into the div instead of just changing its text. So a user can toggle favorite and unfavorite without having to refresh the page. I've tried putting the link_to buttons inside the .html("") section but that doesn't work. I'm not sure how to submit a post request with ajax.

Thank you for the help! Let me know if you need any more code or I wasn't clear about something.

1

1 Answers

4
votes

An id must be unique in one page. You should be able to append the post.id to your link:

_post.html.erb

<% if current_user.voted_on? post  %>
  <%= render 'unfavorite_link', post: post %>
<% else %> 
  <%= render 'favorite_link', post: post %>
<% end %>

_favorite_link.html.erb

<%= link_to '<i class="fa fa-star"></i> Favorite'.html_safe, favorite_post_path(post), method: :put, remote: true, id: "favorite-#{post.id}" %>

_unfavorite_link.html.erb

<%= link_to '<i style="color: red" class="fa fa-star"></i> Favorited'.html_safe, unfavorite_post_path(post), method: :put, remote: true, id: "unfavorite-#{post.id}" %>

Instead of only setting the html using AJAX, you can use replaceWith which replaces the whole link, not just its inner HTML:

favorite.js.erb

$('#favorite-<%= @post.id %>').replaceWith('<%= escape_javascript render 'unfavorite_link', post: @post %>');

unfavorite.js.erb

$('#unfavorite-<%= @post.id %>').replaceWith('<%= escape_javascript render 'favorite_link', post: @post %>');