]> git.proxmox.com Git - extjs.git/blame - extjs/classic/classic/src/ProgressBar.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / src / ProgressBar.js
CommitLineData
6527f429
DM
1/**\r
2 * An updateable progress bar component. The progress bar supports two different modes: manual and automatic.\r
3 *\r
4 * In manual mode, you are responsible for showing, updating (via {@link #updateProgress}) and clearing the progress bar\r
5 * as needed from your own code. This method is most appropriate when you want to show progress throughout an operation\r
6 * that has predictable points of interest at which you can update the control.\r
7 *\r
8 * In automatic mode, you simply call {@link #wait} and let the progress bar run indefinitely, only clearing it once the\r
9 * operation is complete. You can optionally have the progress bar wait for a specific amount of time and then clear\r
10 * itself. Automatic mode is most appropriate for timed operations or asynchronous operations in which you have no need\r
11 * for indicating intermediate progress.\r
12 *\r
13 * @example\r
14 * var p = Ext.create('Ext.ProgressBar', {\r
15 * renderTo: Ext.getBody(),\r
16 * width: 300\r
17 * });\r
18 *\r
19 * // Wait for 5 seconds, then update the status el (progress bar will auto-reset)\r
20 * p.wait({\r
21 * interval: 500, //bar will move fast!\r
22 * duration: 50000,\r
23 * increment: 15,\r
24 * text: 'Updating...',\r
25 * scope: this,\r
26 * fn: function(){\r
27 * p.updateText('Done!');\r
28 * }\r
29 * });\r
30 */\r
31Ext.define('Ext.ProgressBar', {\r
32 extend: 'Ext.Component',\r
33 xtype: 'progressbar',\r
34 mixins: [\r
35 'Ext.ProgressBase'\r
36 ],\r
37\r
38 requires: [\r
39 'Ext.Template',\r
40 'Ext.CompositeElement',\r
41 'Ext.TaskManager',\r
42 'Ext.layout.component.ProgressBar'\r
43 ],\r
44\r
45 uses: ['Ext.fx.Anim'],\r
46\r
47 /**\r
48 * @cfg {String/HTMLElement/Ext.dom.Element} textEl\r
49 * The element to render the progress text to (defaults to the progress bar's internal text element)\r
50 */\r
51\r
52 /**\r
53 * @cfg {String} id\r
54 * The progress bar element's id (defaults to an auto-generated id)\r
55 */\r
56\r
57 /**\r
58 * @cfg {String} [baseCls='x-progress']\r
59 * The base CSS class to apply to the progress bar's wrapper element.\r
60 */\r
61 baseCls: Ext.baseCSSPrefix + 'progress',\r
62\r
63 /**\r
64 * @cfg {Boolean/Object} animate\r
65 * True to animate the progress bar during transitions, or an animation configuration\r
66 * (see the {@link #method-animate} method for details).\r
67 */\r
68 animate: false,\r
69\r
70 /**\r
71 * @cfg {String} text\r
72 * The text shown in the progress bar.\r
73 */\r
74 text: '',\r
75\r
76 /**\r
77 * @private\r
78 */\r
79 waitTimer: null,\r
80\r
81 childEls: [\r
82 'bar'\r
83 ],\r
84\r
85 defaultBindProperty: 'value',\r
86\r
87 renderTpl: [\r
88 '<tpl if="internalText">',\r
89 '<div class="{baseCls}-text {baseCls}-text-back">{text}</div>',\r
90 '</tpl>',\r
91 '<div id="{id}-bar" data-ref="bar" class="{baseCls}-bar {baseCls}-bar-{ui}" role="presentation" style="width:{percentage}%">',\r
92 '<tpl if="internalText">',\r
93 '<div class="{baseCls}-text">',\r
94 '<div>{text}</div>',\r
95 '</div>',\r
96 '</tpl>',\r
97 '</div>'\r
98 ],\r
99\r
100 componentLayout: 'progressbar',\r
101 \r
102 ariaRole: 'progressbar',\r
103\r
104 /**\r
105 * @event update\r
106 * Fires after each update interval\r
107 * @param {Ext.ProgressBar} this\r
108 * @param {Number} value The current progress value\r
109 * @param {String} text The current progress text\r
110 */\r
111\r
112 initRenderData: function() {\r
113 var me = this,\r
114 value = me.value || 0;\r
115\r
116 return Ext.apply(me.callParent(), {\r
117 internalText : !me.hasOwnProperty('textEl'),\r
118 text : me.text || '&#160;',\r
119 percentage : value * 100\r
120 });\r
121 },\r
122\r
123 onRender : function() {\r
124 var me = this;\r
125\r
126 me.callParent(arguments);\r
127\r
128 // External text display\r
129 if (me.textEl) {\r
130 me.textEl = Ext.get(me.textEl);\r
131 me.updateText(me.text);\r
132 }\r
133 // Inline text display\r
134 else {\r
135 // This produces a composite w/2 el's (which is why we cannot use childEls or\r
136 // renderSelectors):\r
137 me.textEl = me.el.select('.' + me.baseCls + '-text');\r
138 }\r
139 },\r
140\r
141 updateValue: function(value) {\r
142 this.updateProgress(value, Math.round(value * 100) + '%');\r
143 },\r
144\r
145 /**\r
146 * Updates the progress bar value, and optionally its text.\r
147 * \r
148 * If the text argument is not specified, then the {@link #textTpl} will be used to generate the text.\r
149 * If there is no `textTpl`, any existing text value will be unchanged. To blank out existing text, pass `""`.\r
150 *\r
151 * Note that even if the progress bar value exceeds 1, it will never automatically reset --\r
152 * you are responsible for determining when the progress is complete and\r
153 * calling {@link #reset} to clear and/or hide the control.\r
154 * @param {Number} [value=0] A floating point value between 0 and 1 (e.g., .5)\r
155 * @param {String} [text=''] The string to display in the progress text element\r
156 * @param {Boolean} [animate=false] Whether to animate the transition of the progress bar. If this value is not\r
157 * specified, the default for the class is used\r
158 * @return {Ext.ProgressBar} this\r
159 */\r
160 updateProgress: function(value, text, animate) {\r
161 value = value || 0;\r
162\r
163 var me = this,\r
164 oldValue = me.value,\r
165 textTpl = me.getTextTpl();\r
166\r
167 // Ensure value is not undefined.\r
168 me.value = value || (value = 0);\r
169\r
170 // Empty string (falsy) must blank out the text as per docs.\r
171 if (text != null) {\r
172 me.updateText(text);\r
173 }\r
174 // Generate text using template and progress values.\r
175 else if (textTpl) {\r
176 me.updateText(textTpl.apply({\r
177 value: value,\r
178 percent: value * 100\r
179 }));\r
180 }\r
181 if (me.rendered && !me.destroyed) {\r
182 if (animate === true || (animate !== false && me.animate)) {\r
183 me.bar.stopAnimation();\r
184 me.bar.animate(Ext.apply({\r
185 from: {\r
186 width: (oldValue * 100) + '%'\r
187 },\r
188 to: {\r
189 width: (value * 100) + '%'\r
190 }\r
191 }, me.animate));\r
192 } else {\r
193 me.bar.setStyle('width', (value * 100) + '%');\r
194 }\r
195 }\r
196 me.fireEvent('update', me, value, text);\r
197 return me;\r
198 },\r
199\r
200 /**\r
201 * Updates the progress bar text. If specified, textEl will be updated, otherwise the progress bar itself will\r
202 * display the updated text.\r
203 * @param {String} [text=''] The string to display in the progress text element\r
204 * @return {Ext.ProgressBar} this\r
205 */\r
206 updateText: function(text) {\r
207 var me = this;\r
208 \r
209 me.text = text;\r
210 if (me.rendered) {\r
211 me.textEl.setHtml(me.text);\r
212 }\r
213 return me;\r
214 },\r
215\r
216 applyText : function(text) {\r
217 this.updateText(text);\r
218 },\r
219 \r
220 getText: function(){\r
221 return this.text; \r
222 },\r
223\r
224 /**\r
225 * Initiates an auto-updating progress bar. A duration can be specified, in which case the progress bar will\r
226 * automatically reset after a fixed amount of time and optionally call a callback function if specified. If no\r
227 * duration is passed in, then the progress bar will run indefinitely and must be manually cleared by calling\r
228 * {@link #reset}.\r
229 *\r
230 * Example usage:\r
231 *\r
232 * var p = new Ext.ProgressBar({\r
233 * renderTo: 'my-el'\r
234 * });\r
235 *\r
236 * //Wait for 5 seconds, then update the status el (progress bar will auto-reset)\r
237 * var p = Ext.create('Ext.ProgressBar', {\r
238 * renderTo: Ext.getBody(),\r
239 * width: 300\r
240 * });\r
241 *\r
242 * //Wait for 5 seconds, then update the status el (progress bar will auto-reset)\r
243 * p.wait({\r
244 * interval: 500, //bar will move fast!\r
245 * duration: 50000,\r
246 * increment: 15,\r
247 * text: 'Updating...',\r
248 * scope: this,\r
249 * fn: function(){\r
250 * p.updateText('Done!');\r
251 * }\r
252 * });\r
253 *\r
254 * //Or update indefinitely until some async action completes, then reset manually\r
255 * p.wait();\r
256 * myAction.on('complete', function(){\r
257 * p.reset();\r
258 * p.updateText('Done!');\r
259 * });\r
260 *\r
261 * @param {Object} config (optional) Configuration options\r
262 * @param {Number} config.duration The length of time in milliseconds that the progress bar should\r
263 * run before resetting itself (defaults to undefined, in which case it will run indefinitely\r
264 * until reset is called)\r
265 * @param {Number} config.interval The length of time in milliseconds between each progress update\r
266 * (defaults to 1000 ms)\r
267 * @param {Boolean} config.animate Whether to animate the transition of the progress bar. If this\r
268 * value is not specified, the default for the class is used.\r
269 * @param {Number} config.increment The number of progress update segments to display within the\r
270 * progress bar (defaults to 10). If the bar reaches the end and is still updating, it will\r
271 * automatically wrap back to the beginning.\r
272 * @param {String} config.text Optional text to display in the progress bar element (defaults to '').\r
273 * @param {Function} config.fn A callback function to execute after the progress bar finishes auto-\r
274 * updating. The function will be called with no arguments. This function will be ignored if\r
275 * duration is not specified since in that case the progress bar can only be stopped programmatically,\r
276 * so any required function should be called by the same code after it resets the progress bar.\r
277 * @param {Object} config.scope The scope that is passed to the callback function (only applies when\r
278 * duration and fn are both passed).\r
279 * @return {Ext.ProgressBar} this\r
280 */\r
281 wait: function(o) {\r
282 var me = this, scope;\r
283 \r
284 if (!me.waitTimer) {\r
285 scope = me;\r
286 o = o || {};\r
287 me.updateText(o.text);\r
288 me.waitTimer = Ext.TaskManager.start({\r
289 run: function(i){\r
290 var inc = o.increment || 10;\r
291 i -= 1;\r
292 me.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);\r
293 },\r
294 interval: o.interval || 1000,\r
295 duration: o.duration,\r
296 onStop: function(){\r
297 if (o.fn) {\r
298 o.fn.apply(o.scope || me);\r
299 }\r
300 me.reset();\r
301 },\r
302 scope: scope\r
303 });\r
304 }\r
305 return me;\r
306 },\r
307\r
308 /**\r
309 * Returns true if the progress bar is currently in a {@link #wait} operation\r
310 * @return {Boolean} True if waiting, else false\r
311 */\r
312 isWaiting: function(){\r
313 return this.waitTimer !== null;\r
314 },\r
315\r
316 /**\r
317 * Resets the progress bar value to 0 and text to empty string. If hide = true, the progress bar will also be hidden\r
318 * (using the {@link #hideMode} property internally).\r
319 * @param {Boolean} [hide=false] True to hide the progress bar.\r
320 * @return {Ext.ProgressBar} this\r
321 */\r
322 reset: function(hide){\r
323 var me = this;\r
324 \r
325 me.updateProgress(0);\r
326 me.clearTimer();\r
327 if (hide === true) {\r
328 me.hide();\r
329 }\r
330 return me;\r
331 },\r
332\r
333 /**\r
334 * @private\r
335 */\r
336 clearTimer: function(){\r
337 var me = this;\r
338 \r
339 if (me.waitTimer) {\r
340 me.waitTimer.onStop = null; //prevent recursion\r
341 Ext.TaskManager.stop(me.waitTimer);\r
342 me.waitTimer = null;\r
343 }\r
344 },\r
345\r
346 onDestroy: function(){\r
347 var me = this,\r
348 bar = me.bar;\r
349 \r
350 me.clearTimer();\r
351 if (me.rendered) {\r
352 if (me.textEl.isComposite) {\r
353 me.textEl.clear();\r
354 }\r
355 Ext.destroyMembers(me, 'textEl', 'progressBar');\r
356 if (bar && me.animate) {\r
357 bar.stopAnimation();\r
358 }\r
359 }\r
360 me.callParent();\r
361 }\r
362});\r