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

Commit 365573a

Browse files
committedNov 30, 2013
feat(progressbar): add max attribute & support transclusion
* General refactor. Move logic to controller. * Remove `onFull` & `onEmpty` handlers. * Remove automatic types and stacked types. * `progress` & `bar` transclude content to support text & extra elements. BREAKING CHANGE: The onFull/onEmpty handlers & auto/stacked types have been removed. To migrate your code change your markup like below. Before: <progress percent="var" class="progress-warning"></progress> After: <progressbar value="var" type="warning"></progressbar> and for stacked instead of passing array/objects you can do: <progress><bar ng-repeat="obj in objs" value="obj.var" type="{{obj.type}}"></bar></progress>
1 parent d64f4a9 commit 365573a

File tree

8 files changed

+247
-394
lines changed

8 files changed

+247
-394
lines changed
 

‎src/progressbar/docs/demo.html

+14-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
11
<div ng-controller="ProgressDemoCtrl" class="well">
2-
<h2>Static</h2>
2+
3+
<h3>Static</h3>
34
<div class="row-fluid">
4-
<div class="span4"><progress percent="55"></progress></div>
5-
<div class="span4"><progress percent="22" class="progress-warning progress-striped"></progress></div>
6-
<div class="span4"><progress percent="88" class="progress-danger progress-striped active"></div>
5+
<div class="span4"><progressbar value="55"></progressbar></div>
6+
<div class="span4"><progressbar class="progress-striped" value="22" type="warning">22%</progressbar></div>
7+
<div class="span4"><progressbar class="progress-striped active" max="200" value="166" type="danger"><i>166 / 200</i></progressbar></div>
78
</div>
8-
9-
<h2>Dynamic <button class="btn btn-primary" type="button" ng-click="random()">Randomize</button></h2>
10-
<pre>Value: {{dynamic}}</pre>
11-
<progress percent="dynamic"></progress>
9+
10+
<h3>Dynamic <button class="btn btn-small btn-primary" type="button" ng-click="random()">Randomize</button></h3>
11+
<progressbar max="max" value="dynamic"><span style="color:black; white-space:nowrap;">{{dynamic}} / {{max}}</span></progressbar>
1212

1313
<small><em>No animation</em></small>
14-
<progress percent="dynamic" class="progress-success" animate="false"></progress>
14+
<progressbar animate="false" value="dynamic" type="success"><b>{{dynamic}}%</b></progressbar>
1515

1616
<small><em>Object (changes type based on value)</em></small>
17-
<progress percent="dynamicObject" class="progress-striped active"></progress>
17+
<progressbar class="progress-striped active" value="dynamic" type="{{type}}">{{type}} <i ng-show="showWarning">!!! Watch out !!!</i></progressbar>
1818

19-
<h2>Stacked <button class="btn btn-primary" type="button" ng-click="randomStacked()">Randomize</button></h2>
20-
<small><em>Array values with automatic types</em></small>
21-
<pre>Value: {{stackedArray}}</pre>
22-
<progress percent="stackedArray" auto-type="true"></progress>
23-
24-
<small><em>Objects</em></small>
25-
<pre>Value: {{stacked}}</pre>
26-
<progress percent="stacked"></progress>
19+
20+
<h3>Stacked <button class="btn btn-small btn-primary" type="button" ng-click="randomStacked()">Randomize</button></h3>
21+
<progress><bar ng-repeat="bar in stacked" value="bar.value" type="{{bar.type}}"><span ng-hide="bar.value < 5">{{bar.value}}%</span></bar></progress>
22+
2723
</div>

‎src/progressbar/docs/demo.js

