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, include_disabled) {
49 include_disabled = typeof(include_disabled) == 'undefined' ? false : include_disabled;
51 if(typeof form == 'string') {
52 form = (document.getElementById(form) || document.forms[form]);
55 var el, name, val, disabled, data = '', hasSubmit = false;
56 for (var i = 0; i < form.elements.length; i++) {
57 el = form.elements[i];
58 disabled = include_disabled ? false : form.elements[i].disabled;
59 name = form.elements[i].name;
60 val = form.elements[i].value;
62 if (!disabled && name){
66 case 'select-multiple':
67 for (var j = 0; j < el.options.length; j++) {
68 if (el.options[j].selected) {
70 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(el.options[j].attributes['value'].specified ? el.options[j].value : el.options[j].text) + '&';
73 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(el.options[j].hasAttribute('value') ? el.options[j].value : el.options[j].text) + '&';
81 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
94 if(hasSubmit == false) {
95 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
100 data += Roo.encodeURIComponent(name) + '=' + Roo.encodeURIComponent(val) + '&';
105 data = data.substr(0, data.length - 1);
113 useDefaultHeader:true,
115 defaultPostHeader:'application/x-www-form-urlencoded',
117 useDefaultXhrHeader:true,
119 defaultXhrHeader:'XMLHttpRequest',
121 hasDefaultHeaders:true,
133 setProgId:function(id)
135 this.activeX.unshift(id);
138 setDefaultPostHeader:function(b)
140 this.useDefaultHeader = b;
143 setDefaultXhrHeader:function(b)
145 this.useDefaultXhrHeader = b;
148 setPollingInterval:function(i)
150 if (typeof i == 'number' && isFinite(i)) {
151 this.pollInterval = i;
155 createXhrObject:function(transactionId)
161 http = new XMLHttpRequest();
163 obj = { conn:http, tId:transactionId };
167 for (var i = 0; i < this.activeX.length; ++i) {
171 http = new ActiveXObject(this.activeX[i]);
173 obj = { conn:http, tId:transactionId };
186 getConnectionObject:function()
189 var tId = this.transactionId;
193 o = this.createXhrObject(tId);
195 this.transactionId++;
206 asyncRequest:function(method, uri, callback, postData)
208 var o = this.getConnectionObject();
214 o.conn.open(method, uri, true);
216 if (this.useDefaultXhrHeader) {
217 if (!this.defaultHeaders['X-Requested-With']) {
218 this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
222 if(postData && this.useDefaultHeader){
223 this.initHeader('Content-Type', this.defaultPostHeader);
226 if (this.hasDefaultHeaders || this.hasHeaders) {
230 this.handleReadyState(o, callback);
231 o.conn.send(postData || null);
237 handleReadyState:function(o, callback)
241 if (callback && callback.timeout) {
243 this.timeout[o.tId] = window.setTimeout(function() {
244 oConn.abort(o, callback, true);
245 }, callback.timeout);
248 this.poll[o.tId] = window.setInterval(
250 if (o.conn && o.conn.readyState == 4) {
251 window.clearInterval(oConn.poll[o.tId]);
252 delete oConn.poll[o.tId];
254 if(callback && callback.timeout) {
255 window.clearTimeout(oConn.timeout[o.tId]);
256 delete oConn.timeout[o.tId];
259 oConn.handleTransactionResponse(o, callback);
262 , this.pollInterval);
265 handleTransactionResponse:function(o, callback, isAbort)
269 this.releaseObject(o);
273 var httpStatus, responseObject;
277 if (o.conn.status !== undefined && o.conn.status != 0) {
278 httpStatus = o.conn.status;
290 if (httpStatus >= 200 && httpStatus < 300) {
291 responseObject = this.createResponseObject(o, callback.argument);
292 if (callback.success) {
293 if (!callback.scope) {
294 callback.success(responseObject);
299 callback.success.apply(callback.scope, [responseObject]);
304 switch (httpStatus) {
312 responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
313 if (callback.failure) {
314 if (!callback.scope) {
315 callback.failure(responseObject);
318 callback.failure.apply(callback.scope, [responseObject]);
323 responseObject = this.createResponseObject(o, callback.argument);
324 if (callback.failure) {
325 if (!callback.scope) {
326 callback.failure(responseObject);
329 callback.failure.apply(callback.scope, [responseObject]);
335 this.releaseObject(o);
336 responseObject = null;
339 createResponseObject:function(o, callbackArg)
346 var headerStr = o.conn.getAllResponseHeaders();
347 var header = headerStr.split('\n');
348 for (var i = 0; i < header.length; i++) {
349 var delimitPos = header[i].indexOf(':');
350 if (delimitPos != -1) {
351 headerObj[header[i].substring(0, delimitPos)] = header[i].substring(delimitPos + 2);
359 obj.status = o.conn.status;
360 obj.statusText = o.conn.statusText;
361 obj.getResponseHeader = headerObj;
362 obj.getAllResponseHeaders = headerStr;
363 obj.responseText = o.conn.responseText;
364 obj.responseXML = o.conn.responseXML;
366 if (typeof callbackArg !== undefined) {
367 obj.argument = callbackArg;
373 createExceptionObject:function(tId, callbackArg, isAbort)
376 var COMM_ERROR = 'communication failure';
378 var ABORT_ERROR = 'transaction aborted';
384 obj.status = ABORT_CODE;
385 obj.statusText = ABORT_ERROR;
388 obj.status = COMM_CODE;
389 obj.statusText = COMM_ERROR;
393 obj.argument = callbackArg;
399 initHeader:function(label, value, isDefault)
401 var headerObj = (isDefault) ? this.defaultHeaders : this.headers;
403 if (headerObj[label] === undefined) {
404 headerObj[label] = value;
409 headerObj[label] = value + "," + headerObj[label];
413 this.hasDefaultHeaders = true;
416 this.hasHeaders = true;
421 setHeader:function(o)
423 if (this.hasDefaultHeaders) {
424 for (var prop in this.defaultHeaders) {
425 if (this.defaultHeaders.hasOwnProperty(prop)) {
426 o.conn.setRequestHeader(prop, this.defaultHeaders[prop]);
431 if (this.hasHeaders) {
432 for (var prop in this.headers) {
433 if (this.headers.hasOwnProperty(prop)) {
434 o.conn.setRequestHeader(prop, this.headers[prop]);
438 this.hasHeaders = false;
442 resetDefaultHeaders:function() {
443 delete this.defaultHeaders;
444 this.defaultHeaders = {};
445 this.hasDefaultHeaders = false;
448 abort:function(o, callback, isTimeout)
450 if(this.isCallInProgress(o)) {
452 window.clearInterval(this.poll[o.tId]);
453 delete this.poll[o.tId];
455 delete this.timeout[o.tId];
458 this.handleTransactionResponse(o, callback, true);
468 isCallInProgress:function(o)
471 return o.conn.readyState != 4 && o.conn.readyState != 0;
480 releaseObject:function(o)
489 'MSXML2.XMLHTTP.3.0',