Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[extjs.git] / docs / source / ext-base-ajax.html
1 <html>\r
2 <head>\r
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    \r
4   <title>The source code</title>\r
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
7 </head>\r
8 <body  onload="prettyPrint();">\r
9     <pre class="prettyprint lang-js">/*\r
10 * Portions of this file are based on pieces of Yahoo User Interface Library\r
11 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.\r
12 * YUI licensed under the BSD License:\r
13 * http://developer.yahoo.net/yui/license.txt\r
14 */\r
15 Ext.lib.Ajax = function() {     \r
16     var activeX = ['MSXML2.XMLHTTP.3.0',\r
17                    'MSXML2.XMLHTTP',\r
18                    'Microsoft.XMLHTTP'],\r
19         CONTENTTYPE = 'Content-Type';\r
20                    \r
21     // private\r
22     function setHeader(o) {\r
23         var conn = o.conn,\r
24             prop;\r
25         \r
26         function setTheHeaders(conn, headers){\r
27             for (prop in headers) {\r
28                 if (headers.hasOwnProperty(prop)) {\r
29                     conn.setRequestHeader(prop, headers[prop]);\r
30                 }\r
31             }   \r
32         }       \r
33         \r
34         if (pub.defaultHeaders) {\r
35             setTheHeaders(conn, pub.defaultHeaders);\r
36         }\r
37 \r
38         if (pub.headers) {\r
39             setTheHeaders(conn, pub.headers);\r
40             delete pub.headers;                \r
41         }\r
42     }    \r
43     \r
44     // private\r
45     function createExceptionObject(tId, callbackArg, isAbort, isTimeout) {          \r
46         return {\r
47             tId : tId,\r
48             status : isAbort ? -1 : 0,\r
49             statusText : isAbort ? 'transaction aborted' : 'communication failure',\r
50             isAbort: isAbort,\r
51             isTimeout: isTimeout,\r
52             argument : callbackArg\r
53         };\r
54     }  \r
55     \r
56     // private \r
57     function initHeader(label, value) {         \r
58         (pub.headers = pub.headers || {})[label] = value;                       \r
59     }\r
60     \r
61     // private\r
62     function createResponseObject(o, callbackArg) {\r
63         var headerObj = {},\r
64             headerStr,              \r
65             conn = o.conn,\r
66             t,\r
67             s;\r
68 \r
69         try {\r
70             headerStr = o.conn.getAllResponseHeaders();   \r
71             Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){\r
72                 t = v.indexOf(':');\r
73                 if(t >= 0){\r
74                     s = v.substr(0, t).toLowerCase();\r
75                     if(v.charAt(t + 1) == ' '){\r
76                         ++t;\r
77                     }\r
78                     headerObj[s] = v.substr(t + 1);\r
79                 }\r
80             });\r
81         } catch(e) {}\r
82                     \r
83         return {\r
84             tId : o.tId,\r
85             status : conn.status,\r
86             statusText : conn.statusText,\r
87             getResponseHeader : function(header){return headerObj[header.toLowerCase()];},\r
88             getAllResponseHeaders : function(){return headerStr},\r
89             responseText : conn.responseText,\r
90             responseXML : conn.responseXML,\r
91             argument : callbackArg\r
92         };\r
93     }\r
94     \r
95     // private\r
96     function releaseObject(o) {\r
97         o.conn = null;\r
98         o = null;\r
99     }        \r
100     \r
101     // private\r
102     function handleTransactionResponse(o, callback, isAbort, isTimeout) {\r
103         if (!callback) {\r
104             releaseObject(o);\r
105             return;\r
106         }\r
107 \r
108         var httpStatus, responseObject;\r
109 \r
110         try {\r
111             if (o.conn.status !== undefined && o.conn.status != 0) {\r
112                 httpStatus = o.conn.status;\r
113             }\r
114             else {\r
115                 httpStatus = 13030;\r
116             }\r
117         }\r
118         catch(e) {\r
119             httpStatus = 13030;\r
120         }\r
121 \r
122         if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {\r
123             responseObject = createResponseObject(o, callback.argument);\r
124             if (callback.success) {\r
125                 if (!callback.scope) {\r
126                     callback.success(responseObject);\r
127                 }\r
128                 else {\r
129                     callback.success.apply(callback.scope, [responseObject]);\r
130                 }\r
131             }\r
132         }\r
133         else {\r
134             switch (httpStatus) {\r
135                 case 12002:\r
136                 case 12029:\r
137                 case 12030:\r
138                 case 12031:\r
139                 case 12152:\r
140                 case 13030:\r
141                     responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout);\r
142                     if (callback.failure) {\r
143                         if (!callback.scope) {\r
144                             callback.failure(responseObject);\r
145                         }\r
146                         else {\r
147                             callback.failure.apply(callback.scope, [responseObject]);\r
148                         }\r
149                     }\r
150                     break;\r
151                 default:\r
152                     responseObject = createResponseObject(o, callback.argument);\r
153                     if (callback.failure) {\r
154                         if (!callback.scope) {\r
155                             callback.failure(responseObject);\r
156                         }\r
157                         else {\r
158                             callback.failure.apply(callback.scope, [responseObject]);\r
159                         }\r
160                     }\r
161             }\r
162         }\r
163 \r
164         releaseObject(o);\r
165         responseObject = null;\r
166     }  \r
167     \r
168     // private\r
169     function handleReadyState(o, callback){\r
170     callback = callback || {};\r
171         var conn = o.conn,\r
172             tId = o.tId,\r
173             poll = pub.poll,\r
174             cbTimeout = callback.timeout || null;\r
175 \r
176         if (cbTimeout) {\r
177             pub.timeout[tId] = setTimeout(function() {\r
178                 pub.abort(o, callback, true);\r
179             }, cbTimeout);\r
180         }\r
181 \r
182         poll[tId] = setInterval(\r
183             function() {\r
184                 if (conn && conn.readyState == 4) {\r
185                     clearInterval(poll[tId]);\r
186                     poll[tId] = null;\r
187 \r
188                     if (cbTimeout) {\r
189                         clearTimeout(pub.timeout[tId]);\r
190                         pub.timeout[tId] = null;\r
191                     }\r
192 \r
193                     handleTransactionResponse(o, callback);\r
194                 }\r
195             },\r
196             pub.pollInterval);\r
197     }\r
198     \r
199     // private\r
200     function asyncRequest(method, uri, callback, postData) {\r
201         var o = getConnectionObject() || null;\r
202 \r
203         if (o) {\r
204             o.conn.open(method, uri, true);\r
205 \r
206             if (pub.useDefaultXhrHeader) {                    \r
207                 initHeader('X-Requested-With', pub.defaultXhrHeader);\r
208             }\r
209 \r
210             if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){\r
211                 initHeader(CONTENTTYPE, pub.defaultPostHeader);\r
212             }\r
213 \r
214             if (pub.defaultHeaders || pub.headers) {\r
215                 setHeader(o);\r
216             }\r
217 \r
218             handleReadyState(o, callback);\r
219             o.conn.send(postData || null);\r
220         }\r
221         return o;\r
222     }\r
223     \r
224     // private\r
225     function getConnectionObject() {\r
226         var o;          \r
227 \r
228         try {\r
229             if (o = createXhrObject(pub.transactionId)) {\r
230                 pub.transactionId++;\r
231             }\r
232         } catch(e) {\r
233         } finally {\r
234             return o;\r
235         }\r
236     }\r
237        \r
238     // private\r
239     function createXhrObject(transactionId) {\r
240         var http;\r
241             \r
242         try {\r
243             http = new XMLHttpRequest();                \r
244         } catch(e) {\r
245             for (var i = 0; i < activeX.length; ++i) {              \r
246                 try {\r
247                     http = new ActiveXObject(activeX[i]);                        \r
248                     break;\r
249                 } catch(e) {}\r
250             }\r
251         } finally {\r
252             return {conn : http, tId : transactionId};\r
253         }\r
254     }\r
255          \r
256     var pub = {\r
257         request : function(method, uri, cb, data, options) {\r
258             if(options){\r
259                 var me = this,              \r
260                     xmlData = options.xmlData,\r
261                     jsonData = options.jsonData,\r
262                     hs;\r
263                     \r
264                 Ext.applyIf(me, options);           \r
265                 \r
266                 if(xmlData || jsonData){\r
267                     hs = me.headers;\r
268                     if(!hs || !hs[CONTENTTYPE]){\r
269                         initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json');\r
270                     }\r
271                     data = xmlData || (!Ext.isPrimitive(jsonData) ? Ext.encode(jsonData) : jsonData);\r
272                 }\r
273             }                       \r
274             return asyncRequest(method || options.method || "POST", uri, cb, data);\r
275         },\r
276 \r
277         serializeForm : function(form) {\r
278             var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,\r
279                 hasSubmit = false,\r
280                 encoder = encodeURIComponent,\r
281                 element,\r
282                 options, \r
283                 name, \r
284                 val,                \r
285                 data = '',\r
286                 type;\r
287                 \r
288             Ext.each(fElements, function(element) {                 \r
289                 name = element.name;                 \r
290                 type = element.type;\r
291                 \r
292                 if (!element.disabled && name){\r
293                     if(/select-(one|multiple)/i.test(type)) {\r
294                         Ext.each(element.options, function(opt) {\r
295                             if (opt.selected) {\r
296                                 data += String.format("{0}={1}&", encoder(name), encoder((opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttribute('value') !== null) ? opt.value : opt.text));\r
297                             }                               \r
298                         });\r
299                     } else if(!/file|undefined|reset|button/i.test(type)) {\r
300                             if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){\r
301                                 \r
302                                 data += encoder(name) + '=' + encoder(element.value) + '&';                     \r
303                                 hasSubmit = /submit/i.test(type);    \r
304                             }                       \r
305                     } \r
306                 }\r
307             });            \r
308             return data.substr(0, data.length - 1);\r
309         },\r
310         \r
311         useDefaultHeader : true,\r
312         defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',\r
313         useDefaultXhrHeader : true,\r
314         defaultXhrHeader : 'XMLHttpRequest',        \r
315         poll : {},\r
316         timeout : {},\r
317         pollInterval : 50,\r
318         transactionId : 0,\r
319         \r
320 //  This is never called - Is it worth exposing this?               \r
321 //          setProgId : function(id) {\r
322 //              activeX.unshift(id);\r
323 //          },\r
324 \r
325 //  This is never called - Is it worth exposing this?   \r
326 //          setDefaultPostHeader : function(b) {\r
327 //              this.useDefaultHeader = b;\r
328 //          },\r
329         \r
330 //  This is never called - Is it worth exposing this?   \r
331 //          setDefaultXhrHeader : function(b) {\r
332 //              this.useDefaultXhrHeader = b;\r
333 //          },\r
334 \r
335 //  This is never called - Is it worth exposing this?           \r
336 //          setPollingInterval : function(i) {\r
337 //              if (typeof i == 'number' && isFinite(i)) {\r
338 //                  this.pollInterval = i;\r
339 //              }\r
340 //          },\r
341         \r
342 //  This is never called - Is it worth exposing this?\r
343 //          resetDefaultHeaders : function() {\r
344 //              this.defaultHeaders = null;\r
345 //          },\r
346     \r
347             abort : function(o, callback, isTimeout) {\r
348                 var me = this,\r
349                     tId = o.tId,\r
350                     isAbort = false;\r
351                 \r
352                 if (me.isCallInProgress(o)) {\r
353                     o.conn.abort();\r
354                     clearInterval(me.poll[tId]);\r
355                     me.poll[tId] = null;\r
356                     clearTimeout(pub.timeout[tId]);\r
357                     me.timeout[tId] = null;\r
358                     \r
359                     handleTransactionResponse(o, callback, (isAbort = true), isTimeout);                \r
360                 }\r
361                 return isAbort;\r
362             },\r
363     \r
364             isCallInProgress : function(o) {\r
365                 // if there is a connection and readyState is not 0 or 4\r
366                 return o.conn && !{0:true,4:true}[o.conn.readyState];           \r
367             }\r
368         };\r
369         return pub;\r
370     }();</pre>    \r
371 </body>\r
372 </html>