7 * provide a simple Ajax request utility functions
9 * Portions of this file are based on pieces of Yahoo User Interface Library
10 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
11 * YUI licensed under the BSD License:
12 * http://developer.yahoo.net/yui/license.txt
13 * <script type="text/javascript">
21 request : function(method, uri, cb, data, options) {
23 var hs = options.headers;
26 if(hs.hasOwnProperty(h)){
27 this.initHeader(h, hs[h], false);
32 this.initHeader('Content-Type', 'text/xml', false);
34 data = options.xmlData;
38 return this.asyncRequest(method, uri, cb, data);
44 * @param {DomForm} form element
45 * @return {String} urlencode form output.
47 serializeForm : function(form) {
48 if(typeof form == 'string') {
49 form = (document.getElementById(form) || document.forms[form]);
52 var el, name, val, disabled, data = '', hasSubmit = false;
53 for (var i = 0; i < form.elements.length; i++) {
54 el = form.elements[i];
55 disabled = form.elements[i].disabled;
56 name = form.elements[i].name;
57 val = form.elements[i].value;
59 if (!disabled && name){
63 case 'select-multiple':
64 for (var j = 0; j < el.options.length; j++) {
65 if (el.options[j].selected) {
67 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(el.options[j].attributes['value'].specified ? el.options[j].value : el.options[j].text) + '&';
70 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(el.options[j].hasAttribute('value') ? el.options[j].value : el.options[j].text) + '&';
78 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
91 if(hasSubmit == false) {
92 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
97 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
102 data = data.substr(0, data.length - 1);
110 useDefaultHeader:true,
112 defaultPostHeader:'application/x-www-form-urlencoded',
114 useDefaultXhrHeader:true,
116 defaultXhrHeader:'XMLHttpRequest',
118 hasDefaultHeaders:true,
130 setProgId:function(id)
132 this.activeX.unshift(id);
135 setDefaultPostHeader:function(b)
137 this.useDefaultHeader = b;
140 setDefaultXhrHeader:function(b)
142 this.useDefaultXhrHeader = b;
145 setPollingInterval:function(i)
147 if (typeof i == 'number' && isFinite(i)) {
148 this.pollInterval = i;
152 createXhrObject:function(transactionId)
158 http = new XMLHttpRequest();
160 obj = { conn:http, tId:transactionId };
164 for (var i = 0; i < this.activeX.length; ++i) {
168 http = new ActiveXObject(this.activeX[i]);
170 obj = { conn:http, tId:transactionId };
183 getConnectionObject:function()
186 var tId = this.transactionId;
190 o = this.createXhrObject(tId);
192 this.transactionId++;
203 asyncRequest:function(method, uri, callback, postData)
205 var o = this.getConnectionObject();
211 o.conn.open(method, uri, true);
213 if (this.useDefaultXhrHeader) {
214 if (!this.defaultHeaders['X-Requested-With']) {
215 this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
219 if(postData && this.useDefaultHeader){
220 this.initHeader('Content-Type', this.defaultPostHeader);
223 if (this.hasDefaultHeaders || this.hasHeaders) {
227 this.handleReadyState(o, callback);
228 o.conn.send(postData || null);
234 handleReadyState:function(o, callback)
238 if (callback && callback.timeout) {
240 this.timeout[o.tId] = window.setTimeout(function() {
241 oConn.abort(o, callback, true);
242 }, callback.timeout);
245 this.poll[o.tId] = window.setInterval(
247 if (o.conn && o.conn.readyState == 4) {
248 window.clearInterval(oConn.poll[o.tId]);
249 delete oConn.poll[o.tId];
251 if(callback && callback.timeout) {
252 window.clearTimeout(oConn.timeout[o.tId]);
253 delete oConn.timeout[o.tId];
256 oConn.handleTransactionResponse(o, callback);
259 , this.pollInterval);
262 handleTransactionResponse:function(o, callback, isAbort)
266 this.releaseObject(o);
270 var httpStatus, responseObject;
274 if (o.conn.status !== undefined && o.conn.status != 0) {
275 httpStatus = o.conn.status;
287 if (httpStatus >= 200 && httpStatus < 300) {
288 responseObject = this.createResponseObject(o, callback.argument);
289 if (callback.success) {
290 if (!callback.scope) {
291 callback.success(responseObject);
296 callback.success.apply(callback.scope, [responseObject]);
301 switch (httpStatus) {
309 responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
310 if (callback.failure) {
311 if (!callback.scope) {
312 callback.failure(responseObject);
315 callback.failure.apply(callback.scope, [responseObject]);
320 responseObject = this.createResponseObject(o, callback.argument);
321 if (callback.failure) {
322 if (!callback.scope) {
323 callback.failure(responseObject);
326 callback.failure.apply(callback.scope, [responseObject]);
332 this.releaseObject(o);
333 responseObject = null;
336 createResponseObject:function(o, callbackArg)
343 var headerStr = o.conn.getAllResponseHeaders();
344 var header = headerStr.split('\n');
345 for (var i = 0; i < header.length; i++) {
346 var delimitPos = header[i].indexOf(':');
347 if (delimitPos != -1) {
348 headerObj[header[i].substring(0, delimitPos)] = header[i].substring(delimitPos + 2);
356 obj.status = o.conn.status;
357 obj.statusText = o.conn.statusText;
358 obj.getResponseHeader = headerObj;
359 obj.getAllResponseHeaders = headerStr;
360 obj.responseText = o.conn.responseText;
361 obj.responseXML = o.conn.responseXML;
363 if (typeof callbackArg !== undefined) {
364 obj.argument = callbackArg;
370 createExceptionObject:function(tId, callbackArg, isAbort)
373 var COMM_ERROR = 'communication failure';
375 var ABORT_ERROR = 'transaction aborted';
381 obj.status = ABORT_CODE;
382 obj.statusText = ABORT_ERROR;
385 obj.status = COMM_CODE;
386 obj.statusText = COMM_ERROR;
390 obj.argument = callbackArg;
396 initHeader:function(label, value, isDefault)
398 var headerObj = (isDefault) ? this.defaultHeaders : this.headers;
400 if (headerObj[label] === undefined) {
401 headerObj[label] = value;
406 headerObj[label] = value + "," + headerObj[label];
410 this.hasDefaultHeaders = true;
413 this.hasHeaders = true;
418 setHeader:function(o)
420 if (this.hasDefaultHeaders) {
421 for (var prop in this.defaultHeaders) {
422 if (this.defaultHeaders.hasOwnProperty(prop)) {
423 o.conn.setRequestHeader(prop, this.defaultHeaders[prop]);
428 if (this.hasHeaders) {
429 for (var prop in this.headers) {
430 if (this.headers.hasOwnProperty(prop)) {
431 o.conn.setRequestHeader(prop, this.headers[prop]);
435 this.hasHeaders = false;
439 resetDefaultHeaders:function() {
440 delete this.defaultHeaders;
441 this.defaultHeaders = {};
442 this.hasDefaultHeaders = false;
445 abort:function(o, callback, isTimeout)
447 if(this.isCallInProgress(o)) {
449 window.clearInterval(this.poll[o.tId]);
450 delete this.poll[o.tId];
452 delete this.timeout[o.tId];
455 this.handleTransactionResponse(o, callback, true);
465 isCallInProgress:function(o)
468 return o.conn.readyState != 4 && o.conn.readyState != 0;
477 releaseObject:function(o)
486 'MSXML2.XMLHTTP.3.0',