August 16th, 2007
No Comments

Ajax Responder in MooTools

Some developers coming from Prototype might know Ajax Responders. Global events for all Ajax requests on the site. Most frameworks have extra Objects/Classes for them, here is how you can add them with a few lines to your MooTools code. It also shows how to extend a Class, explains Events and Options and how to work with inheritance.

The Goal

This is what we want to achieve: Every Ajax class in our code should fire a global onRequest, onComplete and onFailure. For this example we add only a logging to those events, you also can add your blinking/spinning/jumping loading animations there.

These are our events that we want to have in every Ajax instance:

// An object, holding all our site specific code (just to keep our code clean and namespaced).
var Site = {

    // You can also add an effect here or count running requests.
    'onAjaxRequest': function() {
        // "this", the scope of your function, is the Ajax instance. Everywhere in Mootools
        // where you use addEvent on a Class or an Element, "this" is always the Class/Element
        // in your callback
        $('log').adopt(new Element('li').setHTML('Requesting "' + this.url + '" ...'));
        // "url" is a property in Ajax that holds the given url
    },

    'onAjaxComplete': function() {
        $('log').adopt(new Element('li').setHTML('Completed "' + this.url + '"!'));
    },

    'onAjaxFailure': function() {
        $('log').adopt(new Element('li').setHTML('Failed requesting "' + this.url + '"!'));
    }

}

The Basics (Ajax, Options, Events, Chaining)

This is how we add these events to 1 Ajax instance. This also explains how Events on Classes and Options work:

// Get an Element by id
var content = $('content');

// A new Ajax instance, for updating content and 2 events
// setOptions, used in Ajax::initialize, automatically adds
// Events given in your options.
var updater = new Ajax(url, {
    'update': content,
    'onRequest': function() {
        content.setStyle('opacity', 0.2);
    },
    'onComplete': function() {
        content.setStyle('opacity', 1);
    }
});

// Now the updater instance has 2 onRequest, 2 onComplete and 1 onFailure events.
updater.addEvent('onRequest', Site.onAjaxRequest);
updater.addEvent('onComplete', Site.onAjaxComplete);
updater.addEvent('onFailure', Site.onAjaxFailure);

// Finally, the request
updater.request();

Chained version, the same code for the Ajax instance as above, but chained. Makes the code easier to read and shorter. In MooTools nearly every class method is chainable.

var updater = new Ajax(url, {
    'update': content,
    'onRequest': function() {
        content.setStyle('opacity', 0.2);
    },
    'onComplete': function() {
        content.setStyle('opacity', 1);
    }
}).addEvents({
    'onRequest': Site.onAjaxRequest,
    'onComplete': Site.onAjaxComplete,
    'onFailure': Site.onAjaxFailure
}).request();

Ok, 1 instance now has the events, but for a global event every Ajax instance should have these events. There are several possibilities to add events to all instances of a Class.

The Possibilities

Extending the Ajax class

This first code extends Ajax and adds the event in initialize. initialize is called when you create a new Ajax instance with … new Ajax(url); ….

Ajax = Ajax.extend({

    initialize: function(url, options) {
        // this.parent refers to the original initialize method
        this.parent(url, options);
        this.addEvents({
            'onRequest': Site.onAjaxRequest,
            'onComplete': Site.onAjaxComplete,
            'onFailure': Site.onAjaxFailure
        });
    }

});

Now every new Ajax instance instance has our global request events, they are added in initialize.

Extending the prototype

The other way to add them is the prototype. The Ajax Class is basically a function. Ajax.prototype holds all the methods for an Ajax instance.

Ajax.prototype.addEvents({
    'onRequest': Site.onAjaxRequest,
    'onComplete': Site.onAjaxComplete,
    'onFailure': Site.onAjaxFailure
});

So, result is, that Ajax.protoype has the events (they are saved internally in the property $events, this means here Ajax.prototype.$events). This does not use inheritance, it simply uses the internal event handling on the class prototype. It’s the cleanest and fastest way to add events to every class instance. This last method brings problems when you have multiple Ajax instances since every instance uses the same event stack, its copied as reference from the prototype, my fault. ;-) new Ajax().$events == Ajax.prototype.$events I suggest to use the first code, extending the Ajax class to add your events. Its cleaner, easier to read and you have the chance to add more customized code.

Keywords:
Share it: Stumble it!Digg This!del.icio.us (No Posts)

discussion by DISQUS No Comments

Please use the support forums for discussing the project, asking questions or posting bug-fixes!

Sort:
No Comments
  • First
  • ‹ Prev
  • Next ›
  • Last
No Comments
  • First
  • ‹ Prev
  • Next ›
  • Last

Post your comment

Please use the support forums for discussing the project, asking questions or posting bug-fixes!


Internet Consultant & Contractor

I'm available to combine forces with you and your team to find the most simple, elegant and convenient web solutions . I await your call.

If you just like my work and want to say Thank You, donate via PayPal or Amazon Wish List.

Developer Resources & Tools