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

Commit 713c848

Browse files
lepit31wesleycho
authored andcommitted
feat(rating): add title support for stars
- Add support for adding titles to stars Closes #3621
1 parent a69f66f commit 713c848

File tree

5 files changed

+78
-9
lines changed

5 files changed

+78
-9
lines changed

src/rating/docs/demo.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div ng-controller="RatingDemoCtrl">
22
<h4>Default</h4>
3-
<rating ng-model="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" titles="['one','two','three']" ></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>
@@ -12,4 +12,4 @@ <h4>Default</h4>
1212
<h4>Custom icons</h4>
1313
<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>
1414
<div ng-init="y = 2"><rating ng-model="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
15-
</div>
15+
</div>

src/rating/docs/readme.md

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ Rating directive that will take care of visualising a star rating bar.
1616
_(Defaults: false)_ :
1717
Prevent user's interaction.
1818

19+
* `titles`
20+
_(Defaults: ["one", "two", "three", "four", "five"])_ :
21+
An array of Strings defining titles for all icons
22+
1923
* `on-hover(value)`
2024
:
2125
An optional expression called when user's mouse is over a particular icon.

src/rating/rating.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ angular.module('ui.bootstrap.rating', [])
33
.constant('ratingConfig', {
44
max: 5,
55
stateOn: null,
6-
stateOff: null
6+
stateOff: null,
7+
titles : ['one', 'two', 'three', 'four', 'five']
78
})
89

910
.controller('RatingController', ['$scope', '$attrs', 'ratingConfig', function($scope, $attrs, ratingConfig) {
@@ -22,19 +23,30 @@ angular.module('ui.bootstrap.rating', [])
2223

2324
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
2425
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
25-
26+
var tmpTitles = angular.isDefined($attrs.titles) ? $scope.$parent.$eval($attrs.titles) : ratingConfig.titles ;
27+
this.titles = angular.isArray(tmpTitles) && tmpTitles.length > 0 ?
28+
tmpTitles : ratingConfig.titles;
29+
2630
var ratingStates = angular.isDefined($attrs.ratingStates) ? $scope.$parent.$eval($attrs.ratingStates) :
2731
new Array( angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max );
2832
$scope.range = this.buildTemplateObjects(ratingStates);
2933
};
3034

3135
this.buildTemplateObjects = function(states) {
3236
for (var i = 0, n = states.length; i < n; i++) {
33-
states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff }, states[i]);
37+
states[i] = angular.extend({ index: i }, { stateOn: this.stateOn, stateOff: this.stateOff, title: this.getTitle(i) }, states[i]);
3438
}
3539
return states;
3640
};
37-
41+
42+
this.getTitle = function(index) {
43+
if (index >= this.titles.length) {
44+
return index + 1;
45+
} else {
46+
return this.titles[index];
47+
}
48+
};
49+
3850
$scope.rate = function(value) {
3951
if ( !$scope.readonly && value >= 0 && value <= $scope.range.length ) {
4052
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue === value ? 0 : value);
@@ -84,4 +96,4 @@ angular.module('ui.bootstrap.rating', [])
8496
ratingCtrl.init( ngModelCtrl );
8597
}
8698
};
87-
});
99+
});

src/rating/test/rating.spec.js

+53
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ describe('rating directive', function () {
2727
return state;
2828
}
2929

30+
function getTitles() {
31+
var stars = getStars();
32+
return stars.toArray().map(function(star) {
33+
return angular.element(star).attr('title');
34+
});
35+
}
36+
3037
function triggerKeyDown(keyCode) {
3138
var e = $.Event('keydown');
3239
e.which = keyCode;
@@ -273,4 +280,50 @@ describe('rating directive', function () {
273280
expect(getState('on', 'off')).toEqual([true, true, true, true, true, false, false, false, false, false]);
274281
});
275282
});
283+
284+
describe('Default title', function() {
285+
it('should return the default title for each star', function() {
286+
expect(getTitles()).toEqual(['one', 'two', 'three', 'four', 'five']);
287+
});
288+
});
289+
290+
describe('shows different title when `max` attribute is greater than the titles array ', function() {
291+
var originalConfig = {};
292+
beforeEach(inject(function(ratingConfig) {
293+
$rootScope.rate = 5;
294+
angular.extend(originalConfig, ratingConfig);
295+
ratingConfig.max = 10;
296+
element = $compile('<rating ng-model="rate"></rating>')($rootScope);
297+
$rootScope.$digest();
298+
}));
299+
afterEach(inject(function(ratingConfig) {
300+
// return it to the original state
301+
angular.extend(ratingConfig, originalConfig);
302+
}));
303+
304+
it('should return the default title for each star', function() {
305+
expect(getTitles()).toEqual(['one', 'two', 'three', 'four', 'five', '6', '7', '8', '9', '10']);
306+
});
307+
});
308+
309+
describe('shows custom titles ', function() {
310+
it('should return the custom title for each star', function() {
311+
$rootScope.titles = [44,45,46];
312+
element = $compile('<rating ng-model="rate" titles="titles"></rating>')($rootScope);
313+
$rootScope.$digest();
314+
expect(getTitles()).toEqual(['44', '45', '46', '4', '5']);
315+
});
316+
it('should return the default title if the custom title is empty', function() {
317+
$rootScope.titles = [];
318+
element = $compile('<rating ng-model="rate" titles="titles"></rating>')($rootScope);
319+
$rootScope.$digest();
320+
expect(getTitles()).toEqual(['one', 'two', 'three', 'four', 'five']);
321+
});
322+
it('should return the default title if the custom title is not an array', function() {
323+
element = $compile('<rating ng-model="rate" titles="test"></rating>')($rootScope);
324+
$rootScope.$digest();
325+
expect(getTitles()).toEqual(['one', 'two', 'three', 'four', 'five']);
326+
});
327+
});
328+
276329
});

template/rating/rating.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<span ng-mouseleave="reset()" ng-keydown="onKeydown($event)" tabindex="0" role="slider" aria-valuemin="0" aria-valuemax="{{range.length}}" aria-valuenow="{{value}}">
2-
<i ng-repeat="r in range track by $index" ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < value && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')">
2+
<i ng-repeat="r in range track by $index" ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < value && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')" ng-attr-title="{{r.title}}" >
33
<span class="sr-only">({{ $index < value ? '*' : ' ' }})</span>
44
</i>
5-
</span>
5+
</span>

0 commit comments

Comments
 (0)