Fixed some bugs in the serialization code, it seems to work now.
[jquery.git] / ajax / ajax.js
1 // AJAX Plugin
2 // Docs Here:
3 // http://jquery.com/docs/ajax/
4
5 if ( typeof XMLHttpRequest == 'undefined' && typeof window.ActiveXObject == 'function') {
6         XMLHttpRequest = function() {
7                 return new ActiveXObject((navigator.userAgent.toLowerCase().indexOf('msie 5') >= 0) ?
8                         "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
9         };
10 }
11
12 //
13 // Counter for holding the active query's
14 $.xmlActive=0;
15
16 $.xml = function( type, url, data, ret ) {
17         var xml = new XMLHttpRequest();
18
19         if ( xml ) {
20                 //
21                 // Increase the query counter
22                 $.xmlActive++;
23
24                 //
25                 // Show loader if needed
26                 if ($.xmlCreate) {
27                         $.xmlCreate();
28                 }
29
30                 //
31                 // Open the socket
32                 xml.open(type || "GET", url, true);
33
34                 if ( data ) {
35                         xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
36                 }
37
38                 //
39                 // Set header so calling script knows that it's an XMLHttpRequest
40                 xml.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
41
42                 /* Force "Connection: close" for Mozilla browsers to work around
43                  * a bug where XMLHttpReqeuest sends an incorrect Content-length
44                  * header. See Mozilla Bugzilla #246651.
45                  */
46                 if ( xml.overrideMimeType ) {
47                         xml.setRequestHeader('Connection', 'close');
48                 }
49
50                 xml.onreadystatechange = function() {
51                         if ( xml.readyState == 4 ) {
52                                 if ( ret ) { ret(xml); }
53
54                                 //
55                                 // Decrease counter
56                                 $.xmlActive--;
57
58                                 //
59                                 // Hide loader if needed
60                                 if ($.xmlActive <= 0) {
61                                         if ($.xmlDestroy) {
62                                                 $.xmlDestroy();
63                                         }
64                                 }
65                         }
66                 };
67
68                 xml.send(data);
69         }
70 };
71
72 $.httpData = function(r,type) {
73         return r.getResponseHeader("content-type").indexOf("xml") > 0 || type == "xml" ?
74                 r.responseXML : r.responseText;
75 };
76
77 $.get = function( url, ret, type ) {
78         $.xml( "GET", url, null, function(r) {
79                 if ( ret ) { ret( $.httpData(r,type) ); }
80         });
81 };
82
83 $.getXML = function( url, ret ) {
84         $.get( url, ret, "xml" );
85 };
86
87 $.post = function( url, data, ret, type ) {
88         $.xml( "POST", url, $.param(data), function(r) {
89                 if ( ret ) { ret( $.httpData(r,type) ); }
90         });
91 };
92
93 $.postXML = function( url, data, ret ) {
94         $.post( url, data, ret, "xml" );
95 };
96
97 $.param = function(a) {
98         var s = [];
99         if (a && typeof a == 'object' && a.constructor == Array) {
100                 for ( var i=0; i < a.length; i++ ) {
101                         s[s.length] = a[i].name + "=" + encodeURIComponent( a[i].value );
102                 }
103         } else {
104                 for ( var j in a ) {
105                         s[s.length] = j + "=" + encodeURIComponent( a[j] );
106                 }
107         }
108         return s.join("&");
109 };
110
111 $.fn.load = function(a,o,f) {
112         // Arrrrghhhhhhhh!!
113         // I overwrote the event plugin's .load
114         // this won't happen again, I hope -John
115         if ( a && a.constructor == Function ) {
116                 return this.bind("load", a);
117         }
118
119         var t = "GET";
120         if ( o && o.constructor == Function ) {
121                 f = o;
122                 o = null;
123         }
124         if (o !== null) {
125                 o = $.param(o);
126                 t = "POST";
127         }
128         var self = this;
129         $.xml(t,a,o,function(h){
130                 h = h.responseText;
131                 self.html(h).find("script").each(function(){
132                         try {
133                                 $.eval( this.text || this.textContent || this.innerHTML );
134                         } catch(e){}
135                 });
136                 if(f){f(h);}
137         });
138         return this;
139 };
140
141 /**
142  * function: $.fn.formValues
143  * usage: $('#frmLogin').formValues()
144  * docs: Gets form values and creates a key=>value array of the found values (for ENABLED elements!)
145  */
146 $.fn.formValues = function() {
147         var a = [];
148         $("input,textarea,option",this).filter(":enabled").each(function(){
149                 // Skip selects with options which are not selected
150                 if ((this.parentNode.type == 'select-one' || this.parentNode.type == 'select-multiple') && !this.selected) {
151                         return null;
152                 }
153
154                 // Skip radio and checkbox elements which are not checked
155                 if ((this.type == 'radio' || this.type == 'checkbox') && !this.checked) {
156                         return null;
157                 }
158
159                 // All other elements are valid
160                 a.push({
161                         name: this.name || this.id || this.parentNode.name || this.parentNode.id,
162                         value: this.value
163                 });
164         });
165         return a;
166 };
167
168 /**
169  * function: $.update
170  * usage: $.update('someJQueryObject', 'someurl', 'array');
171  * docs: Mimics the ajaxUpdater from prototype. Posts the key=>value array to the url and
172  * puts the results from that call in the jQuery object specified.
173  * --> If you set the blnNoEval to true, the script tags are NOT evaluated.
174  */
175 $.update = function(objElement, strURL, arrValues, fncCallback) {
176         $.post(strURL, arrValues, function(strHTML) {
177                 // Update the element with the new HTML
178                 objElement.html(strHTML);
179
180                 // Evaluate the scripts
181                 objElement.html(strHTML).find("script").each(function(){
182                         try {
183                                 $.eval( this.text || this.textContent || this.innerHTML );
184                         } catch(e) { }
185                 });
186
187                 // Callback handler
188                 if (fncCallback) { fncCallback(); }
189         });
190 };