Rohit Verma
Rohit Verma

Reputation: 3785

How to make star ratting using jQuery?

Actually i'm trying to make a star rating but i'm not able to understand how to make it properly. What is best way to make it?

What i tried:-

$(document).ready(function(){
        $('.ratingUl li').mouseover(function(){
          $(this).find('i').addClass('bg-yellow');
        });

        $('.ratingUl li').mouseout(function(){
//          $(this).find('i').removeClass('bg-yellow');
        });

        $('.ratingUl li').click(function(){
            $(this).find('i').addClass('bg-yellow');
          var ratedValue =  $(this).find('i').attr('value');
        });
    });
  .position-relative{ position: relative;}
  .ratingUl{ margin: 0px; padding: 0px;}
  .ratingUl li{ list-style: none; display: inline;}
  .bg-yellow{ color:orange;}
  .hide{ display: none;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
  
<div class="container p-5">
<ul class="ratingUl">
<li> <i class="fas fa-star" value="1"></i>  </li>
<li> <i class="fas fa-star" value="2"></i>  </li>
<li> <i class="fas fa-star" value="3"></i>  </li>
<li> <i class="fas fa-star" value="4"></i>  </li>
<li> <i class="fas fa-star" value="5"></i>  </li>
</ul>
</div>

Upvotes: 1

Views: 224

Answers (3)

David
David

Reputation: 7295

The standard behavior is, when the user trigger a mouseover event over a start, to mark that one and all the previous ones and to unmark the rest of them.

  • Use .prevAll() to select the siblings before the current start.
  • Use .addBack() to include the current one in the selection.
  • Use .nextAll() to find the rest of them.

$(document).ready(function(){
        $('.ratingUl li').mouseover(function(){
          $(this).prevAll().addBack().find('i').addClass('bg-yellow');
          $(this).nextAll().find('i').removeClass('bg-yellow');
          console.log( $('.ratingUl li i.bg-yellow').length );
        });
    });
.position-relative{ position: relative;}
  .ratingUl{ margin: 0px; padding: 0px;}
  .ratingUl li{ list-style: none; display: inline;}
  .bg-yellow{ color:orange;}
  .hide{ display: none;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
  
<div class="container p-5">
<ul class="ratingUl">
<li> <i class="fas fa-star" value="1"></i>  </li>
<li> <i class="fas fa-star" value="2"></i>  </li>
<li> <i class="fas fa-star" value="3"></i>  </li>
<li> <i class="fas fa-star" value="4"></i>  </li>
<li> <i class="fas fa-star" value="5"></i>  </li>
</ul>
</div>

How to get the value of the last selected start?

I would do it in a different way: just count how many starts have the .bg-yellow class applied.

console.log( $('.ratingUl li i.bg-yellow').length );

Upvotes: 2

Sandro Schaurer
Sandro Schaurer

Reputation: 417

You can try it like this for CSS:

<style>
    #star-rating li {
        display: inline-block;
    }

    #star1:hover, #star2:hover, #star3:hover, #star4:hover, #star5:hover,
    #star2:hover ~ #star1, #star3:hover ~ #star1, #star3:hover ~ #star2, 
    #star4:hover ~ #star1, #star4:hover ~ #star2, #star4:hover ~ #star3, 
    #star5:hover ~ #star1, #star5:hover ~ #star2, #star5:hover ~ #star3, 
    #star5:hover ~ #star4 {
        color: orange;
    }
</style>

HTML:

<ul id="star-rating">
    <li><span onclick="testfunc(1)"><i id="star1" class="fas fa-star"></i></span></li>
    <li><span onclick="testfunc(2)"><i id="star2" class="fas fa-star"></i></span></li>
    <li><span onclick="testfunc(3)"><i id="star3" class="fas fa-star"></i></span></li>
    <li><span onclick="testfunc(4)"><i id="star4" class="fas fa-star"></i></span></li>
    <li><span onclick="testfunc(5)"><i id="star5" class="fas fa-star"></i></span></li>
</ul>

JS:

<script>
    starValue => {
        alert('Star Rating Selected: ' + starValue);
    }
</script>

Should work :)

If not you can replace the '~' in CSS by '+'

Upvotes: 0

Malith
Malith

Reputation: 980

You can do it this way. I created small plugin for this. you can find it here.

Demo : https://malithmcr.github.io/Better-Rating/

Download : https://github.com/malithmcr/Better-Rating

;(function($){
$.fn.extend({
    betterRating: function( options ) {
        /**
         * @option : wrapper - rating list wrapper div
         * @option : icon - fontAwesome icon name
         */
        this.defaultOptions = {
            wrapper: '#list',
            icon: 'fa fa-star',
        };
        var settings = $.extend({}, this.defaultOptions, options);
        this.getRating(settings);
        return this.each(function() {
            var $this = $(this);
        });
    },
    getRating: function(settings) {
            var self = this;

            $('.rating i').on('click', function(){
                $('#rating-count').val($(this).data('rate'));
                $(this).parent().find('i:lt(' + ($(this).index() + 1) + ')').addClass('selected');
            });

            $('.rating i').on('mouseover', function(){
                $(this).parent().children('.rating i').each(function(e){
                    $(this).removeClass('selected');
                  });
                $(this).parent().find('i:lt(' + ($(this).index() + 1) + ')').addClass('hover');
              }).on('mouseout', function(){
                $(this).parent().children('.rating i').each(function(e){
                  $(this).removeClass('hover');
                });
              });

            $(this).submit(function( event ) {
                event.preventDefault();
                var formData = $(this).serializeArray();
                console.log(formData);

                $('#better-rating-list').append(self.template(formData));
            });

    },

    /** creation of the list template*/
    template: function(data) {
            var rating = '<i class="fa fa-star selected" data-rate="1"></i>';
            for(var i =1; i < data[1].value; i++) {
                rating += '<i class="fa fa-star selected" data-rate="1"></i>';
            }
            var list = '<li>';
            list += '<div class="profile-rating-wrapper">';
            list += ' <div class="profile-pic"><img src="images/profile_pic.png" alt="" /></div>';
            list += '<div class="name">'+data[0].value+' Wrote:</div>';
            list += '<div class="rating">'
            list += rating;
            list += '</div>';
            list += '</div>';
            list += '<div class="content">';
            list += '<p>'+data[2].value+'</p>';
            list += '</div>';
            list += '</li>';
            return list;
    }

});

Upvotes: 1

Related Questions