aboutsummaryrefslogtreecommitdiffstats
path: root/vid/src/main/webapp/app/vid/scripts/directives/progressBarDirective.js
blob: 5ffada8a304edbe9c408f28822f4fc652a2cead8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*-
 * ============LICENSE_START=======================================================
 * VID
 * ================================================================================
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */

"use strict";

/*
 * "progressBarDirective.js" provides a progress bar directive.
 * 
 * SYNTAX:
 * 
 * <div progress-bar value="percentProgress"></div>
 * 
 * "percentProgress" is the numeric percent progress to be displayed (0 to 100)
 * expressed as a number only (i.e. no trailing "%"). An "scoped" Angular value
 * can be used (e.g. "{{percentProgress}}").
 * 
 * Two additional attributes can also be included:
 * 
 * increases-only="true | false"
 * 
 * Normally, the progress bar always updates the display with whatever value is
 * set. Alternatively, if "increases-only" is set to "true", the display will
 * only be updated if "percentProgress" is >= the previous value.
 * 
 * control="control"
 * 
 * Provides a method ... $scope.control.reset()" ... that a controller can call
 * to reset the progress to it's initial zero state. This would only expected to
 * be needed if A) increases-only is set to true and B) there is a need to reset
 * the controller to 0. If increases-only is set to false or not present, an
 * alternative method of resetting the progress is to just tset percentProgress
 * to 0.
 * 
 * CAVEATS:
 * 
 * 1) The extended attribute "ngx-show" should be used instead of "ng-show" if
 * the control needs to be conditionally visible. Example:
 * ngx-show="{{isProgressVisible}}"
 * 
 * 2) $scope.control.reset() should be conditionally called as follows IF it is
 * called immediately after HTML is rendered. This is due to a timing-related
 * behavior.
 * 
 * 3) The progress bar displays values of "0" and "100" if precentProgress is,
 * respectively, less than 0 or greater than 100.
 * 
 * CUSTOM STYLING:
 * 
 * The ECOMP portal styling uses the class named "progress". The class
 * attributes can be overridden in CSS. This example was tested:
 * 
 * .progress { margin: 0px 10px; height: 40px }
 * 
 * Additional styling can be applied to the progress-bar element. Example:
 * 
 * div[progress-bar=""] { padding-top: 10px; }
 * 
 * if (angular.isFunction($scope.control.reset)) { $scope.control.reset(); }
 * 
 * DEPENDENCIES:
 * 
 * This code assumes dependency files provided by the ECOMP Portal framework are
 * included. For example, ".../app/fusion/external/ebz/sandbox/styles/base.css"
 * is one required dependency. There may also be others.
 */

var progressBarDirective = function() {

    var style = "font-weight: bold;";
    /*
     * The 3 "aria-*" properties were added as per an Internet reference
     * example. These appear to have no impact on current behavior but are
     * retained for future reference.
     */
    var properties = "class='progress-bar' role='progressbar' "
	    + "aria-valuenow='' aria-valuemin='0' aria-valuemax='100'";
    var previousValue = 0;

    var updateProgress = function(element, attrs, valueAsString) {
	if (valueAsString === undefined || valueAsString === null
		|| valueAsString === "") {
	    valueAsString = "0";
	}
	var valueAsInteger = parseInt(valueAsString);
	if (valueAsInteger > 100) {
	    valueAsInteger = 100;
	    valueAsString = "100";
	}
	if (attrs.increasesOnly === "true") {
	    if (valueAsInteger >= previousValue) {
		previousValue = valueAsInteger;
	    } else {
		return;
	    }
	}
	element.css("width", valueAsString + "%");
	if (valueAsInteger >= 100) {
	    element.removeClass("progress-bar-info").addClass(
		    "progress-bar-success");
	} else {
	    element.removeClass("progress-bar-success").addClass(
		    "progress-bar-info");
	}
	if (valueAsInteger >= 5) {
	    element.html(valueAsString + " %");
	} else {
	    /*
	     * Hide text since color combination is barely visible when progress
	     * portion is narrow.
	     */
	    element.html("");
	}
    }

    return {
	restrict : "EA",
	transclude : true,
	replace : true,
	template : "<div ng-transclude " + properties + " style='" + style
		+ "'></div>",
	scope : {
	    control : "=",
	    progressBar : "@"
	},
	link : function(scope, element, attrs) {

	    /*
	     * It should be possible to alternatively add this wrapper in the
	     * template instead of using "element.wrap". Some techniques were
	     * attempted but were unsuccessful.
	     */
	    element.wrap("<div class='progress'></div");

	    var control = scope.control || {};

	    control.reset = function() {
		previousValue = 0;
		updateProgress(element, attrs, 0);
	    }

	    attrs.$observe("value", function(valueString) {
		updateProgress(element, attrs, valueString);
	    });

	    attrs.$observe("ngxShow", function(valueString) {
		if (valueString === "false") {
		    element.parent().hide();
		} else {
		    element.parent().show();
		}
	    });
	}
    }
}

app.directive("progressBar", progressBarDirective);