Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / LoadMask.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.LoadMask
17  * A simple utility class for generically masking elements while loading data.  If the {@link #store}
18  * config option is specified, the masking will be automatically synchronized with the store's loading
19  * process and the mask element will be cached for reuse.
20  * <p>Example usage:</p>
21  * <pre><code>
22 // Basic mask:
23 var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
24 myMask.show();
25 </code></pre>
26
27  */
28
29 Ext.define('Ext.LoadMask', {
30
31     /* Begin Definitions */
32
33     mixins: {
34         observable: 'Ext.util.Observable'
35     },
36
37     requires: ['Ext.data.StoreManager'],
38
39     /* End Definitions */
40
41     /**
42      * @cfg {Ext.data.Store} store
43      * Optional Store to which the mask is bound. The mask is displayed when a load request is issued, and
44      * hidden on either load success, or load fail.
45      */
46
47     /**
48      * @cfg {String} msg
49      * The text to display in a centered loading message box (defaults to 'Loading...')
50      */
51     msg : 'Loading...',
52     /**
53      * @cfg {String} msgCls
54      * The CSS class to apply to the loading message element (defaults to "x-mask-loading")
55      */
56     msgCls : Ext.baseCSSPrefix + 'mask-loading',
57     
58     /**
59      * @cfg {Boolean} useMsg
60      * Whether or not to use a loading message class or simply mask the bound element.
61      */
62     useMsg: true,
63
64     /**
65      * Read-only. True if the mask is currently disabled so that it will not be displayed (defaults to false)
66      * @type Boolean
67      */
68     disabled: false,
69
70     /**
71      * Creates new LoadMask.
72      * @param {Mixed} el The element, element ID, or DOM node you wish to mask.
73      * Also, may be a Component who's element you wish to mask.
74      * @param {Object} config (optional) The config object
75      */
76     constructor : function(el, config) {
77         var me = this;
78
79         if (el.isComponent) {
80             me.bindComponent(el);
81         } else {
82             me.el = Ext.get(el);
83         }
84         Ext.apply(me, config);
85
86         me.addEvents('beforeshow', 'show', 'hide');
87         if (me.store) {
88             me.bindStore(me.store, true);
89         }
90         me.mixins.observable.constructor.call(me, config);
91     },
92
93     bindComponent: function(comp) {
94         var me = this,
95             listeners = {
96                 resize: me.onComponentResize,
97                 scope: me
98             };
99
100         if (comp.el) {
101             me.onComponentRender(comp);
102         } else {
103             listeners.render = {
104                 fn: me.onComponentRender,
105                 scope: me,
106                 single: true
107             };
108         }
109         me.mon(comp, listeners);
110     },
111
112     /**
113      * @private
114      * Called if we were configured with a Component, and that Component was not yet rendered. Collects the element to mask.
115      */
116     onComponentRender: function(comp) {
117         this.el = comp.getContentTarget();
118     },
119
120     /**
121      * @private
122      * Called when this LoadMask's Component is resized. The isMasked method also re-centers any displayed message.
123      */
124     onComponentResize: function(comp, w, h) {
125         this.el.isMasked();
126     },
127
128     /**
129      * Changes the data store bound to this LoadMask.
130      * @param {Store} store The store to bind to this LoadMask
131      */
132     bindStore : function(store, initial) {
133         var me = this;
134
135         if (!initial && me.store) {
136             me.mun(me.store, {
137                 scope: me,
138                 beforeload: me.onBeforeLoad,
139                 load: me.onLoad,
140                 exception: me.onLoad
141             });
142             if(!store) {
143                 me.store = null;
144             }
145         }
146         if (store) {
147             store = Ext.data.StoreManager.lookup(store);
148             me.mon(store, {
149                 scope: me,
150                 beforeload: me.onBeforeLoad,
151                 load: me.onLoad,
152                 exception: me.onLoad
153             });
154
155         }
156         me.store = store;
157         if (store && store.isLoading()) {
158             me.onBeforeLoad();
159         }
160     },
161
162     /**
163      * Disables the mask to prevent it from being displayed
164      */
165     disable : function() {
166         var me = this;
167
168        me.disabled = true;
169        if (me.loading) {
170            me.onLoad();
171        }
172     },
173
174     /**
175      * Enables the mask so that it can be displayed
176      */
177     enable : function() {
178         this.disabled = false;
179     },
180
181     /**
182      * Method to determine whether this LoadMask is currently disabled.
183      * @return {Boolean} the disabled state of this LoadMask.
184      */
185     isDisabled : function() {
186         return this.disabled;
187     },
188
189     // private
190     onLoad : function() {
191         var me = this;
192
193         me.loading = false;
194         me.el.unmask();
195         me.fireEvent('hide', me, me.el, me.store);
196     },
197
198     // private
199     onBeforeLoad : function() {
200         var me = this;
201
202         if (!me.disabled && !me.loading && me.fireEvent('beforeshow', me, me.el, me.store) !== false) {
203             if (me.useMsg) {
204                 me.el.mask(me.msg, me.msgCls, false);
205             } else {
206                 me.el.mask();
207             }
208             
209             me.fireEvent('show', me, me.el, me.store);
210             me.loading = true;
211         }
212     },
213
214     /**
215      * Show this LoadMask over the configured Element.
216      */
217     show: function() {
218         this.onBeforeLoad();
219     },
220
221     /**
222      * Hide this LoadMask.
223      */
224     hide: function() {
225         this.onLoad();
226     },
227
228     // private
229     destroy : function() {
230         this.hide();
231         this.clearListeners();
232     }
233 });
234