jquery ajax: closes #4994. Adding 'context' setting to $.ajax
authorAriel Flesler <aflesler@gmail.com>
Tue, 15 Sep 2009 15:19:58 +0000 (15:19 +0000)
committerAriel Flesler <aflesler@gmail.com>
Tue, 15 Sep 2009 15:19:58 +0000 (15:19 +0000)
src/ajax.js
test/unit/ajax.js

index 62b3ac0..f8ac52e 100644 (file)
@@ -41,21 +41,20 @@ jQuery.fn.extend({
                        }
                }
 
-               var self = this;
-
                // Request the remote document
                jQuery.ajax({
                        url: url,
                        type: type,
                        dataType: "html",
                        data: params,
+                       context:this,
                        complete: function(res, status){
                                // If successful, inject the HTML into all the matched elements
                                if ( status === "success" || status === "notmodified" ) {
                                        // See if a selector was specified
-                                       self.html( selector ?
+                                       this.html( selector ?
                                                // Create a dummy div to hold the results
-                                               jQuery("<div/>")
+                                               jQuery("<div />")
                                                        // inject the contents of the document in, removing the scripts
                                                        // to avoid any 'Permission Denied' errors in IE
                                                        .append(res.responseText.replace(rscript, ""))
@@ -68,7 +67,7 @@ jQuery.fn.extend({
                                }
 
                                if ( callback ) {
-                                       self.each( callback, [res.responseText, status, res] );
+                                       this.each( callback, [res.responseText, status, res] );
                                }
                        }
                });
@@ -193,8 +192,9 @@ jQuery.extend({
                // Extend the settings, but re-extend 's' so that it can be
                // checked again later (in the test suite, specifically)
                s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
-
+               
                var jsonp, status, data,
+                       callbackContext = s.context || window,
                        type = s.type.toUpperCase();
 
                // convert data if not already a string
@@ -352,7 +352,7 @@ jQuery.extend({
                } catch(e){}
 
                // Allow custom headers/mimetypes and early abort
-               if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+               if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
                        // Handle the global AJAX counter
                        if ( s.global && ! --jQuery.active ) {
                                jQuery.event.trigger( "ajaxStop" );
@@ -364,7 +364,7 @@ jQuery.extend({
                }
 
                if ( s.global ) {
-                       jQuery.event.trigger("ajaxSend", [xhr, s]);
+                       trigger("ajaxSend", [xhr, s]);
                }
 
                // Wait for a response to come back
@@ -464,24 +464,24 @@ jQuery.extend({
                function success(){
                        // If a local callback was specified, fire it and pass it the data
                        if ( s.success ) {
-                               s.success( data, status );
+                               s.success.call( callbackContext, data, status );
                        }
 
                        // Fire the global callback
                        if ( s.global ) {
-                               jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+                               trigger( "ajaxSuccess", [xhr, s] );
                        }
                }
 
                function complete(){
                        // Process result
                        if ( s.complete ) {
-                               s.complete(xhr, status);
+                               s.complete.call( callbackContext, xhr, status);
                        }
 
                        // The request was completed
                        if ( s.global ) {
-                               jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+                               trigger( "ajaxComplete", [xhr, s] );
                        }
 
                        // Handle the global AJAX counter
@@ -489,6 +489,10 @@ jQuery.extend({
                                jQuery.event.trigger( "ajaxStop" );
                        }
                }
+               
+               function trigger(type, args){
+                       (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+               }
 
                // return XMLHttpRequest to allow aborting the request etc.
                return xhr;
@@ -497,12 +501,12 @@ jQuery.extend({
        handleError: function( s, xhr, status, e ) {
                // If a local callback was specified, fire it
                if ( s.error ) {
-                       s.error( xhr, status, e );
+                       s.error.call( s.context || window, xhr, status, e );
                }
 
                // Fire the global callback
                if ( s.global ) {
-                       jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+                       (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
                }
        },
 
index fb328bc..4478c9b 100644 (file)
@@ -70,6 +70,44 @@ test("jQuery.ajax() - error callbacks", function() {
        });
 });
 
+test("Ajax events with context", function() {
+       expect(6);
+       
+       stop();
+       var context = {};
+       
+       function event(e){
+               equals( this, context, e.type );
+       }
+
+       function callback(){
+               equals( this, context, "context is preserved on callback" );
+       }
+       
+       jQuery('#foo').add(context)
+                       .ajaxSend(event)
+                       .ajaxComplete(event)
+                       .ajaxError(event)
+                       .ajaxSuccess(event);
+
+       jQuery.ajax({
+               url: url("data/name.html"),
+               beforeSend: callback,
+               success: callback,
+               error: callback,
+               complete:function(){
+                       callback.call(this);
+                       setTimeout(proceed, 300);
+               },
+               context:context
+       });
+       
+       function proceed(){
+               jQuery('#foo').add(context).unbind();
+               start();
+       }
+});
+
 test("jQuery.ajax() - disabled globals", function() {
        expect( 3 );
        stop();
@@ -284,19 +322,20 @@ test("pass-through request object", function() {
 
 test("ajax cache", function () {
        expect(18);
+       
        stop();
 
        var count = 0;
 
        jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
                var re = /_=(.*?)(&|$)/g;
-       var oldOne = null;
+               var oldOne = null;
                for (var i = 0; i < 6; i++) {
-         var ret = re.exec(s.url);
+                       var ret = re.exec(s.url);
                        if (!ret) {
                                break;
                        }
-         oldOne = ret[1];
+                       oldOne = ret[1];
                }
                equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
                ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");