Reputation: 39
I'm trying to update the vote counts when I click on like or dislike by using ajax so the page don't have to reload. The buttons seem to be working in the server logs and I'm not getting any errors in the console logs.
The vote counts are not updating unless I refresh the page. How can I get the vote counts to update with ajax/json?
Show View with buttons
<span class="up"><%= @lyric.get_upvotes.size %> </span>
<%= link_to like_lyric_path(@lyric), class: 'voteup', remote: true, data: { type: :json }, method: :get do %>
<span class="glyphicon glyphicon-chevron-up" aria-hidden="true"></span>
<% end %>
<span class="down"><%= @lyric.get_downvotes.size %></span>
<%= link_to dislike_lyric_path(@lyric), class: 'votedown', remote: true, data: { type: :json }, method: :get do %>
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
<% end %>
JS
$('.voteup')
.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 () {
$('.up').html('<%=escape_javascript @lyric.get_upvotes.size.to_s %>');
$('.down').html('<%=escape_javascript @lyric.get_downvotes.size.to_s %>');
});
</script>
<script>
$('.votedown')
.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 () {
$('.up').html('<%=escape_javascript @lyric.get_upvotes.size.to_s %>');
$('.down').html('<%=escape_javascript @lyric.get_downvotes.size.to_s %>');
});
</script>
Controller
def upvote
@lyric.upvote_by current_user
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { data: @lyric.get_upvotes.size} }
format.js { render :layout => false }
end
end
def downvote
@lyric.downvote_by current_user
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { data: @lyric.get_downvotes.size } }
format.js { render :layout => false }
end
end
Upvotes: 0
Views: 40
Reputation: 410
The JS loaded once page is fetched will remain static. So the lines $('.up').html('<%=escape_javascript @lyric.get_upvotes.size.to_s %>');
and
$('.down').html('<%=escape_javascript @lyric.get_downvotes.size.to_s %>');
which need to be run on the server(as it is rails code, that executes on the server) to get the updated value of @lyric.get_upvotes.size.to_S
will not work. Instead what you can do is,
the format.json
is already returning the json
- {data: 10}
....where 10 is suppose the number of votes(up or down whichever).
Modify the ajax:success
of both .voteup
and .votedown
classes to this
$('.voteup').
on('ajax:success', function (result) {
$('.up').html(result.data + ' Upvotes');
});
$('.votedown').
on('ajax:success', function (result) {
$('.down').html(result.data + ' Downvotes');
});
Upvotes: 1