sitemap

Chaining with MooTools 1.2 – Tutorial

This guide will show how powerful the MooTools Chain class is. In MooTools chaining facilitates the execution of a stack of functions sequentially and is extremely powerful. I have only tested this in MooTools v1.2 beta 2.

I will be posting more of these short guides on using MooTools in the upcoming weeks. Each will focus on a small problem and solve it with MooTools with the aim of being a useful way to learn the framework.

Chaining you say!

Chaining is very powerful and whilst it is similar to Effect.Queue in Script.aculo.us, it can do much more! The aim of this brief tutorial is to show you how to use MooTools Chaining in the context of queueing effects coupled with other arbitrary actions. However, you will see that you can easily apply Chaining to do much more than that.

From the MooTools 1.2 Docs:

A Utility Class which executes functions one after another, with each function firing after completion of the previous. Its methods can be implemented with Class:implement into any Class, and it is currently implemented in Fx and Request. In Fx, for example, it is used to create custom, complex animations.

Chain can be used as a stand-alone class but becomes much more powerful if you implement it into classes of your own.

In this tutorial I will be creating a class which implements Chain. The Chain class belongs to the Class.Extras component so you will need to make sure that you select Class.Extras and all its dependencies when downloading MooTools.

Implementing Chain

First of all we need to implement the methods and properties of the Chain class into our own class:

var ChainExample = new Class({

  Implements: [Chain]

});

Our class now has the following methods available to it:

  • Chain::chain – Pass any number of functions to add them to the bottom of the call stack.
  • Chain::callChain – Pops a function off the top of the call stack and executes it.
  • Chain::clearChain – Removes all functions from the call stack without executing any.

Using Chain to Execute Actions in Order

Now we have implemented Chain into our ChainExample class we are ready to make use of the functionality it provides.

The ChainExample class will add events to three button elements. When a button element is clicked a corresponding panel will appear. Before this happens all other panels will be faded out. Chaining is used to make sure that these events happen in the order we want.

The full code for ChainExample is:

/**

 * Add events to buttons. Clicking a button will hide all panels before showing the panel corresponding to that button

 */

var ChainExample = new Class({

    Implements: [Chain],

    /**

     * Define the element ID of the button and the element ID of the corresponding panel

     */

    actions: new Hash({

        'button-one': 'panel-one',

        'button-two': 'panel-two',

        'button-three': 'panel-three'

    }),

    /**

     * An Array to store an effect instance for each panel

     */

    effects: [],

    initialize: function()

    {

        /**

         * Add an onclick event to each button. Clicking a button calls the showPanel method

         */

        this.actions.getKeys().each(function(buttonId) {

            $(buttonId).addEvent('click', this.showPanel.bindWithEvent(this));

        },this);

        /**

         * Create an Fx object for each panel

         */

         this.actions.getValues().each(function(panelId) {

            this.effects[panelId] = new Fx.Tween($(panelId), 'opacity', { duration: 'short', onComplete: function() { this.callChain();}.bind(this)});

         }, this);         /**

          * Initialize by hiding all panels, note the call to callChain to cause stuff to happen

          */

        this.hideAll();

        this.callChain();

    },

    /**

     * Add the a actions required to hide all panels to the Chain call stack

     */

    hideAll: function()

    {

        /**

         * loop each panel and Chain: 1. fade the panel, 2. set the display property to "none" after the effect has finished.

         *

         * Note that this function does not actually cause anything to happen, it simply adds actions to the Chain

         */

        this.actions.getValues().each(function(panelId) {

            this.chain(

                function() { this.effects[panelId].start(0); },

                function() { $(panelId).setStyles({'display': 'none'}); this.callChain(); }

            );

        },this);

    },

    /**

     * Handle a button click by fading and hiding all open panels and then appearing the corresponding panel

     */

    showPanel: function(event)

    {

        this.hideAll();

        var panel = this.actions.get(event.target.get('id'));

        this.chain(

            function() { $(panel).setStyles({'display': 'block', 'opacity': '0'}); this.callChain(); },

            function() { this.effects[panel].start(1); }

        );

        this.callChain(); //this call starts the chain. Since each function in the call also makes a call to callChain the entire stack will be executed

    }

});