+11-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
var ProgressDemoCtrl = function ($scope) {
2-
2+
3+
$scope.max = 200;
4+
35
$scope.random = function() {
4-
var value = Math.floor((Math.random()*100)+1);
6+
var value = Math.floor((Math.random() * 100) + 1);
57
var type;
68

79
if (value < 25) {
@@ -14,28 +16,21 @@ var ProgressDemoCtrl = function ($scope) {
1416
type = 'danger';
1517
}
1618

19+
$scope.showWarning = (type === 'danger' || type === 'warning');
20+
1721
$scope.dynamic = value;
18-
$scope.dynamicObject = {
19-
value: value,
20-
type: type
21-
};
22+
$scope.type = type;
2223
};
2324
$scope.random();
2425

25-
var types = ['success', 'info', 'warning', 'danger'];
2626
$scope.randomStacked = function() {
27-
$scope.stackedArray = [];
2827
$scope.stacked = [];
28+
var types = ['success', 'info', 'warning', 'danger'];
2929

30-
var n = Math.floor((Math.random()*4)+1);
31-
32-
for (var i=0; i < n; i++) {
33-
var value = Math.floor((Math.random()*30)+1);
34-
$scope.stackedArray.push(value);
35-
36-
var index = Math.floor((Math.random()*4));
30+
for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) {
31+
var index = Math.floor((Math.random() * 4));
3732
$scope.stacked.push({
38-
value: value,
33+
value: Math.floor((Math.random() * 30) + 1),
3934
type: types[index]
4035
});
4136
}

‎src/progressbar/docs/readme.md

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1-
A lightweight progress bar directive that is focused on providing progress visualization!
1+
A progress bar directive that is focused on providing feedback on the progress of a workflow or action.
22

3-
The progress bar directive supports multiple (stacked) bars into the same element, optional transition animation, event handler for full & empty state and many more.
3+
It supports multiple (stacked) bars into the same `<progress>` element or a single `<progressbar>` elemtnt with optional `max` attribute and transition animations.
4+
5+
### Settings ###
6+
7+
#### `<progressbar>` ####
8+
9+
* `value` <i class="icon-eye-open"></i>
10+
:
11+
The current value of progress completed.
12+
13+
* `type`
14+
_(Default: null)_ :
15+
Style type. Possible values are 'success', 'warning' etc.
16+
17+
* `max`
18+
_(Default: 100)_ :
19+
A number that specifies the total value of bars that is required.
20+
21+
* `animate`
22+
_(Default: true)_ :
23+
Whether bars use transitions to achieve the width change.
24+
25+
26+
### Stacked ###
27+
28+
Place multiple `<bars>` into the same `<progress>` element to stack them.
29+
`<progress>` supports `max` and `animate` & `<bar>` supports `value` and `type` attributes.

‎src/progressbar/progressbar.js

+66-72
Original file line numberDiff line numberDiff line change
@@ -2,105 +2,99 @@ angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
22

33
.constant('progressConfig', {
44
animate: true,
5-
autoType: false,
6-
stackedTypes: ['success', 'info', 'warning', 'danger']
5+
max: 100
76
})
87

9-
.controller('ProgressBarController', ['$scope', '$attrs', 'progressConfig', function($scope, $attrs, progressConfig) {
8+
.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', '$transition', function($scope, $attrs, progressConfig, $transition) {
9+
var self = this,
10+
bars = [],
11+
max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max,
12+
animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
1013

11-
// Whether bar transitions should be animated
12-
var animate = angular.isDefined($attrs.animate) ? $scope.$eval($attrs.animate) : progressConfig.animate;
13-
var autoType = angular.isDefined($attrs.autoType) ? $scope.$eval($attrs.autoType) : progressConfig.autoType;
14-
var stackedTypes = angular.isDefined($attrs.stackedTypes) ? $scope.$eval('[' + $attrs.stackedTypes + ']') : progressConfig.stackedTypes;
14+
this.addBar = function(bar, element) {
15+
var oldValue = 0, index = bar.$parent.$index;
16+
if ( angular.isDefined(index) && bars[index] ) {
17+
oldValue = bars[index].value;
18+
}
19+
bars.push(bar);
20+
21+
this.update(element, bar.value, oldValue);
1522

16-
// Create bar object
17-
this.makeBar = function(newBar, oldBar, index) {
18-
var newValue = (angular.isObject(newBar)) ? newBar.value : (newBar || 0);
19-
var oldValue = (angular.isObject(oldBar)) ? oldBar.value : (oldBar || 0);
20-
var type = (angular.isObject(newBar) && angular.isDefined(newBar.type)) ? newBar.type : (autoType) ? getStackedType(index || 0) : null;
23+
bar.$watch('value', function(value, oldValue) {
24+
if (value !== oldValue) {
25+
self.update(element, value, oldValue);
26+
}
27+
});
2128

22-
return {
23-
from: oldValue,
24-
to: newValue,
25-
type: type,
26-
animate: animate
27-
};
29+
bar.$on('$destroy', function() {
30+
self.removeBar(bar);
31+
});
2832
};
2933

30-
function getStackedType(index) {
31-
return stackedTypes[index];
32-
}
34+
// Update bar element width
35+
this.update = function(element, newValue, oldValue) {
36+
var percent = this.getPercentage(newValue);
37+
38+
if (animate) {
39+
element.css('width', this.getPercentage(oldValue) + '%');
40+
$transition(element, {width: percent + '%'});
41+
} else {
42+
element.css({'transition': 'none', 'width': percent + '%'});
43+
}
44+
};
3345

34-
this.addBar = function(bar) {
35-
$scope.bars.push(bar);
36-
$scope.totalPercent += bar.to;
46+
this.removeBar = function(bar) {
47+
bars.splice(bars.indexOf(bar), 1);
3748
};
3849

39-
this.clearBars = function() {
40-
$scope.bars = [];
41-
$scope.totalPercent = 0;
50+
this.getPercentage = function(value) {
51+
return Math.round(100 * value / max);
4252
};
43-
this.clearBars();
4453
}])
4554

4655
.directive('progress', function() {
4756
return {
4857
restrict: 'EA',
4958
replace: true,
50-
controller: 'ProgressBarController',
59+
transclude: true,
60+
controller: 'ProgressController',
61+
require: 'progress',
62+
scope: {},
63+
template: '<div class="progress" ng-transclude></div>'
64+
//templateUrl: 'template/progressbar/progress.html' // Works in AngularJS 1.2
65+
};
66+
})
67+
68+
.directive('bar', function() {
69+
return {
70+
restrict: 'EA',
71+
replace: true,
72+
transclude: true,
73+
require: '^progress',
5174
scope: {
52-
value: '=percent',
53-
onFull: '&',
54-
onEmpty: '&'
75+
value: '=',
76+
type: '@'
5577
},
56-
templateUrl: 'template/progressbar/progress.html',
57-
link: function(scope, element, attrs, controller) {
58-
scope.$watch('value', function(newValue, oldValue) {
59-
controller.clearBars();
60-
61-
if (angular.isArray(newValue)) {
62-
// Stacked progress bar
63-
for (var i=0, n=newValue.length; i < n; i++) {
64-
controller.addBar(controller.makeBar(newValue[i], oldValue[i], i));
65-
}
66-
} else {
67-
// Simple bar
68-
controller.addBar(controller.makeBar(newValue, oldValue));
69-
}
70-
}, true);
71-
72-
// Total percent listeners
73-
scope.$watch('totalPercent', function(value) {
74-
if (value >= 100) {
75-
scope.onFull();
76-
} else if (value <= 0) {
77-
scope.onEmpty();
78-
}
79-
}, true);
78+
templateUrl: 'template/progressbar/bar.html',
79+
link: function(scope, element, attrs, progressCtrl) {
80+
progressCtrl.addBar(scope, element);
8081
}
8182
};
8283
})
8384

84-
.directive('progressbar', ['$transition', function($transition) {
85+
.directive('progressbar', function() {
8586
return {
8687
restrict: 'EA',
8788
replace: true,
89+
transclude: true,
90+
controller: 'ProgressController',
8891
scope: {
89-
width: '=',
90-
old: '=',
91-
type: '=',
92-
animate: '='
92+
value: '=',
93+
type: '@'
9394
},
94-
templateUrl: 'template/progressbar/bar.html',
95-
link: function(scope, element) {
96-
scope.$watch('width', function(value) {
97-
if (scope.animate) {
98-
element.css('width', scope.old + '%');
99-
$transition(element, {width: value + '%'});
100-
} else {
101-
element.css('width', value + '%');
102-
}
103-
});
95+
templateUrl: 'template/progressbar/progressbar.html',
96+
link: function(scope, element, attrs, progressCtrl) {
97+
progressCtrl.addBar(scope, angular.element(element.children()[0]));
10498
}
10599
};
106-
}]);
100+
});

0 commit comments

Comments
 (0)