Question

I've created a rating system using Angular-UI. The number of stars displayed come from a variable called max. I'm able to show this variable inside an input using ng-model, but once I modify it, it won't change the number of stars.

You can see what I mean in this Plunker.

Here's the relevant js:

.directive('myRating', function() {
  return {
    restrict: 'E',
    template: '<div> \
         <div class="row rating" ng-controller="RatingDemoCtrl"> \
           <rating value="rate" max="max" readonly="isReadonly" state-on="\'glyphicon-star rated\'" state-off="\'glyphicon-star\'"></rating> <a class="glyphicon glyphicon-pencil" ng-show="editMode" ng-click="editStars = !editStars"></a>\
            <input ng-if="editStars" type="text" class="form-control" ng-model="max" /> \
         </div> \
      </div>',
    replace: true,
  };
});

var RatingDemoCtrl = function ($scope) {
  $scope.rate = 0;
  $scope.max = 10;
  $scope.isReadonly = false;

  $scope.hoveringOver = function(value) {
    $scope.overStar = value;
    $scope.percent = 100 * (value / $scope.max);
  };
};

The ng-model is working correctly as it will show the value of max every time, but it won't modify it in real time.

Any ideas?

Was it helpful?

Solution

It is totally doable. Copy down the ui-bootstrap code and alter it a little bit. I hacked inside and it seems to be working great. Check out a working PLUNKER. Here are the changes I made, they can be seen on lines 2493-2559.

First I went into the directive and added maxRange as a two-way bound object

scope: {
  value: '=',
  onHover: '&',
  onLeave: '&',
  maxRange: '=max'
},

Then I went into the controller and changed a few things so I could watch the maxRange value and update the objects based on that.

$scope.$watch('maxRange', function() {
  $scope.range = createRateObjects(new Array(parseInt($scope.maxRange)));
});

Hacking rocks. Don't be afraid to modify other people's code a little bit if it doesn't fit your needs!

OTHER TIPS

I've just quickly looked over this problem and it seems like the AngularJS Bootstrap Rating directive doesn't handle updating the max value on the fly.

I accidentally found another hack for this:

Wrapping your rating-directive in a ng-if also seems to work.

<div ng-if="true">
  <rating max="myVar"></rating>
</div>

According to the angular documentation, ng-if will reinsert the HTML on each evaluation, triggering a re-evaluation of myVar.

Yes, it is still a bit hacky, but I think it is prettier than changing code in your bower_components-folder which will be overwritter on each update.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top