Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / examples / ux / statusbar / StatusBar.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.ux.StatusBar
17  * <p>Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}.  In addition to
18  * supporting the standard {@link Ext.toolbar.Toolbar} interface for adding buttons, menus and other items, the StatusBar
19  * provides a greedy status element that can be aligned to either side and has convenient methods for setting the
20  * status text and icon.  You can also indicate that something is processing using the {@link #showBusy} method.</p>
21  * <pre><code>
22 Ext.create('Ext.Panel', {
23     title: 'StatusBar',
24     // etc.
25     bbar: Ext.create('Ext.ux.StatusBar', {
26         id: 'my-status',
27
28         // defaults to use when the status is cleared:
29         defaultText: 'Default status text',
30         defaultIconCls: 'default-icon',
31
32         // values to set initially:
33         text: 'Ready',
34         iconCls: 'ready-icon',
35
36         // any standard Toolbar items:
37         items: [{
38             text: 'A Button'
39         }, '-', 'Plain Text']
40     })
41 });
42
43 // Update the status bar later in code:
44 var sb = Ext.getCmp('my-status');
45 sb.setStatus({
46     text: 'OK',
47     iconCls: 'ok-icon',
48     clear: true // auto-clear after a set interval
49 });
50
51 // Set the status bar to show that something is processing:
52 sb.showBusy();
53
54 // processing....
55
56 sb.clearStatus(); // once completeed
57 </code></pre>
58  * @extends Ext.toolbar.Toolbar
59  * @constructor
60  * Creates a new StatusBar
61  * @param {Object/Array} config A config object
62  */
63 Ext.define('Ext.ux.statusbar.StatusBar', {
64     extend: 'Ext.toolbar.Toolbar',
65     alternateClassName: 'Ext.ux.StatusBar',
66     alias: 'widget.statusbar',
67     requires: ['Ext.toolbar.TextItem'],
68     /**
69      * @cfg {String} statusAlign
70      * The alignment of the status element within the overall StatusBar layout.  When the StatusBar is rendered,
71      * it creates an internal div containing the status text and icon.  Any additional Toolbar items added in the
72      * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be
73      * rendered, in added order, to the opposite side.  The status element is greedy, so it will automatically
74      * expand to take up all sapce left over by any other items.  Example usage:
75      * <pre><code>
76 // Create a left-aligned status bar containing a button,
77 // separator and text item that will be right-aligned (default):
78 Ext.create('Ext.Panel', {
79     title: 'StatusBar',
80     // etc.
81     bbar: Ext.create('Ext.ux.StatusBar', {
82         defaultText: 'Default status text',
83         id: 'status-id',
84         items: [{
85             text: 'A Button'
86         }, '-', 'Plain Text']
87     })
88 });
89
90 // By adding the statusAlign config, this will create the
91 // exact same toolbar, except the status and toolbar item
92 // layout will be reversed from the previous example:
93 Ext.create('Ext.Panel', {
94     title: 'StatusBar',
95     // etc.
96     bbar: Ext.create('Ext.ux.StatusBar', {
97         defaultText: 'Default status text',
98         id: 'status-id',
99         statusAlign: 'right',
100         items: [{
101             text: 'A Button'
102         }, '-', 'Plain Text']
103     })
104 });
105 </code></pre>
106      */
107     /**
108      * @cfg {String} defaultText
109      * The default {@link #text} value.  This will be used anytime the status bar is cleared with the
110      * <tt>useDefaults:true</tt> option (defaults to '').
111      */
112     /**
113      * @cfg {String} defaultIconCls
114      * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon).
115      * This will be used anytime the status bar is cleared with the <tt>useDefaults:true</tt> option (defaults to '').
116      */
117     /**
118      * @cfg {String} text
119      * A string that will be <b>initially</b> set as the status message.  This string
120      * will be set as innerHTML (html tags are accepted) for the toolbar item.
121      * If not specified, the value set for <code>{@link #defaultText}</code>
122      * will be used.
123      */
124     /**
125      * @cfg {String} iconCls
126      * A CSS class that will be <b>initially</b> set as the status bar icon and is
127      * expected to provide a background image (defaults to '').
128      * Example usage:<pre><code>
129 // Example CSS rule:
130 .x-statusbar .x-status-custom {
131     padding-left: 25px;
132     background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
133 }
134
135 // Setting a default icon:
136 var sb = Ext.create('Ext.ux.StatusBar', {
137     defaultIconCls: 'x-status-custom'
138 });
139
140 // Changing the icon:
141 sb.setStatus({
142     text: 'New status',
143     iconCls: 'x-status-custom'
144 });
145 </code></pre>
146      */
147
148     /**
149      * @cfg {String} cls
150      * The base class applied to the containing element for this component on render (defaults to 'x-statusbar')
151      */
152     cls : 'x-statusbar',
153     /**
154      * @cfg {String} busyIconCls
155      * The default <code>{@link #iconCls}</code> applied when calling
156      * <code>{@link #showBusy}</code> (defaults to <tt>'x-status-busy'</tt>).
157      * It can be overridden at any time by passing the <code>iconCls</code>
158      * argument into <code>{@link #showBusy}</code>.
159      */
160     busyIconCls : 'x-status-busy',
161     /**
162      * @cfg {String} busyText
163      * The default <code>{@link #text}</code> applied when calling
164      * <code>{@link #showBusy}</code> (defaults to <tt>'Loading...'</tt>).
165      * It can be overridden at any time by passing the <code>text</code>
166      * argument into <code>{@link #showBusy}</code>.
167      */
168     busyText : 'Loading...',
169     /**
170      * @cfg {Number} autoClear
171      * The number of milliseconds to wait after setting the status via
172      * <code>{@link #setStatus}</code> before automatically clearing the status
173      * text and icon (defaults to <tt>5000</tt>).  Note that this only applies
174      * when passing the <tt>clear</tt> argument to <code>{@link #setStatus}</code>
175      * since that is the only way to defer clearing the status.  This can
176      * be overridden by specifying a different <tt>wait</tt> value in
177      * <code>{@link #setStatus}</code>. Calls to <code>{@link #clearStatus}</code>
178      * always clear the status bar immediately and ignore this value.
179      */
180     autoClear : 5000,
181
182     /**
183      * @cfg {String} emptyText
184      * The text string to use if no text has been set.  Defaults to
185      * <tt>'&nbsp;'</tt>).  If there are no other items in the toolbar using
186      * an empty string (<tt>''</tt>) for this value would end up in the toolbar
187      * height collapsing since the empty string will not maintain the toolbar
188      * height.  Use <tt>''</tt> if the toolbar should collapse in height
189      * vertically when no text is specified and there are no other items in
190      * the toolbar.
191      */
192     emptyText : '&nbsp;',
193
194     // private
195     activeThreadId : 0,
196
197     // private
198     initComponent : function(){
199         if (this.statusAlign === 'right') {
200             this.cls += ' x-status-right';
201         }
202         this.callParent(arguments);
203     },
204
205     // private
206     afterRender : function(){
207         this.callParent(arguments);
208
209         var right = this.statusAlign === 'right';
210         this.currIconCls = this.iconCls || this.defaultIconCls;
211         this.statusEl = Ext.create('Ext.toolbar.TextItem', {
212             cls: 'x-status-text ' + (this.currIconCls || ''),
213             text: this.text || this.defaultText || ''
214         });
215
216         if (right) {
217             this.add('->');
218             this.add(this.statusEl);
219         } else {
220             this.insert(0, this.statusEl);
221             this.insert(1, '->');
222         }
223         this.height = 27;
224         this.doLayout();
225     },
226
227     /**
228      * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the
229      * status that was set after a specified interval.
230      * @param {Object/String} config A config object specifying what status to set, or a string assumed
231      * to be the status text (and all other options are defaulted as explained below). A config
232      * object containing any or all of the following properties can be passed:<ul>
233      * <li><tt>text</tt> {String} : (optional) The status text to display.  If not specified, any current
234      * status text will remain unchanged.</li>
235      * <li><tt>iconCls</tt> {String} : (optional) The CSS class used to customize the status icon (see
236      * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.</li>
237      * <li><tt>clear</tt> {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will
238      * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not
239      * specified, the new status will not be auto-cleared and will stay until updated again or cleared using
240      * {@link #clearStatus}. If <tt>true</tt> is passed, the status will be cleared using {@link #autoClear},
241      * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed,
242      * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value.
243      * All other options will be defaulted as with the boolean option.  To customize any other options,
244      * you can pass an object in the format:<ul>
245      *    <li><tt>wait</tt> {Number} : (optional) The number of milliseconds to wait before clearing
246      *    (defaults to {@link #autoClear}).</li>
247      *    <li><tt>anim</tt> {Number} : (optional) False to clear the status immediately once the callback
248      *    executes (defaults to true which fades the status out).</li>
249      *    <li><tt>useDefaults</tt> {Number} : (optional) False to completely clear the status text and iconCls
250      *    (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
251      * </ul></li></ul>
252      * Example usage:<pre><code>
253 // Simple call to update the text
254 statusBar.setStatus('New status');
255
256 // Set the status and icon, auto-clearing with default options:
257 statusBar.setStatus({
258     text: 'New status',
259     iconCls: 'x-status-custom',
260     clear: true
261 });
262
263 // Auto-clear with custom options:
264 statusBar.setStatus({
265     text: 'New status',
266     iconCls: 'x-status-custom',
267     clear: {
268         wait: 8000,
269         anim: false,
270         useDefaults: false
271     }
272 });
273 </code></pre>
274      * @return {Ext.ux.StatusBar} this
275      */
276     setStatus : function(o) {
277         o = o || {};
278
279         if (Ext.isString(o)) {
280             o = {text:o};
281         }
282         if (o.text !== undefined) {
283             this.setText(o.text);
284         }
285         if (o.iconCls !== undefined) {
286             this.setIcon(o.iconCls);
287         }
288
289         if (o.clear) {
290             var c = o.clear,
291                 wait = this.autoClear,
292                 defaults = {useDefaults: true, anim: true};
293
294             if (Ext.isObject(c)) {
295                 c = Ext.applyIf(c, defaults);
296                 if (c.wait) {
297                     wait = c.wait;
298                 }
299             } else if (Ext.isNumber(c)) {
300                 wait = c;
301                 c = defaults;
302             } else if (Ext.isBoolean(c)) {
303                 c = defaults;
304             }
305
306             c.threadId = this.activeThreadId;
307             Ext.defer(this.clearStatus, wait, this, [c]);
308         }
309         this.doLayout();
310         return this;
311     },
312
313     /**
314      * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation.
315      * @param {Object} config (optional) A config object containing any or all of the following properties.  If this
316      * object is not specified the status will be cleared using the defaults below:<ul>
317      * <li><tt>anim</tt> {Boolean} : (optional) True to clear the status by fading out the status element (defaults
318      * to false which clears immediately).</li>
319      * <li><tt>useDefaults</tt> {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and
320      * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).</li>
321      * </ul>
322      * @return {Ext.ux.StatusBar} this
323      */
324     clearStatus : function(o) {
325         o = o || {};
326
327         if (o.threadId && o.threadId !== this.activeThreadId) {
328             // this means the current call was made internally, but a newer
329             // thread has set a message since this call was deferred.  Since
330             // we don't want to overwrite a newer message just ignore.
331             return this;
332         }
333
334         var text = o.useDefaults ? this.defaultText : this.emptyText,
335             iconCls = o.useDefaults ? (this.defaultIconCls ? this.defaultIconCls : '') : '';
336
337         if (o.anim) {
338             // animate the statusEl Ext.Element
339             this.statusEl.el.puff({
340                 remove: false,
341                 useDisplay: true,
342                 scope: this,
343                 callback: function(){
344                     this.setStatus({
345                      text: text,
346                      iconCls: iconCls
347                  });
348
349                     this.statusEl.el.show();
350                 }
351             });
352         } else {
353             // hide/show the el to avoid jumpy text or icon
354              this.statusEl.hide();
355              this.setStatus({
356                  text: text,
357                  iconCls: iconCls
358              });
359              this.statusEl.show();
360         }
361         this.doLayout();
362         return this;
363     },
364
365     /**
366      * Convenience method for setting the status text directly.  For more flexible options see {@link #setStatus}.
367      * @param {String} text (optional) The text to set (defaults to '')
368      * @return {Ext.ux.StatusBar} this
369      */
370     setText : function(text){
371         this.activeThreadId++;
372         this.text = text || '';
373         if (this.rendered) {
374             this.statusEl.setText(this.text);
375         }
376         return this;
377     },
378
379     /**
380      * Returns the current status text.
381      * @return {String} The status text
382      */
383     getText : function(){
384         return this.text;
385     },
386
387     /**
388      * Convenience method for setting the status icon directly.  For more flexible options see {@link #setStatus}.
389      * See {@link #iconCls} for complete details about customizing the icon.
390      * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed)
391      * @return {Ext.ux.StatusBar} this
392      */
393     setIcon : function(cls){
394         this.activeThreadId++;
395         cls = cls || '';
396
397         if (this.rendered) {
398          if (this.currIconCls) {
399              this.statusEl.removeCls(this.currIconCls);
400              this.currIconCls = null;
401          }
402          if (cls.length > 0) {
403              this.statusEl.addCls(cls);
404              this.currIconCls = cls;
405          }
406         } else {
407             this.currIconCls = cls;
408         }
409         return this;
410     },
411
412     /**
413      * Convenience method for setting the status text and icon to special values that are pre-configured to indicate
414      * a "busy" state, usually for loading or processing activities.
415      * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a
416      * string to use as the status text (in which case all other options for setStatus will be defaulted).  Use the
417      * <tt>text</tt> and/or <tt>iconCls</tt> properties on the config to override the default {@link #busyText}
418      * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and
419      * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}.
420      * @return {Ext.ux.StatusBar} this
421      */
422     showBusy : function(o){
423         if (Ext.isString(o)) {
424             o = { text: o };
425         }
426         o = Ext.applyIf(o || {}, {
427             text: this.busyText,
428             iconCls: this.busyIconCls
429         });
430         return this.setStatus(o);
431     }
432 });
433