Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / ComponentLoader.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.ComponentLoader
17  * @extends Ext.ElementLoader
18  * 
19  * This class is used to load content via Ajax into a {@link Ext.Component}. In general 
20  * this class will not be instanced directly, rather a loader configuration will be passed to the
21  * constructor of the {@link Ext.Component}.
22  * 
23  * ## HTML Renderer
24  * By default, the content loaded will be processed as raw html. The response text
25  * from the request is taken and added to the component. This can be used in
26  * conjunction with the {@link #scripts} option to execute any inline scripts in
27  * the resulting content. Using this renderer has the same effect as passing the
28  * {@link Ext.Component#html} configuration option.
29  * 
30  * ## Data Renderer
31  * This renderer allows content to be added by using JSON data and a {@link Ext.XTemplate}.
32  * The content received from the response is passed to the {@link Ext.Component#update} method.
33  * This content is run through the attached {@link Ext.Component#tpl} and the data is added to
34  * the Component. Using this renderer has the same effect as using the {@link Ext.Component#data}
35  * configuration in conjunction with a {@link Ext.Component#tpl}.
36  * 
37  * ## Component Renderer
38  * This renderer can only be used with a {@link Ext.container.Container} and subclasses. It allows for
39  * Components to be loaded remotely into a Container. The response is expected to be a single/series of
40  * {@link Ext.Component} configuration objects. When the response is received, the data is decoded
41  * and then passed to {@link Ext.container.Container#add}. Using this renderer has the same effect as specifying
42  * the {@link Ext.container.Container#items} configuration on a Container. 
43  * 
44  * ## Custom Renderer
45  * A custom function can be passed to handle any other special case, see the {@link #renderer} option.
46  * 
47  * ## Example Usage
48  *     new Ext.Component({
49  *         tpl: '{firstName} - {lastName}',
50  *         loader: {
51  *             url: 'myPage.php',
52  *             renderer: 'data',
53  *             params: {
54  *                 userId: 1
55  *             }
56  *         }
57  *     });
58  */
59 Ext.define('Ext.ComponentLoader', {
60
61     /* Begin Definitions */
62     
63     extend: 'Ext.ElementLoader',
64
65     statics: {
66         Renderer: {
67             Data: function(loader, response, active){
68                 var success = true;
69                 try {
70                     loader.getTarget().update(Ext.decode(response.responseText));
71                 } catch (e) {
72                     success = false;
73                 }
74                 return success;
75             },
76
77             Component: function(loader, response, active){
78                 var success = true,
79                     target = loader.getTarget(),
80                     items = [];
81
82                 //<debug>
83                 if (!target.isContainer) {
84                     Ext.Error.raise({
85                         target: target,
86                         msg: 'Components can only be loaded into a container'
87                     });
88                 }
89                 //</debug>
90
91                 try {
92                     items = Ext.decode(response.responseText);
93                 } catch (e) {
94                     success = false;
95                 }
96
97                 if (success) {
98                     if (active.removeAll) {
99                         target.removeAll();
100                     }
101                     target.add(items);
102                 }
103                 return success;
104             }
105         }
106     },
107
108     /* End Definitions */
109
110     /**
111      * @cfg {Ext.Component/String} target The target {@link Ext.Component} for the loader. Defaults to <tt>null</tt>.
112      * If a string is passed it will be looked up via the id.
113      */
114     target: null,
115
116     /**
117      * @cfg {Mixed} loadMask True or a {@link Ext.LoadMask} configuration to enable masking during loading. Defaults to <tt>false</tt>.
118      */
119     loadMask: false,
120     
121     /**
122      * @cfg {Boolean} scripts True to parse any inline script tags in the response. This only used when using the html
123      * {@link #renderer}.
124      */
125
126     /**
127      * @cfg {String/Function} renderer
128
129 The type of content that is to be loaded into, which can be one of 3 types:
130
131 + **html** : Loads raw html content, see {@link Ext.Component#html}
132 + **data** : Loads raw html content, see {@link Ext.Component#data}
133 + **component** : Loads child {Ext.Component} instances. This option is only valid when used with a Container.
134
135 Defaults to `html`.
136
137 Alternatively, you can pass a function which is called with the following parameters.
138
139 + loader - Loader instance
140 + response - The server response
141 + active - The active request
142
143 The function must return false is loading is not successful. Below is a sample of using a custom renderer:
144
145     new Ext.Component({
146         loader: {
147             url: 'myPage.php',
148             renderer: function(loader, response, active) {
149                 var text = response.responseText;
150                 loader.getTarget().update('The response is ' + text);
151                 return true;
152             }
153         }
154     });
155      * @markdown
156      */
157     renderer: 'html',
158
159     /**
160      * Set a {Ext.Component} as the target of this loader. Note that if the target is changed,
161      * any active requests will be aborted.
162      * @param {String/Ext.Component} target The component to be the target of this loader. If a string is passed
163      * it will be looked up via its id.
164      */
165     setTarget: function(target){
166         var me = this;
167         
168         if (Ext.isString(target)) {
169             target = Ext.getCmp(target);
170         }
171
172         if (me.target && me.target != target) {
173             me.abort();
174         }
175         me.target = target;
176     },
177     
178     // inherit docs
179     removeMask: function(){
180         this.target.setLoading(false);
181     },
182     
183     /**
184      * Add the mask on the target
185      * @private
186      * @param {Mixed} mask The mask configuration
187      */
188     addMask: function(mask){
189         this.target.setLoading(mask);
190     },
191
192     /**
193      * Get the target of this loader.
194      * @return {Ext.Component} target The target, null if none exists.
195      */
196     
197     setOptions: function(active, options){
198         active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll;
199     },
200
201     /**
202      * Gets the renderer to use
203      * @private
204      * @param {String/Function} renderer The renderer to use
205      * @return {Function} A rendering function to use.
206      */
207     getRenderer: function(renderer){
208         if (Ext.isFunction(renderer)) {
209             return renderer;
210         }
211
212         var renderers = this.statics().Renderer;
213         switch (renderer) {
214             case 'component':
215                 return renderers.Component;
216             case 'data':
217                 return renderers.Data;
218             default:
219                 return Ext.ElementLoader.Renderer.Html;
220         }
221     }
222 });
223