1

I have rating-stars, using foreach need to addClass depends on the value been passed from the model. i.e. if 2 (then first 2 stars class rated is applied)

 foreach (var rev in Model.Reviews)
 {
   <p class="rating">  
   <span id="5" class="fa fa-star"></span>
   <span id="4" class="fa fa-star"></span>
   <span id="3" class="fa fa-star"></span>
   <span id="2" class="fa fa-star"></span>
   <span id="1" class="fa fa-star"></span>
   </p>

   <script>
       apply(@rev.Rating);
   </script>
 }

apply function:

 <script type="text/javascript">
           function apply(r) {
               $('.rating span').each(function () {
                    if (this.id <= r) {
                        $(this).addClass("rated");
                    }
                });
            }
  </script>

The problem for example: when rev.Rating is 2, the addClass is applied correctly to two ids. But then when next value is 4 it overrides the first and it applies addClass to 4 stars and then next is 4 stars.

the issue it overrides the previous stars with the current model value.

I think because the p class="rating" is the same. But I thought if I pass (this) current reference it shouldt override the other elements. Any ideas why? and How I can fix it.

using this code inside a view, using MVC

6
  • 1
    What else are you using, since the above block isn't valid js to my knowledge? Commented Aug 18, 2015 at 0:58
  • this code is inside a view. Using MVC. Commented Aug 18, 2015 at 0:59
  • @Ron I believe it's called JavaScriptMVC. Commented Aug 18, 2015 at 1:01
  • 1
    issue: you have for each review, id's 1-5, which will lead the document to be populated with many id's and that's not valid html Commented Aug 18, 2015 at 1:02
  • 1
    @Ron MVC means Model/View/Controller, we'll need the specific library please. Commented Aug 18, 2015 at 1:02

1 Answer 1

1

Yes the problem is your use of apply method, you can have a single dom ready callback which will update the rated class like below.

In each rating element, you can store its initial value using a data-* value, which can be used in a dom ready handler after the loop.

Also since ID of an element must be unique, you can use another data-* attribute to store the value of the span

jQuery(function($) {
  $('.rating').each(function() {
    $(this).find('span').slice(-$(this).data('default-value')).addClass("rated");
  });
})
.rated {
  border: 1px solid red;
}
<p class="rating" data-default-value="2">
  <!-- data-default-value="@rev.Rating" -->
  <span data-value="5" class="fa fa-star"></span>
  <span data-value="4" class="fa fa-star"></span>
  <span data-value="3" class="fa fa-star"></span>
  <span data-value="2" class="fa fa-star"></span>
  <span data-value="1" class="fa fa-star"></span>
</p>
<p class="rating" data-default-value="4">
  <span data-value="5" class="fa fa-star"></span>
  <span data-value="4" class="fa fa-star"></span>
  <span data-value="3" class="fa fa-star"></span>
  <span data-value="2" class="fa fa-star"></span>
  <span data-value="1" class="fa fa-star"></span>
</p>


So

foreach (var rev in Model.Reviews)
 {
   <p class="rating" data-default-value="@rev.Rating"> 
       <span id="5" class="fa fa-star"></span>
       <span id="4" class="fa fa-star"></span>
       <span id="3" class="fa fa-star"></span>
       <span id="2" class="fa fa-star"></span>
       <span id="1" class="fa fa-star"></span>
   </p>
 }
<script>
    jQuery(function ($) {
        $('.rating').each(function () {
            $(this).find('span').slice(-$(this).data('default-value')).addClass("rated");
        });
    })
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

This is a great alternative solution.
Awesome! Many Thanks! Didnt know about slice method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.