Arieh.co.il

A story of how you should create your JS widgets

Last week I got a feature request first one of the site's I was working on this past year. The site has a gallery that is based on my ThumbsSlides plugin, and using Smoothbox for the lightbox effect.

This started a short journey for me, that made me understand how important it is that we write our Class's properly. If you want to skip the story and get to where I talk some principles, you can skip here.

The request was that I would add the ability to navigate the images through the lightbox. This meant 2 different problems:

  1. ThumbsSlides was never meant to allow such functionality. This required that the Class will recognize the current viewed item, and a means to navigate through the items one by one.
  2. It also meant that I will find a way to integrate ThumbsSlides with Smoothbox.

Improving ThumbsSlides

Long story short, i found myself completely rewriting most of the Class's methods, making them much better. It made the Class much more dynamic, requiring much less CSS to work, and making most of the calculations much simpler.

I think my main problem was that although making a carousel seems easy enough, I never really designed this Class. While working on the fix, I got away from my computer, and actually started sketching the flow and properties of the various states the list can be at. This was a very interesting experience, as the last time i used sketching and input/output tables was in highschool.

As I said earlier, the end result is a much more solid and easy to use. Although this is the first plugin I uploaded to the forge, it is only now that I really feel it is really Forge quality.

Although the title sais this is an intro to the Class, I won't bother you with code examples, but you can look at the demo page to see it in da works.

Integration with Smoothbox - or - Why I ended up creating yet another Lightbox module

At first I thought I could simply hack something up, editing the Smoothbox source code to enter some HTML, and then find it and attach the events via $$. By was I wrong. After a few attempts at this, I figured it would be easier to replace the module (which was simply the first I found), and so began my search for a better lightbox implementation.

My only conclusion is that although many implementations use Mootools as their DOM tools, non of them really understands Mootools. Most of them were functional. Those who weren't, didn't use Class, and none supplied valid hooks for extensions, not mentioning any type of events.

Now, if you ever opened the Mootools docs, you would have noticed that almost every module supplies both extension hooks, and a list of standard events, so you can integrate the module with others. This is a principle I always work hard to implement, and when creating a Class, I almost always supply it with Events.

All the widgets I saw had an internal navigation mechanism, but not even one supplied an event system that will let me know when an image was switched. So instead of hacking away at those classes, I decided that it would be much simpler to create a bare-boned lightbox that does things the Moo way.

And so was born SLBox. It is a simple lightbox widget, that receives a url to an image and wrap it with a box. It also creates a menu with prev/next buttons, that does absolutely nothing other than firing events and empty functions.

Well, this isn't really nothing - it's the whole point - supplying hooks by which one can decide how the behavior should work. If you don't want any buttons, you can say so with the options (another key feature of Mootools' Class!).

This was enough for the site I was working on, but I figured it wasn't much use for the Mootools community looking for functional widgets, and so I added in SLBGalery. This little class recieve a list of anchors surrounding images, and makes a lightbox gallery out of it. But to make it really shine, I made sure that it will fully expose the SLBox's API.

To look at it go, you can look through the ThumbsSlides demo page. If you look at the code, you will see that the Classes interact seamlessly, as they were both designed to be used.

A few notes about why I think this should interest you

The web is full of tools for us to use. It would be crazy to create everything by yourself, when so many have done the stuff you're doing before you. But it is also very common that we would like your widgets to interact.

Javascript makes integrating various widgets together extremly easy. It's amazing impementation of lambda, it's scope resolution mechanism, and the integrated event system, all give us greate tools to make our code easier to use with other, external code.

If that isn't enough, Mootools' Class comes with it's amazing Events and Options interfaces, that are specifically designed to help us create extensible Classes.

It is really easy to figure out what events your Class should have. Does your Class has one main operation that it performs? fire a complete event when it's done. Does it have any operations that trigger by user interaction? give them events. For example - SLBox have the next and prev events, that fire when those buttons are pressed. Think - what parts of my Class might interest a 3rd party Class - and give them events. If the operation is done on an element - maybe it is a good idea to supply that element as an argument.

Firing events is really cheap, and it will make your Class a 100 times more usable and professional. It sums up in 18 characters. 20 if you count semicolon and line break . 22 if you count apostrophes. this.fireEvent("");.

It is amazing to me how so many of the widgets out there spend so much time designing their products, without taking the time to think about the fact that they might not be used as standalones. For me it feels sloppy.

So Whenever you write your class, always use thing template:

var MyClass = new Class({
    Implements : [Options,Events]
    , options :{
    }
    , initialize : function(options){
        this.setOptions(options);
    }
});

Even if there is a slight chance that you will end up writing a Class that has no options (for example my DateRange), it is far more likely that it will.

Links

  1. ThumbsSlides on the forge.
  2. SLBox on the forge.
JavaScript Reference, JavaScript Guide, JavaScript API, JS API, JS Guide, JS Reference, Learn JS, JS Documentation