window.addEvent('domready',

    function()

    {

        var myChain = new ChainExample();

    }

);

I will only go through the code relevant to chaining in detail. Lets have a look at each important part:

ChainExample::initialize

In the constructor we bind behaviours to the buttons and create Fx objects for the panels. Notice the custom onComplete callback provided for each Fx instance. This tells the internal chain stack to pop the next function and run it right after the effect has finished. We are now able to execute any function as soon as the effect completes.

ChainExample::hideAll

Look at this method carefully. A call to ChainExample::hideAll() does not actually hide the panels. The method adds to the chain stack a set of functions that will fade and hide each panel in order. To get the panels to actually hide we must execute the chain stack using this.callChain().

Notice how the second function passed to this.chain invokes this.callChain(). The function is telling the chain stack to continue onto the next function by itself.

Another important thing to note is that there is no need to bind the function passed to this.chain as this is dealt with internally.

ChainExample::showPanel

This is the event handling function that will show a panel.

First off a call to ChainExample::hideAll() is made. Remember that this method doesn’t cause anything to happen immediately. At this point we have added all the steps needed to hide all the panels to the chain stack. We then proceed to add steps which will show the correct panel.

Once the entire chain stack is set up this.callChain() is executed and the entire stack will be called because each step makes its own call to this.callChain() once it has finished.

That’s the basics of Chain. We have created a class which allows us to combine any number of effects and arbitrary functions and ensure that the are executed in the order we want. Hence the basic idea of Chain is to create a stack of functions and execute them in the order you please whenever you please.

Downloadable Demo

I have put together a quick demo so that you can see the code in action. Download the demo here.

Further Considerations

In my example, every function in the chain stack makes a call to this.callChain() once is has completed. This means that as soon as the first function is executed (by manually invoking this.callChain()) the entire stack will run from start to finish automatically. Chain can be used in a different fashion where Chain::callChain() is always invoked externally. As a crude modification to my example, every click on a button could invoke this.callChain(). Thus each button click takes one further step to completion of the actions.

If you need to add timings and delays consider using Function:delay to delay the invocation of Chain::callChain().

It is also possible to use multiple chains in the same class for even more complex behaviour. This would involve using separate instances of the Chain class directly.


Posted by Daniel Skinner 2008-01-31 22:30:11


Trackback Button Comments RSS 2.0 Button

Categories: Guides, Web Development

Tags: , , , ,

