Singletons and Event Arbiters

June 23rd, 2009 by Aaron N.

I got an email today asking about how I use singletons in my own development environment and I thought I’d post my response for anyone who might find it useful.

Here’s the question:

Whats the best way to define some
code, assign it to a global object and have it run all at once?

I use MooTools server-side quite a bit in my ASP code using JScript
and we have need for global singleton objects to be around (such as
our logger). As there are no clear best practice ways out there of
doing it I’ve started and stuck with something like this:

var LoggerObject = function() {
// Logger code
}

var Logger = new LoggerObject()

which is ok but feels like I’m missing something. How do the pros do
it, whats the advantages/disadvantages to other methods?

Now, for those who aren’t familiar with the concept, a singleton is a class that designed to have only one (or, perhaps, a limited number greater than one) instance. In JavaScript, any object can inherit from any other object and you can’t really prevent this, so in the truest sense of the term, there’s no such thing as a JavaScript singleton.

MooTools gives us a function called “Class” which helps us manage inheritance between objects. Creating an object that is an instance of a class is done with the “new” operator:

var myWidget = new Widget()

If you wanted to create a class and immediately cast it into an instance, you could do the following:

var myInstance = new new Class({...})

The double “new” invokes the function returned by class and returns an object - an instance of that class. There’s rarely a reason to do this. In fact, the only reason I can think of is if you want that class to extend another:

var myInstance = new new Class({
    Extends: SomeOtherClass,
    //new properties go here
});

The problem with this pattern is that it doesn’t really get you much. JavaScript is all about objects, and there are better ways to accomplish this task.

I use objects (as singletons) all the time for my application code (almost never for plugins obviously; those are meant to be extended and instantiated). I often use a “site” object to attach methods and manage state (such as if the user is logged in, their username, etc). I just make this a plain old JavaScript object, like so:

var mySite = {
    login: function(username){ this.username = username; },
    showWelcome: function(){
        $('welcome').set('html', 'Welcome ' + this.username);
    }
};

There’s nothing special here - this is how JavaScript works. It’s important to note that classes in MooTools exist to give us functionality and to let us derive functionality through inheritance. If I create a class called Widget and I later want to make a version called Widget.Ajax, I can extend Widget and add only the ajax parts. With singletons, the whole point is that you aren’t going to create more than one of them.

However, there are some other things that MooTools’ Class gives us, such as mixins (classes that are meant to use Implement to imbue the target class with their properties). Examples here include the Events and Options mixins that give instances methods like setOptions and addEvent. In these cases you can still use the object declaration above and then extend the object:

var mySite = {
    login: function(username){
        this.username = username;
        this.fireEvent('login');
    },
    showWelcome: function(){
        $('welcome').set('html', 'Welcome ' + this.username);
    }
};
$extend(mySite, new Events());

Working this way obviates the need for the clunky “new new Class” pattern and it’s more intelligible in my opinion.

Event Arbiters

Which brings me to a common practice I use when I build applications. When I build a site or application I try to make things as modular as possible. I make it so that my site works without any JavaScript first, then I start adding in the UI goodness with ajax and animations and sortable tables and all that jazz. I also make the JavaScript itself modular. Everything that can be a class I make a class. The stuff that’s left over is the code that instantiates those classes.

But what if the code that instantiates one widget needs to get information from another widget? For instance, what if our Welcome widget needs to know the state of the Login widget? Well, if our Login widget stores it’s state on the mySite object, then the Welcome widget can just inspect that, right? That’s cool; if the page loads and mySite.username is undefined then the Welcome widget knows the user isn’t logged in. All good.

But what happens when that state changes? What happens when the user logs in? Now we need an event - onLogin or something, but that means that Welcome needs to attach itself to Login and now we’ve lost some modularity because we’ve introduced a dependency. Welcome can’t work without Login. In this case, this doesn’t seem like a bad dependency to have - after all, a welcome message without login functionality doesn’t make much sense - but there might be dozens of other widgets that need to do things when the user logs in and we may want those widget to work even if the user doesn’t log in. Further, we may want to load the Login widget only on demand - when the user tries to log in for example. We can’t do that if all our widgets need to attach events to the Login widget.

