Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(rating): plug into ngModel controller
Browse files Browse the repository at this point in the history
Closes #1546

BREAKING CHANGE: `rating` is now integrated with `ngModelController`.
 * `value` is replaced from `ng-model`.

  Before:

  <rating value="rate" ...></rating>

  After:

  <rating ng-model="rate" ...></rating>
  • Loading branch information
bekos authored and pkozlowski-opensource committed Jan 13, 2014
1 parent d65901c commit 47e227f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 27 deletions.
6 changes: 3 additions & 3 deletions src/rating/docs/demo.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div ng-controller="RatingDemoCtrl">
<h4>Default</h4>
<rating value="rate" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
<rating ng-model="rate" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
<span class="label" ng-class="{'label-warning': percent<30, 'label-info': percent>=30 && percent<70, 'label-success': percent>=70}" ng-show="overStar && !isReadonly">{{percent}}%</span>

<pre style="margin:15px 0;">Rate: <b>{{rate}}</b> - Readonly is: <i>{{isReadonly}}</i> - Hovering over: <b>{{overStar || "none"}}</b></pre>
Expand All @@ -10,6 +10,6 @@ <h4>Default</h4>
<hr />

<h4>Custom icons</h4>
<div ng-init="x = 5"><rating value="x" max="15" state-on="'glyphicon-ok-sign'" state-off="'glyphicon-ok-circle'"></rating> <b>(<i>Rate:</i> {{x}})</b></div>
<div ng-init="y = 2"><rating value="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
<div ng-init="x = 5"><rating ng-model="x" max="15" state-on="'glyphicon-ok-sign'" state-off="'glyphicon-ok-circle'"></rating> <b>(<i>Rate:</i> {{x}})</b></div>
<div ng-init="y = 2"><rating ng-model="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
</div>
5 changes: 3 additions & 2 deletions src/rating/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ Rating directive that will take care of visualising a star rating bar.

#### `<rating>` ####

* `value` <i class="glyphicon glyphicon-eye-open"></i>
<<<<<<< HEAD

This comment has been minimized.

Copy link
@campersau

campersau Jan 13, 2014

Leftover from a merge?

This comment has been minimized.

Copy link
@pkozlowski-opensource

pkozlowski-opensource Jan 13, 2014

Member

Grr, thnx @campersau!

* `ng-model` <i class="glyphicon glyphicon-eye-open"></i>
:
The current rate.

* `max`
_(Defaults: 5)_ :
Changes the number of icons.

* `readonly`
* `readonly` <i class="icon-eye-open"></i>
_(Defaults: false)_ :
Prevent user's interaction.

Expand Down
41 changes: 28 additions & 13 deletions src/rating/rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,22 @@ angular.module('ui.bootstrap.rating', [])
})

