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

Commit 47e227f

Browse files
bekospkozlowski-opensource
authored andcommitted
feat(rating): plug into ngModel controller
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>
1 parent d65901c commit 47e227f

File tree

4 files changed

+43
-27
lines changed

4 files changed

+43
-27
lines changed

src/rating/docs/demo.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div ng-controller="RatingDemoCtrl">
22
<h4>Default</h4>
3-
<rating value="rate" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
3+
<rating ng-model="rate" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
44
<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>
55

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

1212
<h4>Custom icons</h4>
13-
<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>
14-
<div ng-init="y = 2"><rating value="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
13+
<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>
14+
<div ng-init="y = 2"><rating ng-model="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
1515
</div>

src/rating/docs/readme.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ Rating directive that will take care of visualising a star rating bar.
44

55
#### `<rating>` ####
66

7-
* `value` <i class="glyphicon glyphicon-eye-open"></i>
7+
<<<<<<< HEAD
8+
* `ng-model` <i class="glyphicon glyphicon-eye-open"></i>
89
:
910
The current rate.
1011

1112
* `max`
1213
_(Defaults: 5)_ :
1314
Changes the number of icons.
1415

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

src/rating/rating.js

+28-13
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,22 @@ angular.module('ui.bootstrap.rating', [])
77
})
88

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

1112
this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
1213
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
1314
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
15+
16+
this.init = function(ngModelCtrl_) {
17+
ngModelCtrl = ngModelCtrl_;
18+
ngModelCtrl.$render = this.render;
19+
20+
$scope.range = this.buildTemplateObjects(
21+
angular.isDefined($attrs.ratingStates) ? $scope.$parent.$eval($attrs.ratingStates) : new Array(this.maxRange)
22+
);
23+
};
1424

15-
this.createRateObjects = function(states) {
25+
this.buildTemplateObjects = function(states) {
1626
var defaultOptions = {
1727
stateOn: this.stateOn,
1828
stateOff: this.stateOff
@@ -24,12 +34,10 @@ angular.module('ui.bootstrap.rating', [])
2434
return states;
2535
};
2636

27-
// Get objects used in template
28-
$scope.range = angular.isDefined($attrs.ratingStates) ? this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));
29-
3037
$scope.rate = function(value) {
31-
if ( $scope.value !== value && !$scope.readonly ) {
32-
$scope.value = value;
38+
if ( !$scope.readonly ) {
39+
ngModelCtrl.$setViewValue(value);
40+
ngModelCtrl.$render();
3341
}
3442
};
3543

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

4351
$scope.reset = function() {
44-
$scope.val = angular.copy($scope.value);
52+
$scope.val = ngModelCtrl.$viewValue;
4553
$scope.onLeave();
4654
};
47-
48-
$scope.$watch('value', function(value) {
49-
$scope.val = value;
50-
});
55+
56+
this.render = function() {
57+
$scope.val = ngModelCtrl.$viewValue;
58+
};
5159

5260
$scope.readonly = false;
5361
if ($attrs.readonly) {
@@ -60,13 +68,20 @@ angular.module('ui.bootstrap.rating', [])
6068
.directive('rating', function() {
6169
return {
6270
restrict: 'EA',
71+
require: ['rating', 'ngModel'],
6372
scope: {
64-
value: '=',
6573
onHover: '&',
6674
onLeave: '&'
6775
},
6876
controller: 'RatingController',
6977
templateUrl: 'template/rating/rating.html',
70-
replace: true
78+
replace: true,
79+
link: function(scope, element, attrs, ctrls) {
80+
var ratingCtrl = ctrls[0], ngModelCtrl = ctrls[1];
81+
82+
if ( ngModelCtrl ) {
83+
ratingCtrl.init( ngModelCtrl );
84+
}
85+
}
7186
};
7287
});

src/rating/test/rating.spec.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ describe('rating directive', function () {
66
$compile = _$compile_;
77
$rootScope = _$rootScope_;
88
$rootScope.rate = 3;
9-
element = $compile('<rating value="rate"></rating>')($rootScope);
9+
element = $compile('<rating ng-model="rate"></rating>')($rootScope);
1010
$rootScope.$digest();
1111
}));
1212

@@ -71,22 +71,22 @@ describe('rating directive', function () {
7171
});
7272

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

7777
expect(getStars().length).toBe(7);
7878
});
7979

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

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

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

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

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

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

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

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

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

0 commit comments

Comments
 (0)