This is why I make mySite an instance of Events. mySite doesn’t really have any native events per se. Rather, other classes attach events to it and fire events for it. So, in our puzzle above about our Login widget, instead of all the other widgets attaching an onLogin event to Login, they can attach it to mySite, and then our Login widget fires that event not on itself but on mySite:

var mySite = new Events();
var Login = new Class({
    //...login logic and stuff
    loginSuccess: function(username){
        mySite.username = username;
        mySite.fireEvent('login');
    }
});
var Welcome = new Class({
    initialize: function(){
        this.showMessage();
        mySite.addEvent('login', this.showMessage.bind(this));
    },
    showMessage: function(){
        $('welcome').set('html', mySite.username ? 'Welcome ' + mySite.username : 'Please log in');
    }
});

Now our classes are no longer dependent on each other. They are both dependent on mySite but that was always the case. They can each come and go as they wish without really caring about the other. This increased modularity pays off later as your site grows in complexity. Some pages may have some widgets and some may have others. You can attach logic to the mySite object without having to really manage those dependencies.

Clientcide 2.1.0: updated for MooTools 1.2.3, bug fixes, a few new features

June 19th, 2009 by Aaron N.

Today we released MooTools 1.2.3 and MooTools More 1.2.3.1. Both of these are, for the most part, bug fix releases with a few small features included. The big change is the deprecation of $ which is now replaced by document.id. This is a big change, and I suggest that you go read up on the MooTools blog about the details. It’s important to note that it won’t affect any of your code; all of these updates include no breaking changes.

The removal of $ as a dependency means that you can use MooTools with other frameworks (like jQuery) and MooTools won’t break. But if your code still uses $ then nothing will change unless you want to use MooTools with another framework that also uses $. Then you might want to consider using document.id, too.

For plugin authors, such as myself, you should update your code to use document.id. This will ensure that if someone using your plugins is using another library that overwrites $, then your plugin will still work. Note that you can easily upgrade an existing plugin by either searching and replacing $() for document.id() (be cautious that your search doesn’t catch $$()) or you can wrap your plugin in an enclosure:

var Widget = (function($){
    return new Class({
       initialize: function(element) {
           this.element = $(element);
           //...etc
       }
    });
})(document.id)

With the Clientcide conversion, I’ve opted for the former (to replace $ with document.id). In addition to this big change, the following other changes and features are included in 2.1.0:

  • Universal: replacing all $() with document.id() (see MooTools 1.2.3)
  • Autocompleter: defining splitter based on separator
  • Autocompleter: Fixing autocompleter for Opera
  • Class.Occlude, Class.ToElement: adding a compat layer for ToElement and Occlude
  • Element.Delegation: Tweaked event delegation check to not extend elements unless match is found.
  • Element.Delegation: Added an over 100x faster event delegation check that walks up the DOM tree from the target checking against the selector. Also removed mouseover and mouseout logic that seemed to be unnecessary.
  • FixPNG: adding alternate fixpng suggestion (in docs)
  • Fupdate: adding caption option to Fupdate
  • Fupdate: adding method and emulation to fupdate request
  • Fupdate.Prompt: making fupdate ajax prompt work with formvalidators applied inline in the html
  • MenuSlider: adding isVisible method for MenuSlider
  • SimpleSlideShow.Carousel: fixing overflow in SimpleSlideShow.Carousel for IE6
  • StickyWin: added click-out and escape options for closing stickywin
  • StickyWin: adding onDestroy event to StickyWin
  • StickyWin.Alert: updating reference to StickyWin.alert > StickyWin.Alert
  • StickyWin.Alert, StickyWin.Confirm, StickyWin.Prompt: refactoring the stickywin alert, confirm and (new) prompt shortcuts into classes
  • StickyWin.Prompt: new class!
  • StickyWin.UI.Pointy: several css and code tweaks to manage IE layout issues; making background image properties in StickyWin.UI.Pointy css attributes (in a <style> tag) to avoid this crazy bug: http://davidovitz.blogspot.com/2006/09/https-bug-in-ie.html