.controller('RatingController', ['$scope', '$attrs', '$parse', 'ratingConfig', function($scope, $attrs, $parse, ratingConfig) {
var ngModelCtrl = {$setViewValue: angular.noop};

this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;

this.init = function(ngModelCtrl_) {
ngModelCtrl = ngModelCtrl_;
ngModelCtrl.$render = this.render;

$scope.range = this.buildTemplateObjects(
angular.isDefined($attrs.ratingStates) ? $scope.$parent.$eval($attrs.ratingStates) : new Array(this.maxRange)
);
};

this.createRateObjects = function(states) {
this.buildTemplateObjects = function(states) {
var defaultOptions = {
stateOn: this.stateOn,
stateOff: this.stateOff
Expand All @@ -24,12 +34,10 @@ angular.module('ui.bootstrap.rating', [])
return states;
};

// Get objects used in template
$scope.range = angular.isDefined($attrs.ratingStates) ? this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));

$scope.rate = function(value) {
if ( $scope.value !== value && !$scope.readonly ) {
$scope.value = value;
if ( !$scope.readonly ) {
ngModelCtrl.$setViewValue(value);
ngModelCtrl.$render();
}
};

Expand All @@ -41,13 +49,13 @@ angular.module('ui.bootstrap.rating', [])
};

$scope.reset = function() {
$scope.val = angular.copy($scope.value);
$scope.val = ngModelCtrl.$viewValue;
$scope.onLeave();
};

$scope.$watch('value', function(value) {
$scope.val = value;
});
this.render = function() {
$scope.val = ngModelCtrl.$viewValue;
};

$scope.readonly = false;
if ($attrs.readonly) {
Expand All @@ -60,13 +68,20 @@ angular.module('ui.bootstrap.rating', [])
.directive('rating', function() {
return {
restrict: 'EA',
require: ['rating', 'ngModel'],
scope: {
value: '=',
onHover: '&',
onLeave: '&'
},
controller: 'RatingController',
templateUrl: 'template/rating/rating.html',
replace: true
replace: true,
link: function(scope, element, attrs, ctrls) {
var ratingCtrl = ctrls[0], ngModelCtrl = ctrls[1];

if ( ngModelCtrl ) {
ratingCtrl.init( ngModelCtrl );
}
}
};
});
18 changes: 9 additions & 9 deletions src/rating/test/rating.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('rating directive', function () {
$compile = _$compile_;
$rootScope = _$rootScope_;
$rootScope.rate = 3;
element = $compile('<rating value="rate"></rating>')($rootScope);
element = $compile('<rating ng-model="rate"></rating>')($rootScope);
$rootScope.$digest();
}));

Expand Down Expand Up @@ -71,22 +71,22 @@ describe('rating directive', function () {
});

it('shows different number of icons when `max` attribute is set', function() {
element = $compile('<rating value="rate" max="7"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" max="7"></rating>')($rootScope);
$rootScope.$digest();

expect(getStars().length).toBe(7);
});

it('shows different number of icons when `max` attribute is from scope variable', function() {
$rootScope.max = 15;
element = $compile('<rating value="rate" max="max"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" max="max"></rating>')($rootScope);
$rootScope.$digest();
expect(getStars().length).toBe(15);
});

it('handles readonly attribute', function() {
$rootScope.isReadonly = true;
element = $compile('<rating value="rate" readonly="isReadonly"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" readonly="isReadonly"></rating>')($rootScope);
$rootScope.$digest();

expect(getState()).toEqual([true, true, true, false, false]);
Expand All @@ -106,7 +106,7 @@ describe('rating directive', function () {

it('should fire onHover', function() {
$rootScope.hoveringOver = jasmine.createSpy('hoveringOver');
element = $compile('<rating value="rate" on-hover="hoveringOver(value)"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" on-hover="hoveringOver(value)"></rating>')($rootScope);
$rootScope.$digest();

getStar(3).trigger('mouseover');
Expand All @@ -116,7 +116,7 @@ describe('rating directive', function () {

it('should fire onLeave', function() {
$rootScope.leaving = jasmine.createSpy('leaving');
element = $compile('<rating value="rate" on-leave="leaving()"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" on-leave="leaving()"></rating>')($rootScope);
$rootScope.$digest();

element.trigger('mouseleave');
Expand All @@ -128,7 +128,7 @@ describe('rating directive', function () {
beforeEach(inject(function() {
$rootScope.classOn = 'icon-ok-sign';
$rootScope.classOff = 'icon-ok-circle';
element = $compile('<rating value="rate" state-on="classOn" state-off="classOff"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" state-on="classOn" state-off="classOff"></rating>')($rootScope);
$rootScope.$digest();
}));

Expand All @@ -145,7 +145,7 @@ describe('rating directive', function () {
{stateOn: 'heart'},
{stateOff: 'off'}
];
element = $compile('<rating value="rate" rating-states="states"></rating>')($rootScope);
element = $compile('<rating ng-model="rate" rating-states="states"></rating>')($rootScope);
$rootScope.$digest();
}));

Expand Down Expand Up @@ -175,7 +175,7 @@ describe('rating directive', function () {
ratingConfig.max = 10;
ratingConfig.stateOn = 'on';
ratingConfig.stateOff = 'off';
element = $compile('<rating value="rate"></rating>')($rootScope);
element = $compile('<rating ng-model="rate"></rating>')($rootScope);
$rootScope.$digest();
}));
afterEach(inject(function(ratingConfig) {
Expand Down

0 comments on commit 47e227f

Please sign in to comment.