Friday 21 March 2014

Rating stars in angular js using directive

Here I am going to explain how to create rating feature using angular js directive concept and send the rating value to backend ( service ). I have explained same using Angular 2(+) concept as well, if you want to compare both implementation check this link as well.

Refer this link to know how it is implemented in Angular 2(+):- Rating star component using Angular 2(+).

Angular js 1 Directive


 
angular.module('samplemodule').directive('starRating',
function() {
return {
restrict : 'A',
template : '<ul class="rating">'
   + ' <li ng-repeat="star in stars" 
   ng-class="star" ng-click="toggle($index)">'
   + '  <i class="fa fa-star-o"></i>'
   + ' </li>'
   + '</ul>',
scope : {
 ratingValue : '=',
 max : '=',
 onRatingSelected : '&'
},
link : function(scope, elem, attrs) {
 var updateStars = function() {
  scope.stars = [];
  for ( var i = 0; i < scope.max; i++) {
   scope.stars.push({
    filled : i < scope.ratingValue
   });
  }
 };
 
 scope.toggle = function(index) {
  scope.ratingValue = index + 1;
  scope.onRatingSelected({
   rating : index + 1
  });
 };
 
 scope.$watch('ratingValue',
  function(oldVal, newVal) {
   if (newVal) {
    updateStars();
   }
  }
 );
}
};
}
);


Here i used Font awesome icon ( <i class="fa fa-star-o"></i> ).Font Awesome gives you scalable vector icons that can instantly be customized — size, color, drop shadow, and anything that can be done with the power of CSS.
Font awsome icons
You can improve the performance of your site by using font awesome images.

View

 
 
<div ng-init="rating = star.rating + 1"></div>

<div class="star-rating" star-rating rating-value="rating"

 data-max="10" on-rating-selected="rateFunction(rating)"></div>
 

Only for displaying the rating you can use the class as star-rating.Here i am going to explain how to send this rating to backend (Service).

Controller

 
    
$scope.rateFunction = function( rating )
{
       var _url = 'your service url';
 
 var data = {
   rating: rating
 };
 
 $http.post( _url, angular.toJson(data), {cache: false} )
  .success( function( data )
  {
   success(data);
  })
  .error(function(data){
    error(data);
  });
 
};
 
 

CSS

Using this "filled" class we are changing the color of the rated stars .

 

.rating .filled {
color: #21568b;
}

Demo

Play in fiddle

Directives are markers on a DOM element that tell AngularJS's HTML compiler to attach a specified behavior to that DOM element or even transform the DOM element and its children. Better define all Global controllers in Directives. Ex: Warning message, alert etc.

'A' - Attribute (Use it as <div starrating>)

'E' - Element (Use it as <starrating>)

'C' - Class. (Use it as <div class="starrating">)

'M' - Comment (Use it as <!- directive: starrating -> )

We used watch concept in directive .Watch is a powerful feature of angular js. “$watch” concept in Angular is to observe the changes on the data of the scope from the controller. That is controller can add a listener on an attribute of its scope.

Related Posts

1. Communicate with controllers in angular js

2. Angular routing

3. Loop concept in angular js

4. Filtering concept in angular js

5. Save highchart as binary image


