Serge Pedroza
Serge Pedroza

Reputation: 2170

JavaScript stars aren't glowing after I've clicked a star?

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

Code before I open a table

<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>

Code After I open a 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

Answers (1)

Richard Peck
Richard Peck

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

Related Questions