Reputation: 2170
I've implemented a star rating system using "Creating an Ajaxified Star Rating System in Rails 3".
After modifying the code, everything works in the index page, but, for some reason, the stars don't stay glowing after I've clicked them. I think there is a problem in my JavaScript. Is there a way to just do it through the CSS?
If you need me to add anything else please let me know.
rating_ballot.js:
$(document).ready(function() {
### Makes stars stay glowing after click.
### But after its clicked, the value is saved, But the star doesn't stay glowing.
$('form.rating_ballot > label').click(function() {
$(this).siblings().removeClass("bright");
$(this).prevAll().andSelf().addClass("bright");
});
### Submits the form & saves data.
$(document).on('change', '.rating_button', function(){
$(this).parent().submit();
});
});
CSS.SCSS:
form.rating_ballot input.rating_button { display: none; }
form.rating_ballot label.rating { cursor: pointer; display: block; height: 20px; width: 20px; float: left; }
form.rating_ballot label.rating span { display: none; }
form.rating_ballot label.rating { background-image: image-url('star-dim.png'); }
form.rating_ballot label.rating.bright { background-image: image-url('star-bright.png'); }
form.rating_ballot label.rating.glow { background-image: image-url('star-glow.png'); }
index.hrml.erb (books):
<% @books.each do |book| %>
<table id="book_<%= book.id %>">
<tbody>
<tr>
<td>
<%= book.title %>
</td>
</tr>
<tr>
<td id="rating">
<%= render :partial => 'ratings/rating', :locals =>{:book => book} %>
</td>
</tr>
<tbody>
</table>
<% end %>
_rating.html.erb:
<%= form_for(rating_ballot(book.id), remote: true, :html => { :class => 'rating_ballot' }) do |f| %>
<% sfx = "value_#{book.id}_1" %>
<%= f.label(sfx, content_tag(:span, '1'), :class => "rating") %>
<%= radio_button_tag("rating[value]", 1, current_user_rating(book.id) == 1,
:class => 'rating_button', :id => "rating_#{sfx}") %>
<% sfx = "value_#{book.id}_2" %>
<%= f.label(sfx, content_tag(:span, '2'), :class => "rating") %>
<%= radio_button_tag("rating[value]", 2, current_user_rating(book.id) == 2,
:class => 'rating_button', :id => "rating_#{sfx}") %>
<% sfx = "value_#{book.id}_3" %>
<%= f.label(sfx, content_tag(:span, '3'), :class => "rating") %>
<%= radio_button_tag("rating[value]", 3, current_user_rating(book.id) == 3,
:class => 'rating_button', :id => "rating_#{sfx}") %>
<% sfx = "value_#{book.id}_4" %>
<%= f.label(sfx, content_tag(:span, '4'), :class => "rating") %>
<%= radio_button_tag("rating[value]", 4, current_user_rating(book.id) == 4,
:class => 'rating_button', :id => "rating_#{sfx}") %>
<% sfx = "value_#{book.id}_5" %>
<%= f.label(sfx, content_tag(:span, '5'), :class => "rating") %>
<%= radio_button_tag("rating[value]", 5, current_user_rating(book.id) == 5,
:class => 'rating_button', :id => "rating_#{sfx}") %>
<%= hidden_field_tag("book_id", book.id) %>
<%= f.submit :Submit, style: "display: none" %>
<% end %>
create.js.erb and update.js.erb:
$('#book_<%= @book.id%> #rating').html("<%= escape_javascript(render :partial => 'ratings/rating', :locals => {:book => @book}) %>");
Helpers:
module BooksHelper
def rating_ballot(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
@rating
else
current_user.ratings.new
end
end
def current_user_rating(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
@rating.value
end
end
end
HTML CODE IN DEVELOPER TOOLS
index.html.erb
<table class="table" id="book_1176">...</table>
<table class="table" id="book_1177">...</table>
<table class="table" id="book_1178">...</table>
<table class="table" id="book_1179">...</table>
<table class="table" id="book_1176">
<tbody>
<tr>
<td id="rating">
<form accept-charset="UTF-8" action="/ratings/1093" class="rating_ballot" data-remote="true" id="edit_rating_1093" method="post">
<div style="margin:0;padding:0;display:inline" class="bright">
<input name="utf8" type="hidden" value="✓"><input name="_method" type="hidden" value="put">
<input name="authenticity_token" type="hidden" value="JjueXU5L/l3qgl8y1CHBEvJWrgJ2DDfN712gGH6ciBM="></div>
<label class="rating bright" for="rating_value_1176_1"><span>1</span></label>
<input class="rating_button #{bright?(i, book.id)} bright" id="rating_value_1176_1" name="rating[value]" type="radio" value="1">
<label class="rating bright" for="rating_value_1176_2"><span>2</span></label>
<input class="rating_button #{bright?(i, book.id)} bright" id="rating_value_1176_2" name="rating[value]" type="radio" value="2">
<label class="rating bright" for="rating_value_1176_3"><span>3</span></label>
<input class="rating_button #{bright?(i, book.id)} bright" id="rating_value_1176_3" name="rating[value]" type="radio" value="3">
<label class="rating bright" for="rating_value_1176_4"><span>4</span></label>
<input checked="checked" class="rating_button #{bright?(i, book.id)} bright" id="rating_value_1176_4" name="rating[value]" type="radio" value="4">
<label class="rating" for="rating_value_1176_5"><span>5</span></label>
<input class="rating_button #{bright?(i, book.id)}" id="rating_value_1176_5" name="rating[value]" type="radio" value="5">
<input id="book_id" name="book_id" type="hidden" value="1176">
<input name="commit" style="display: none" type="submit" value="Submit">
</form>
</td>
</tr>
</tbody>
</table>
Upvotes: 0
Views: 238
Reputation: 76784
Apologies if this does not solve the issue directly:
CSS
The way you get the stars to light-up when they have been "valued" is to give them some sort of class over-and-above the classes they load with
Your JS does this for you:
$('form.rating_ballot > label').click(function() {
$(this).siblings().removeClass("bright");
$(this).prevAll().andSelf().addClass("bright");
});
The problem I can see if you reload the page, there is no method adding the bright
class to your values
This is compounded by the fact you're submitting your page (and therefore reloading it) when you click a star. If this was in Ajax, it wouldn't seem like a problem (although it will still exist)
Fix
I would try this:
<%= form_for(rating_ballot(book.id), remote: true, :html => { :class => 'rating_ballot' }) do |f| %>
<% [1..5].each do |i| %>
<% sfx = "value_#{book.id}_#{i}" %>
<%= f.label(sfx, content_tag(:span, i), :class => "rating") %>
<%= radio_button_tag("rating[value]", i, current_user_rating(book.id) == i,
:class => 'rating_button #{bright?(i, book.id)}', :id => "rating_#{sfx}") %>
<% end %>
<%= hidden_field_tag("book_id", book.id) %>
<%= f.submit :Submit, style: "display: none" %>
<% end %>
module BooksHelper
def rating_ballot(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
@rating
else
current_user.ratings.new
end
end
def current_user_rating(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
@rating.value
end
end
def bright?(val, book_id)
if(current_user_rating(book_id) < val)
"bright"
end
end
end
Upvotes: 2