Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Acts as votable javascript vote button

I'm using a gem called acts_as_votable to make my model votable.

Currently everything is working.

But every time someone votes for a post, the page has to refresh. How do I get the voting to work without the page refreshing. Is there a simple javascript I can add?

Here is what I have in my controller:

def vote
  @post = Post.find(params[:post_id])
  @post.liked_by current_user
  respond_to do |format|
    format.html {redirect_to :back }
  end
end

Here is what I have in my view:

 <%= link_to “like post", like_post_path(@post), method: :put %>
like image 483
Katie H Avatar asked Apr 02 '14 03:04

Katie H


2 Answers

A very simple version might look like this:

Ruby

def vote
  @post = Post.find(params[:post_id])
  @post.liked_by current_user
  respond_to do |format|
    format.html {redirect_to :back }
    format.json { render json: { count: @post.liked_count } }
  end
end

Html

<%= link_to 'like', vote_path(@post), class: 'vote', remote: true, data: { type: :json } %>

JS

$('.vote')
  .on('ajax:send', function () { $(this).addClass('loading'); })
  .on('ajax:complete', function () { $(this).removeClass('loading'); })
  .on('ajax:error', function () { $(this).after('<div class="error">There was an issue.</div>'); })
  .on('ajax:success', function (data) { $(this).html(data.count); });

This is a very rudimentary version that shows the basic approach, but it has some obvious pitfalls:

  • There is no way to "unvote"
  • A "loading" indicator isn't great UX; with JS we can always show the user's current state and deal with syncing to the server in the background
  • Any HTML cacheing in the view will blow this up
like image 150
Wheeyls Avatar answered Sep 28 '22 08:09

Wheeyls


Simple. Take away your respond block:

def vote
  @post = Post.find(params[:post_id])
  @post.liked_by current_user
end

and make your button remote:

<%= link_to “like post", like_post_path(@post), method: :put, remote: true %>

If you would like to have a script run when a person votes to pop up a message or something, create a file vote.js.erb (by rails naming convention) and put it in the view folder. You can put javascript in there that will run when the controller action is accessed.

PS, are you sure the path like_post_path points to your vote controller?

like image 27
Marco Prins Avatar answered Sep 28 '22 08:09

Marco Prins