jQuery vs MooTools, MooTools vs jQuery

May 18th, 2009 by Aaron N.

Every day on twitter I see posts where people are asking themselves the same question: MooTools or jQuery? This is because I have a saved search for “mootools.” Doing a search for “dojo” or “prototype” would find similar tweets from people considering those frameworks or jQuery. The fact is, jQuery is incredibly popular and it’s own popularity breeds adoption as much as the fact that it’s a good bit of software.

Focusing on the “MooTools or jQuery” question, it’s clear that there isn’t a great resource that helps people decide. Looking at the documentation and examples for the two libraries shows they share a lot of functionality. If you’re just now, in 2009, trying to decide which one of these frameworks you want to dive into first, chances are you’re probably relatively new to JavaScript itself and the prospect of comparing the frameworks by actually reading their source code is perhaps more effort than you want to spend. Were I in such a position, I’d want someone to do that for me; to look at them and tell me why some choose one over the other.

So, today I’m releasing jQuery vs MooTools which aims to do just that. No doubt this will cause a stir in our communities but hopefully it will be a healthy one.

I’m not trying to convince people who love jQuery that they’re wrong and should switch, nor am I trying to illustrate to the MooTools community what they’re missing from jQuery. This site is aimed at people who are trying to make this decision and is meant to be an honest comparison of the two libraries. It’s obvious where my bias lays - I’m a MooTools supporter. But I’ve tried to represent the two libraries fairly and, where my opinion is expressed, I try and call that out and say it’s just that - my opinion.

It’s entirely likely that I’ve misrepresented something about the jQuery core library in this post but I’ve done my best not to. Before publishing this site I consulted numerous other contributors to our community. I’ve shared the comparison with authors of other frameworks, bloggers who don’t endorse any particular framework over another, and even sent it to one of the jQuery team members. As I receive feedback, I’ll update the site to incorporate the perspectives of others that may be helpful for the target audience of the comparison (i.e. people considering the two frameworks).

I encourage you to leave comments on the site itself and not here on clientcide.

read on: jQuery vs MooTools

Jira Awesomizer

May 18th, 2009 by Aaron N.

We use Jira for issue tracking where I work. It’s interface…. leaves something to be desired.

I hacked together a greasemonkeyscript that makes it a little less painful. If you use Jira, you might want to check it out.

Follow MooTools on Twitter

May 15th, 2009 by Aaron N.

I used to make a habbit of posting links to all the fun and interesting MooTools news and whatnot here. I’ve recently been focused on the second edition of the MooTools book, MooTools More, bugs, and a new job and have had less time to post here than usual.

To make up for this, I and other MooTools developers have been posting things on Twitter on @mootools. If you want to know what’s happening in the MooTools world, this is the place to follow. If you don’t use Twitter, you can still get the RSS of the feed.

You can also follow MooTools developers who often post useful things about MooTools that don’t make it on to @mootools (in no particular order):

You can find more links for these developers (home pages, github profiles, etc) on the MooTools developer page.

As a side note, you can follow Clientcide on Twitter as @clientcide. I’ll note that the only thing posted there are posts to this blog, so if you’re already following Clientcide via email or rss, you won’t see anything new on twitter.

Bring the BSOD to your Web Apps

May 15th, 2009 by Aaron N.