44 comments :

  1. Thank you ...

    It works for me .

    ReplyDelete
  2. Hi ,

    Is there any way to remove the the first star which is by default selected .I want none of the stars to be selected initially.

    ReplyDelete
    Replies
    1. star.rating-1 instead of star.rating+1 in your html

      Delete
    2. Hi Prashobh PS
      What it takes to become the votes recorded, and may have an overall average with the votes of each stored users?
      What should I put in: 'your service url' ?

      Thanks

      Delete
    3. "your service url" is nothing but your webservice call .

      You will be getting count in $scope.rateFunction ,here you can do your logic to calculate average and all

      Delete
  3. Hi ,

    Is there any way to show star from selected value which is get from angular service from e.g
    {{feedback.feedback.rating}} (Getting from mongoDB Database)

    ReplyDelete
    Replies
    1. yes .
      div ng-init="rating = star.rating
      Here you can assign the dynamic value(1,2,3 etc ).

      Delete
  4. Its awesome post! Thank you!

    ReplyDelete
  5. ill give separate partial for that ..But i have error"+"+".

    ReplyDelete
  6. Great directive!
    How can i use multipile rating in one page?

    Thanks

    ReplyDelete
  7. its Nice, but i want smiles insted of stars.
    how i get it?

    ReplyDelete
    Replies
    1. "fa fa-star-o" here I used font awesome icon ,instead of use whatever the image you want .

      Delete
  8. Awesome !!

    But i need this in tooltip??

    ReplyDelete
  9. when i click on star the star getting selected but controller function not called
    on-rating-selected="rateFunction(rating)"

    Not called in my application why?

    ReplyDelete
    Replies
    1. it is working for me ,if you can share a fiddle i can check

      Delete
  10. Hi... I am new user of angularjs

    you'd use some attributes in HTML like star-rating, rating-value, on-rating-selected so I've to ask one question is that where you define or declare all those attributes, I'd didn't found any declaration or definition for such above mentioned attributes...

    ReplyDelete
    Replies
    1. star-rating is the directive name (starRating) ,rating-value and on-rating-selected you can see inside directive (scope.ratingValue , scope.onRatingSelected).
      Hope it clears your doubt

      Delete
  11. Hi,
    How to fill if rating value is 4.333, have to fill exact value.Can anyone pls suggest.
    Thanks,
    Siva

    ReplyDelete
  12. How can i make any star rating static or read only for any current or max value?? Please reply soon .. Urgently needed....

    ReplyDelete
    Replies
    1. you can try with angular ng-disabled or use any css properties like pointer-event :none ect

      Delete
    2. remove `ng-click="toggle($index)" ` in directive template. that will automatically disable the user to click it

      Delete
  13. Would this work for Internet Explorer too ?
    The star image is not being displayed, only its {{value}}. Eg. {{5}}

    ReplyDelete
    Replies
    1. it should work for ie9 and above ,I didn't test on ie8 and below.I used font awesome image ,you can try with any other

      Delete
  14. What should I do, if I want hover for the stars?? Can you help please...

    ReplyDelete
    Replies
    1. simply add title on the html
      li title="somthing" -> directive template html

      Delete
    2. Can you please add fiddle, I am new to angularjs.

      Delete
    3. Fiddle is available already ,you can play with that.

      Delete
    4. I did it, but I want to hover on stars like in normal star rating hover.

      Delete
  15. This comment has been removed by the author.

    ReplyDelete
  16. Hi,
    Really nice directive and I appreciate your work also.
    I do need to implement it in mobile devices i.e stars would be filled on Touch.

    Can u plz suggest me how to change directive so that it toggle() function can be called on touch instead of ng-click.

    Thanks..

    ReplyDelete
  17. Good post. I really like your post. I like the way you describing this post. Its really informative for the followers.Thanks for sharing this awesome post.
    Application Development using Angularjs

    ReplyDelete
  18. Hi is there a way to present as half star such as a 3.5 which would related to 3 stars and a half???
    Can someone guide me if there is a how-to?

    ReplyDelete
  19. Hi is there a way to display a half star such as 3 stars and a half (3.5) ??

    ReplyDelete
  20. Some times it doesn't updates or even doesn't shows rating if ratingValue is 0
    Just update:
    scope.$watch('ratingValue',
    function(oldVal, newVal) {
    if (newVal || newValue == 0) {
    updateStars();
    }
    }
    );

    ReplyDelete
  21. The oldVal and newVal parameters on your watch function are reversed. The newValue parameter should come first and the oldValue should come second. You can see that this causes issues if you start with a rating of 0 or null.

    ReplyDelete
  22. CSS for make stars hoover

    .rating {
    color: lightgrey;
    margin: 0;
    padding: 0;
    font-size: 30px;
    }

    ul.rating {
    display: inline-block;
    }

    .rating li {
    list-style-type: none;
    display: inline-block;
    padding: 1px;
    text-align: center;
    font-weight: bold;
    cursor: pointer;
    }

    .rating .filled {

    color: #f44336;
    font-size: 30px;
    }


    .star-rating:hover li {
    /*color: #f39c12;*/
    color: #f44336; /* amarillo (seleccionado) */
    }

    .star-rating:hover li:hover~li {
    color: lightgrey; /* gris (normal) */
    }

    ReplyDelete
  23. how do i record that star rating in a log file...

    ReplyDelete
    Replies
    1. "$scope.rateFunction" This method will give selected count.

      Delete