create a decimal star rating for a comment in angularjs

て烟熏妆下的殇ゞ 提交于 2020-01-14 14:45:10

问题


Here is a code which present star rating code in angularjs. In some point I need to have a average of all the rating in whole the system so instead of rate:2 , i will have 2.4 . In such case i am interesting to present 2 star which are complete fill and one which has only half filled. How can I change my code in order to add this functionality? Moreover, initially I would like to don't specify any star filled. That's also need a modification which I am not sure how should be done?

<div ng-app="app" ng-controller="RatingCtrl" class="container">
  <h1>Angular Star Rating Directive</h1>
  <div star-rating ng-model="rating1" max="10" on-rating-selected="rateFunction(rating)"></div>
  <star-rating ng-model="rating2" readonly="isReadonly"></star-rating>
  <label>
    <input type="checkbox" ng-model="isReadonly" /> Is Readonly
  </label>

  <div><strong>Rating 1:</strong> {{rating1}}</div>
  <div><strong>Rating 2:</strong> {{rating2}}</div>
</div>

In my directive

angular.module("app", [])
.controller("RatingCtrl", function($scope) {
  $scope.rating1 = 1;
  $scope.rating2 = 2;
  $scope.isReadonly = true;
  $scope.rateFunction = function(rating) {
    console.log("Rating selected: " + rating);
  };
})
.directive("starRating", function() {
  return {
    restrict : "EA",
    template : "<ul class='rating' ng-class='{readonly: readonly}'>" +
               "  <li ng-repeat='star in stars' ng-class='star' ng-click='toggle($index)'>" +
               "    <i class='fa fa-star'></i>" + //&#9733
               "  </li>" +
               "</ul>",
    scope : {
      ratingValue : "=ngModel",
      max : "=?", //optional: default is 5
      onRatingSelected : "&?",
      readonly: "=?"
    },
    link : function(scope, elem, attrs) {
      if (scope.max == undefined) { scope.max = 5; }
      function updateStars() {
        scope.stars = [];
        for (var i = 0; i < scope.max; i++) {
          scope.stars.push({
            filled : i < scope.ratingValue
          });
        }
      };
      scope.toggle = function(index) {
        if (scope.readonly == undefined || scope.readonly == false){
          scope.ratingValue = index + 1;
          scope.onRatingSelected({
            rating: index + 1
          });
        }
      };
      scope.$watch("ratingValue", function(oldVal, newVal) {
        if (newVal) { updateStars(); }
      });
    }
  };
});

and css

.rating {
  margin: 0;
  padding: 0;
  display: inline-block;
}
.rating li {
  padding: 1px;
  color: #ddd;
  font-size: 20px;
  text-shadow: .05em .05em #aaa;
  list-style-type: none;
  display: inline-block;
  cursor: pointer;
}
.rating li.filled {
  color: #fd0;
}
.rating.readonly li.filled {
  color: #666;
}

http://codepen.io/anon/pen/RPLJYW

Thank you for any help.


回答1:


You could use two identical set of stars to achieve this, position absolute one on top of the other. One fills your background star shapes (gray) and the one position at the top will represent your fill.

The top set of stars are all filled but its container's width can be adjusted to the proportion of stars representing your rate.

var score = 2.4;
var maxStars = 5;
var starContainerMaxWidth = 100; //pixls
var filledInStarsContainerWidth = score / maxStars * starsMaxWidth;

A CSS overflow hidden will hide the portion of stars that are not turned on, in effect allowing you to show 2.4 stars filled.

Update:

I have bashed a quick example http://codepen.io/anon/pen/NqazVa , will need some tidy up and reshuffling but the average rate is calculated and displayed correctly.




回答2:


Check the AngularUI Bootstrap Rating component.

http://angular-ui.github.io/bootstrap/#/rating



来源:https://stackoverflow.com/questions/30956488/create-a-decimal-star-rating-for-a-comment-in-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!