MooTools developer Guillermo Rauch (http://devthought.com) has an awesome MooTools plugin that I just have to share: BSOD.js. Good god, it’s brilliant.

The script BSOD.js provides an easy-to-use class to boost the error reporting user experience of your websites.

Advantages for the user:

  1. It makes it unclear what triggered the error. 
  2. By default, it’s easy on the eyes and it succeeds at alarming and fazing the user 99% of the times.
  3. Users are likely to exit your application or website, giving you plenty of time to fix it.

Hilarious! The demos are every bit as awesome as the original BSOD.

Firebug 1.4 Alpha - Worth It

May 4th, 2009 by Aaron N.

I had a nice email exchange with one of the guys on the Firebug team recently. Basically, I miss Firebug 1.2 w/ Firefox 2.0, but Firefox 3 has some features I really don’t want to live without. In our email conversation, I shared a laundry list of issues that I’ve observed Firebug 1.3 doing that make my life less awesome.

Anyway, one of the suggestions I got was to upgrade to the alpha version of Firebug 1.4 and, I gotta say, it’s worth it. It’s not quite as solid as things were back on Firefox 2, but it’s way better than Firebug 1.3.

You can grab the latest builds here: http://getfirebug.com/releases/firebug/1.4/?C=M;O=A (My Firebug friend recommends the most-recent, currently 1.4a22).

FancyUpload 3.0 Released

April 30th, 2009 by Aaron N.

Harald Kirshner (a.k.a. digitarald) released the latest incarnation of his (awesome) flash / js based file uploader, FancyUpload.

Despite the delay, the completely rewritten version ofFancyUpload, version 3.0, got pushed to github today. This new version is more stable, has betterdocumentation and more showcases than ever. I even added two download packages with runnable installations, like many developers requested. This article introduces the new features and showcases, impatient readers can jump directly to the comprehensive project page or fork on github.

New Features

There are a lot of new features and fixed bugs in this new release, so let me distill the most important ones for you:

  • The API with, separated uploader and file classes, allows an easy implementation in all kind of interfaces
  • Events are dispatched for every step of the uploading process, to keep the interface as responsive as possible
  • Progress tracks the loaded size, upload-rate, estimated time and other values for every file and for the batch as a whole
  • File uploads can be stopped, restarted or removed anytime
  • New Iframe-based class for multiple, asynchronous uploads without dependency on Flash
  • Compatible with Flash 9 and 10 with the browse button as a transparent overlay or as an interactive image sprite
  • Ability to change the upload URL and add POST/GET data on runtime, customized for every file or the whole process

Link »

A MooTools File Manager

April 29th, 2009 by Aaron N.

Chris Pojer, one of the MooTools developers, just released his FileManager plugin and it’s worth checking out.

  • Browse through Files and Folders on your Server
  • Rename, Delete, Move (Drag&Drop), Copy (Drag + hold CTRL) and Download Files
  • View detailed Previews of Images, Text-Files, Compressed-Files or Audio Content
  • Nice User Interface
  • Upload Files via FancyUpload (integrated Feature)
  • Option to automatically resize big Images when uploading
  • Use it to select a File anywhere you need to specify one inside your Application’s Backend
  • Use as a FileManager in TinyMCE
  • Provides your Client with the most possible convenience

Be sure to check out the demos:

Clientcide 2.0.2: Event Delegation Updated for MooTools 2.0 Compatibility

April 27th, 2009 by Aaron N.

I’ve just made an update to the Clientcide libs. Aside from a few minor tweaks and fixes, the big change is that I’ve updated my Event.Delegation.js beta plugin.

MooTools 2.0 features built in event delegation (among many, many other enhancements) but the syntax is a little different than the previous version of my beta plugin. While my previous version had the syntax like this:

element.addEvent('click(a)', function(){...});

MooTools 2.0 currently has the syntax as:

element.addEvent('click:relay(a)', function(){...});

I’ve updated my version to use this new syntax which should make it a little safer to use. For starters, assuming the syntax doesn’t change in 2.0 (which it totally could), you won’t have to do anything when you upgrade. But the other benefit is that, if the syntax changes, it’ll be easier to find them. My previous version is basically impossible to search for in your code, which means that if you’ve been using it in your work and need to update the syntax, it’s going to be hard to find them all.

Warning!

To help with this migration I’ve added a little logic to the code so that if it sees you trying to add an event with the old syntax (’click(a)’) it’ll post a console warning that the selector is no longer valid. This should make it possible for you to browse around your application(s) and see if there are any warnings.

Still Not Perfect

It’s also worth noting that my plugin still suffers from the same problems it had before. Namely, you can’t monitor the blur and focus events and some custom events might not work for you (I haven’t tested them all, but I suspect some won’t work).

Other than that, I’m going to upgrade this from “academic exercise” to “totally usable but might mean some work to upgrade later.”