Organized the event functions.
[jquery.git] / ajax / ajax.js
1 // AJAX Plugin
2 // Docs Here:
3 // http://jquery.com/docs/ajax/
4
5 /**
6  * Load HTML from a remote file and inject it into the DOM
7  */
8 $.fn.load = function( url, params, callback ) {
9         // I overwrote the event plugin's .load
10         // this won't happen again, I hope -John
11         if ( url && url.constructor == Function )
12                 return this.bind("load", url);
13
14         // Default to a GET request
15         var type = "GET";
16
17         // If the second parameter was provided
18         if ( params ) {
19                 // If it's a function
20                 if ( params.constructor == Function ) {
21                         // We assume that it's the callback
22                         callback = params;
23                         params = null;
24                         
25                 // Otherwise, build a param string
26                 } else {
27                         params = $.param( params );
28                         type = "POST";
29                 }
30         }
31         
32         var self = this;
33         
34         // Request the remote document
35         $.ajax( type, url, params,function(res){
36                         
37                 // Inject the HTML into all the matched elements
38                 self.html(res.responseText).each(function(){
39                         // If a callback function was provided
40                         if ( callback && callback.constructor == Function )
41                                 // Execute it within the context of the element
42                                 callback.apply( self, [res.responseText] );
43                 });
44                 
45                 // Execute all the scripts inside of the newly-injected HTML
46                 $("script", self).each(function(){
47                         eval( this.text || this.textContent || this.innerHTML || "");
48                 });
49
50         });
51         
52         return this;
53 };
54
55 /**
56  * Load a remote page using a GET request
57  */
58 $.get = function( url, callback, type ) {
59         // Build and start the HTTP Request
60         $.ajax( "GET", url, null, function(r) {
61                 if ( callback ) callback( $.httpData(r,type) );
62         });
63 };
64
65 /**
66  * Load a remote page using a POST request.
67  */
68 $.post = function( url, data, callback, type ) {
69         // Build and start the HTTP Request
70         $.ajax( "POST", url, $.param(data), function(r) {
71                 if ( callback ) callback( $.httpData(r,type) );
72         });
73 };
74
75 // If IE is used, create a wrapper for the XMLHttpRequest object
76 if ( $.browser == "msie" )
77         XMLHttpRequest = function(){
78                 return new ActiveXObject(
79                         (navigator.userAgent.toLowerCase().indexOf("msie 5") >= 0) ?
80                         "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
81                 );
82         };
83
84 // Attach a bunch of functions for handling common AJAX events
85 (function(){
86         var e = "ajaxStart.ajaxComplete.ajaxError.ajaxSuccess".split(',');
87         
88         for ( var i = 0; i < e.length; i++ ){ (function(){
89                 var o = e[i];
90                 $.fn[o] = function(f){return this.bind(o, f);};
91         })();}
92 })();
93
94 /**
95  * A common wrapper for making XMLHttpRequests
96  */
97 $.ajax = function( type, url, data, ret ) {
98         // If only a single argument was passed in,
99         // assume that it is a object of key/value pairs
100         if ( !url ) {
101                 ret = type.complete;
102                 var success = type.success;
103                 var error = type.error;
104                 data = type.data;
105                 url = type.url;
106                 type = type.type;
107         }
108
109         // Create the request object
110         var xml = new XMLHttpRequest();
111
112         // Open the socket
113         xml.open(type || "GET", url, true);
114         
115         // Set the correct header, if data is being sent
116         if ( data )
117                 xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
118
119         // Set header so calling script knows that it's an XMLHttpRequest
120         xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
121
122         // Make sure the browser sends the right content length
123         if ( xml.overrideMimeType )
124                 xml.setRequestHeader("Connection", "close");
125
126         // Wait for a response to come back
127         xml.onreadystatechange = function(){
128                 // Socket is openend
129                 if ( xml.readyState == 1 ) {
130                         // Increase counter
131                         $.ajax.active++;
132
133                         // Show 'loader'
134                         $.event.trigger( "ajaxStart" );
135                 }
136
137                 // Socket is closed and data is available
138                 if ( xml.readyState == 4 ) {
139                         // Hide loader if needed
140                         if ( ! --$.ajax.active ) {
141                                 $.event.trigger( "ajaxComplete" );
142                                 $.ajax.active = 0
143                         }
144
145                         // Make sure that the request was successful
146                         if ( $.httpSuccess( xml ) ) {
147                         
148                                 // If a local callback was specified, fire it
149                                 if ( success ) success( xml );
150                                 
151                                 // Fire the global callback
152                                 $.event.trigger( "ajaxSuccess" );
153                         
154                         // Otherwise, the request was not successful
155                         } else {
156                                 // If a local callback was specified, fire it
157                                 if ( error ) error( xml );
158                                 
159                                 // Fire the global callback
160                                 $.event.trigger( "ajaxError" );
161                         }
162
163                         // Process result
164                         if ( ret ) ret(xml);
165                 }
166         };
167
168         // Send the data
169         xml.send(data);
170 };
171
172 // Counter for holding the number of active queries
173 $.ajax.active = 0;
174
175 // Determines if an XMLHttpRequest was successful or not
176 $.httpSuccess = function(r) {
177         return ( r.status && ( r.status >= 200 && r.status < 300 ) || 
178                 r.status == 304 ) || !r.status && location.protocol == "file:";
179 };
180
181 // Get the data out of an XMLHttpRequest
182 $.httpData = function(r,type) {
183         // Check the headers, or watch for a force override
184         return r.getResponseHeader("content-type").indexOf("xml") > 0 || 
185                 type == "xml" ? r.responseXML : r.responseText;
186 };
187
188 // Serialize an array of form elements or a set of
189 // key/values into a query string
190 $.param = function(a) {
191         var s = [];
192         
193         // If an array was passed in, assume that it is an array
194         // of form elements
195         if ( a.constructor == Array )
196                 // Serialize the form elements
197                 for ( var i = 0; i < a.length; i++ )
198                         s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
199                 
200         // Otherwise, assume that it's an object of key/value pairs
201         else
202                 // Serialize the key/values
203                 for ( var j in a )
204                         s.push( j + "=" + encodeURIComponent( a[j] ) );
205         
206         // Return the resulting serialization
207         return s.join("&");
208 };