31 Comments »

  1. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by Learning MooTools: MooTools Tutorials and Examples - Six Revisions — June 20, 2008 @ 2:42 am

  2. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by Moo Tools Tutorials « Brandontruong’s Weblog — June 27, 2008 @ 7:27 am

  3. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by 20 MooTools Tutorials and Examples | Mind Tree — August 5, 2008 @ 6:34 am

  4. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by Learning MooTools: 20 MooTools Tutorials and Examples | [w3b]ndesign — August 17, 2008 @ 9:19 pm

  5. Thanks to Philippe for pointing out the code doesn’t work on the released version of 1.2. The main reason is due to the API change of the Fx objects used – The chaining code is still correct.

    Here is an updated version of the code, working with the current released version of 1.2: MooTools Chain Demo

    Comment by Daniel Skinner — August 20, 2008 @ 10:10 pm

  6. Hello,
    Thank you for your reactivity.
    The update of Chaining with MooTools 1.2 works correctly.

    Comment by Philippe HUTEAU — August 22, 2008 @ 7:00 pm

  7. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by Learning MooTools: 20 MooTools Tutorials and Examples | Asktechman.com -Your Guide to best Internet Resources — August 26, 2008 @ 8:06 am

  8. Hi Daniel, nice tutorial.
    Just wanted to point something.
    ChainExample.effects should be a object not an array.

    effects : []

    should be:

    effects : {}

    Arrays cant have string indexes. At least it should not hehe.

    fabiomcostas last blog post..Removing Empty Labels from forms.ChoiceField in ModelFormSets

    Comment by fabiomcosta — December 19, 2008 @ 10:20 pm

  9. Thank you, great example. It helped me very much
    but view big code this horizontal scrolling is very unuseful

    Comment by Pavel — February 9, 2009 @ 7:09 pm

  10. [...] Эта статья – художественный перевод поста Дэниэла Скиннера. [...]

    Pingback by » Цепочки вызовов функций (Chains) в MooTools 1.2 — May 2, 2009 @ 4:17 pm

  11. I find this somewhat confusing….

    NSFWs last blog post..The Cracked Round-Up: This Time It’s Impersonal.

    Comment by NSFW — May 2, 2009 @ 6:09 pm

  12. [...] 12. Chaining with MooTools 1.2 [...]

    Pingback by 20 Mootools examples | Search-End — May 6, 2009 @ 1:22 am

  13. 2pavel:
    yeah, i think so to.
    Maybe the author should attach .txt file with the code example to the article.

    Comment by Alex — May 12, 2009 @ 2:28 pm

  14. Download the demo to see it in action, see the link in the post. Let me know if you still have questions.

    Comment by Daniel Skinner — May 12, 2009 @ 2:34 pm

  15. Thanks

    Comment by Daniel Skinner — May 12, 2009 @ 2:34 pm

  16. I will try this..

    thx for info…

    angga hendras last blog post..Comment on Nomor Urut PILPRES 2009 by angga hendra

    Comment by angga hendra — June 1, 2009 @ 10:48 am

  17. [...] Chaining with MooTools 1.2 [...]

    Pingback by 25 Useful MooTools Tutorials — June 8, 2009 @ 10:35 pm

  18. Thank you … this chaining tutorial has me very helped.

    Comment by Webagentur — June 17, 2009 @ 1:22 pm

  19. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by MooTools Tutorials and Resources Round-Up « Tech7.Net — July 28, 2009 @ 3:57 pm

  20. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by MooTools Tutorials and Resources Round-Up - Programming Blog — July 28, 2009 @ 11:17 pm

  21. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by MooTools Tutorials and Resources Round-Up » Shai Perednik.com — July 29, 2009 @ 6:12 am

  22. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by AMB Album » MooTools Tutorials and Resources Round-Up — July 29, 2009 @ 7:28 am

  23. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by Shopping Mall » MooTools Tutorials and Resources Round-Up — August 1, 2009 @ 12:28 am

  24. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by Advertisers Blog » MooTools Tutorials and Resources Round-Up — August 3, 2009 @ 7:06 am

  25. [...] Chaining with MooToolsA guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by MooTools Tutorials and Resources Round-Up | Search Engine Optimisation — August 3, 2009 @ 10:38 am

  26. [...] Chaining with MooTools A guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by MooTools国外的教程和资源大集合 | CssRainBow.cn — August 13, 2009 @ 7:27 am

  27. [...] Chaining with MooTools A guide to the MooTools’s Chain class and how it can be used in custom classes. [...]

    Pingback by A word about MooTools- Anastacia — August 17, 2009 @ 1:59 pm

  28. I appreciate you explaining chains a little more clearly. This stuff has always confused the heck out of me.

    Comment by Charlotte Mortgage Rates — September 30, 2009 @ 6:39 pm

  29. [...] 文章介绍了使用MooTools实现链Chain的教程。 浏览教程: Chaining with MooTools [...]

    Pingback by MooTools国外经典实例与教程大集合 | CssRainBow.cn — October 18, 2009 @ 8:41 am

  30. [...] Chaining with MooTools 1.2 [...]

    Pingback by Other Tutorials and Resources « PSD to HTML , Slicing PSD to HTML — January 2, 2010 @ 9:52 pm

  31. [...] Chaining with MooTools 1.2 [...]

    Pingback by 25 Useful MooTools Tutorials « PSD to HTML , Slicing PSD to HTML — January 2, 2010 @ 10:16 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment