MooTools for jQuery aka: moo4q

Theory Hour

Introduction to MooTools Class

Welcome to coding with Class. The MooTools Class module makes working with prototypal inheritance a snap. It supports sub classes and mixins as well. Check out this ninja example (c/o Aaron Newton), it's a bit abstract and completely useless on a website but will hopefully get you started. Don't like the world of abstract examples? look to the right.

The Human Class

Human.js

Every class looks something like this. You toss in an object literal as the single argument into the Class machine. This object literal becomes the prototype for all humans. The initialize method will automatically be called when we create a new Human. Jump down to where it says var bob = new Human(). There we create a new Human instance and assign it to the variable bob. bob is now an object with a handful of methods and properties. See how we can ask about his energy or tell him to eat?

The Warrior Mixin

I want some different types of humans, like Ninjas and Samurais, and Dragoons, hmm ... Warriors, yeah. We can use what's called a Mixin that holds several different warrior-ey methods and properties that make all these warriors different from a regular human. Note: we aren't going to be using this anywhere until the next section.

Warrior.js

The Ninja Class

Now that we have a Human and a Warrior class we can create a Ninja. The Ninja is going to be a subclass of Human, in other words, a ninja is a Human. It will also use the warrior mixin so it has a warrior, yeah that sounds weird. Point is, when you Extend a class you are using another class as the prototype for the new class, when you Implement a class, you simply copy over the methods and properties, but it isn't the prototype of the new class. You can implement multiple classes, but you can only extend one. In the end, your new class will have all the methods and properties of the parent class and any implemented classes.

Ninja.js

Now that was easy. Note the method call to this.parent(). If your subclass has a method with the same name of a method in the parent class (like initialize) it overwrites it. Calling parent inside any method will call the parent class's method of the same name. In this example it calls the initialize function of Human.

The Samurai Class

Samurai.js

That's almost no code at all, yet a Samurai is very different from a Ninja. He's always good and has a heck-of-a-lot more energy. So that's the basic idea of MooTools classes. You can create lots of objects that share a bunch of code and can be extended to add whatever else you might need. If you fix a bug in Human, you've fixed a bug in Samurais, Ninjas, and anything else that depends on Human. Nothing short of radical.

The jQuery API

You don't have to use the regular JavaScript syntax to work with moo4q objects, see?

samurai-jack-usage.js

This demo is not fit for IE!

No worries, moo4q works perfectly in IE, just this demo doesn't. This is simply a fun illustration of these concepts that I put together for a presentation at jQuery Conference 2010 in San Francisco. Since it was only ever intended to run on my machine in webkit, no sense spending a bunch of time on IE for it.


Fer Realz

Simple Tabs Class

Here's a production ready example of how to use moo4q. It's definitely worth your while to read both columns of this page. Tab classes are as common as they come. You've got a bunch of tabs that change some content when clicked. Skip to the demo daggumit!

But First!

Moo4q classes must always have their first argument of the initialize method be a jQuery selector, and an optional second argument for options. It does not support more than that. Carry on!

The Tabs Class

Tabs.js

I think the comments in the code there are clear enough. Two things to note: 1) Options are like "defaults" or "settings" in a regular jQuery plugin and 2) that code is wicked clean.

The Tab.Ajax Subclass

One of my personal frustrations with jQuery plugins is that because a plugin is an immutable function, I can't tweak it to meet my needs. MooTools classes can extend each other, or in other words, you can have a plugin that's a subclass of another plugin and they actually share code, but not in a copy/paste kind of way, but in a DRY kind of way.

Pretend for a moment that on one project you needed a tab class with inline content and in another project/page you needed a tab class that loaded content via ajax. The typical solution is to 1) bog down Tab.js with both inline and ajax functionality even though you don't always need ajax or 2) copy, paste, tweak. But since MooTools classes are extendable you can keep your base Tabs.js class simple and then extend it to add AJAX capability.

Tabs.Ajax.js

Take away the comments and you've only got a few lines of code to add AJAX to your tabs. Note the use of detach and attach to provide a fool-proof user experience--protection agains atomic fingers. You could easily override the show method to add animation or all sorts of stuff.

Events are Silly Sweet

You may have noticed a few spots where it said this.fireEvent('show'). That's there to let you do whatever you want when cool stuff happens, just like a callback in regular jQuery plugins. Check out the usage to see how that works:

Tabs-usage.js

On one page are two similar, but different plugins. They share about 80% of the same code, which means easier debugging, easier feature-adding, and a saner life when your PM comes back with 30 new "simple" features and bugs you need to work on.

Here's the live demo.