2 * Ext JS Library 2.2.1
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\r
10 * @class Ext.tree.TreeLoader
\r
11 * @extends Ext.util.Observable
\r
12 * A TreeLoader provides for lazy loading of an {@link Ext.tree.TreeNode}'s child
\r
13 * nodes from a specified URL. The response must be a JavaScript Array definition
\r
14 * whose elements are node definition objects. eg:
\r
18 text: 'A leaf Node',
\r
22 text: 'A folder Node',
\r
25 text: 'A child Node',
\r
31 * A server request is sent, and child nodes are loaded only when a node is expanded.
\r
32 * The loading node's id is passed to the server under the parameter name "node" to
\r
33 * enable the server to produce the correct child nodes.
\r
35 * To pass extra parameters, an event handler may be attached to the "beforeload"
\r
36 * event, and the parameters specified in the TreeLoader's baseParams property:
\r
38 myTreeLoader.on("beforeload", function(treeLoader, node) {
\r
39 this.baseParams.category = node.attributes.category;
\r
42 * This would pass an HTTP parameter called "category" to the server containing
\r
43 * the value of the Node's "category" attribute.
\r
45 * Creates a new Treeloader.
\r
46 * @param {Object} config A config object containing config properties.
\r
48 Ext.tree.TreeLoader = function(config){
\r
49 this.baseParams = {};
\r
50 Ext.apply(this, config);
\r
55 * Fires before a network request is made to retrieve the Json text which specifies a node's children.
\r
56 * @param {Object} This TreeLoader object.
\r
57 * @param {Object} node The {@link Ext.tree.TreeNode} object being loaded.
\r
58 * @param {Object} callback The callback function specified in the {@link #load} call.
\r
63 * Fires when the node has been successfuly loaded.
\r
64 * @param {Object} This TreeLoader object.
\r
65 * @param {Object} node The {@link Ext.tree.TreeNode} object being loaded.
\r
66 * @param {Object} response The response object containing the data from the server.
\r
70 * @event loadexception
\r
71 * Fires if the network request failed.
\r
72 * @param {Object} This TreeLoader object.
\r
73 * @param {Object} node The {@link Ext.tree.TreeNode} object being loaded.
\r
74 * @param {Object} response The response object containing the data from the server.
\r
79 Ext.tree.TreeLoader.superclass.constructor.call(this);
\r
82 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
\r
84 * @cfg {String} dataUrl The URL from which to request a Json string which
\r
85 * specifies an array of node definition objects representing the child nodes
\r
89 * @cfg {String} requestMethod The HTTP request method for loading data (defaults to the value of {@link Ext.Ajax#method}).
\r
92 * @cfg {String} url Equivalent to {@link #dataUrl}.
\r
95 * @cfg {Boolean} preloadChildren If set to true, the loader recursively loads "children" attributes when doing the first load on nodes.
\r
98 * @cfg {Object} baseParams (optional) An object containing properties which
\r
99 * specify HTTP parameters to be passed to each request for child nodes.
\r
102 * @cfg {Object} baseAttrs (optional) An object containing attributes to be added to all nodes
\r
103 * created by this loader. If the attributes sent by the server have an attribute in this object,
\r
104 * they take priority.
\r
107 * @cfg {Object} uiProviders (optional) An object containing properties which
\r
108 * specify custom {@link Ext.tree.TreeNodeUI} implementations. If the optional
\r
109 * <i>uiProvider</i> attribute of a returned child node is a string rather
\r
110 * than a reference to a TreeNodeUI implementation, then that string value
\r
111 * is used as a property name in the uiProviders object.
\r
116 * @cfg {Boolean} clearOnLoad (optional) Default to true. Remove previously existing
\r
117 * child nodes before loading.
\r
119 clearOnLoad : true,
\r
122 * Load an {@link Ext.tree.TreeNode} from the URL specified in the constructor.
\r
123 * This is called automatically when a node is expanded, but may be used to reload
\r
124 * a node (or append new children if the {@link #clearOnLoad} option is false.)
\r
125 * @param {Ext.tree.TreeNode} node
\r
126 * @param {Function} callback
\r
128 load : function(node, callback){
\r
129 if(this.clearOnLoad){
\r
130 while(node.firstChild){
\r
131 node.removeChild(node.firstChild);
\r
134 if(this.doPreload(node)){ // preloaded json children
\r
135 if(typeof callback == "function"){
\r
138 }else if(this.dataUrl||this.url){
\r
139 this.requestData(node, callback);
\r
143 doPreload : function(node){
\r
144 if(node.attributes.children){
\r
145 if(node.childNodes.length < 1){ // preloaded?
\r
146 var cs = node.attributes.children;
\r
147 node.beginUpdate();
\r
148 for(var i = 0, len = cs.length; i < len; i++){
\r
149 var cn = node.appendChild(this.createNode(cs[i]));
\r
150 if(this.preloadChildren){
\r
151 this.doPreload(cn);
\r
162 getParams: function(node){
\r
163 var buf = [], bp = this.baseParams;
\r
164 for(var key in bp){
\r
165 if(typeof bp[key] != "function"){
\r
166 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
\r
169 buf.push("node=", encodeURIComponent(node.id));
\r
170 return buf.join("");
\r
173 requestData : function(node, callback){
\r
174 if(this.fireEvent("beforeload", this, node, callback) !== false){
\r
175 this.transId = Ext.Ajax.request({
\r
176 method:this.requestMethod,
\r
177 url: this.dataUrl||this.url,
\r
178 success: this.handleResponse,
\r
179 failure: this.handleFailure,
\r
181 argument: {callback: callback, node: node},
\r
182 params: this.getParams(node)
\r
185 // if the load is cancelled, make sure we notify
\r
186 // the node that we are done
\r
187 if(typeof callback == "function"){
\r
193 isLoading : function(){
\r
194 return !!this.transId;
\r
197 abort : function(){
\r
198 if(this.isLoading()){
\r
199 Ext.Ajax.abort(this.transId);
\r
204 * <p>Override this function for custom TreeNode node implementation, or to
\r
205 * modify the attributes at creation time.</p>
\r
206 * Example:<code><pre>
\r
207 new Ext.tree.TreePanel({
\r
209 new Ext.tree.TreeLoader({
\r
211 createNode: function(attr) {
\r
212 // Allow consolidation consignments to have
\r
213 // consignments dropped into them.
\r
214 if (attr.isConsolidation) {
\r
215 attr.iconCls = 'x-consol',
\r
216 attr.allowDrop = true;
\r
218 return Ext.tree.TreeLoader.prototype.call(this, attr);
\r
224 * @param attr {Object} The attributes from which to create the new node.
\r
226 createNode : function(attr){
\r
227 // apply baseAttrs, nice idea Corey!
\r
228 if(this.baseAttrs){
\r
229 Ext.applyIf(attr, this.baseAttrs);
\r
231 if(this.applyLoader !== false){
\r
232 attr.loader = this;
\r
234 if(typeof attr.uiProvider == 'string'){
\r
235 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
\r
238 return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
\r
241 new Ext.tree.TreeNode(attr) :
\r
242 new Ext.tree.AsyncTreeNode(attr);
\r
246 processResponse : function(response, node, callback){
\r
247 var json = response.responseText;
\r
249 var o = eval("("+json+")");
\r
250 node.beginUpdate();
\r
251 for(var i = 0, len = o.length; i < len; i++){
\r
252 var n = this.createNode(o[i]);
\r
254 node.appendChild(n);
\r
258 if(typeof callback == "function"){
\r
259 callback(this, node);
\r
262 this.handleFailure(response);
\r
266 handleResponse : function(response){
\r
267 this.transId = false;
\r
268 var a = response.argument;
\r
269 this.processResponse(response, a.node, a.callback);
\r
270 this.fireEvent("load", this, a.node, response);
\r
273 handleFailure : function(response){
\r
274 this.transId = false;
\r
275 var a = response.argument;
\r
276 this.fireEvent("loadexception", this, a.node, response);
\r
277 if(typeof a.callback == "function"){
\r
278 a.callback(this, a.node);
\r