Not so many years ago, I smiled at a customer who claimed to have written an entire web application using JavaScript. No classic ASP.NET development and no Web services; just a collection of HTML pages each padded with a lot of JavaScript and a bunch of HTTP endpoints returning strings. Some endpoints were plain ASP.NET pages; some were HTTP handlers. The entire presentation logic, and some of the business logic, was coded in JavaScript using an in-house framework.

The customer called me to learn more about the ASP.NET AJAX framework that Microsoft had just released in the spring of 2007. The customer said: Writing a JavaScript application is really a nightmare. Wow, I thought, that’s surprising! So I smiled but kept myself from saying with a sardonic grin something like: “You really had no idea of what you were getting into, did you?”

At the time, JavaScript was nowhere near any other mainstream programming language. It was not object oriented and not strongly typed, whatever those expressions meant to you. JavaScript didn’t have a rich type system either; and also lacked a native framework full of readymade objects and functions that developers could find handy and helpful.

What’s new today, about five years later?

First and foremost, any customers who ask for help today on building a web application entirely with JavaScript wouldn’t risk getting a sardonic grin from me or anybody else. Today, that’s in the normal range of things. Is JavaScript a brand new language today? Did it undergo radical changes in the last five years? No, today’s JavaScript is the same language it was a decade ago.

So what’s really different about JavaScript now? The big difference today is that there are a variety of JavaScript frameworks that make writing even a sophisticated application a doable task. One of these frameworks is MooTools, which is the primary topic for this article.

Introducing MooTools

People like to consume interactive applications through the web. For a variety of reasons, the most common way of writing these applications is still JavaScript. JavaScript, in fact, happily survived the advent of Flash and Silverlight. While Flash and Silverlight will still be used in web applications, they will no longer cannibalize old-fashioned, vintage JavaScript.

JavaScript was originally introduced to give web authors the ability to incorporate some simple logic and action in HTML pages. JavaScript was not designed to be a classic and cutting-edge programming language. The design of JavaScript was influenced by many languages, but the predominant factor was simplicity. It needs extra facilities to support the development of any functionality that goes beyond changing the attribute of a DOM element. Here’s where MooTools fits in.

In a nutshell, MooTools is an object-oriented JavaScript framework aimed at experienced web developers who need to write effective code quickly, effectively, and in a cross-browser manner. Released under the open-source MIT license, MooTools is compatible with most browsers including Internet Explorer 6+, Firefox 2+, and Safari 3+.

The library has a modular structure and is based on the following macro components: type system, class management, DOM, effects, networking, and browser interaction. You can extend the library via plug-ins and obtain it through customized downloads that just include the modules you like and need. Let’s drill down into the core features of the library. This article is based on version 1.3 of the library.

The MooTools Type System

JavaScript has its own type system populated by primitive types such as Boolean, Function, Null, Number, Object, String, and Undefined. The list of primitive types is augmented by a few built-in objects such as Array, Date, Math, RegExp and wrapper objects for primitive types (Boolean, Number, String).

MooTools contributes to making the JavaScript’s type system richer by adding a few extensions to known types: Array, Function, Number, Object, and String. In addition, MooTools also offers a new type-the Event type-as a cross-browser representation of browser and DOM events.

MooTools makes the JavaScript’s type system richer by adding a few extensions to known types.

The difference between a MooTools type and the JavaScript native or wrapper object is all in the list of functionalities being offered. For example, the String type in MooTools has unique methods to convert between hyphenated and camelCase strings, between hex values and RGB arrays, or between strings and numbers. It also has methods to capitalize strings and test against regular expressions. Let’s have a look at the following example involving a string:

var temp = "DinoIsHungry";
alert(temp.hyphenate()); // outputs Dino-Is-Hungry

As you can see, you need to do nothing special in order to use the extra capabilities that MooTools adds to string types. You just create a string and invoke any new methods. This is the power of the JavaScript’s native prototype property that MooTools extends with its own set of methods.

In the Number type, you can clearly see the effects of simplifying common operations, such as getting a number from a string and executing math operations. MooTools makes a long list of math operations (for example, abs, exp, min/max, round, sqrt) available directly on the value object rather than available through a static Math object as in plain JavaScript. Here’s the difference between getting the absolute value of a number in MooTools and classic JavaScript:

// In MooTools
alert((-4).abs());
    
// In classic JavaScript
alert(Math.abs(-4));

The Number type in MooTools also has methods to convert between different bases and an interesting shortcut for a fixed-length loop. In fact, the times method invokes a given function the number of times represented by the number. The callback function receives the index of the iteration as the argument. The code snippet below shows how to use the times method to compute the factorial of a number:

// Computes the factorial of 5
var total = 1;
(5).times(function(i) {
    // 0-based index
    total *= (i+1);
});
alert(total);

The set of extensions that MooTools provides for arrays is definitely interesting, as it contains quite a few handy functions that are both frequently needed and annoying to write from scratch. The perfect example is the some/every pair of functions. Invoked on an array, the function some returns true if at least one of the values or objects in the array satisfies the condition passed as an argument. The condition is a function that receives the array item and returns a Boolean value. On the other hand, the function every returns true if all elements in the array match the provided condition.

As a seasoned developer, you are certainly able to write such functions yourself. However, these are also the typical functions that you sometimes find annoying to write-not critical for the success and performance of the application; not so simple to write them without a bit of forethought. Functions like some and every are just the functions you would like to get for free from either the language or some large-scale framework:

var theArray = [2, 4, 6, 7];
    
// Demonstrating the syntax of every
var allEven = theArray.every(function(elem) {
   return elem % 2 === 0;
});
    
alert(allEven);

The Array type has a lot of functions that this pattern applies to. Other examples are the functions combine, which merges two arrays without duplication, getRandom, which picks up a random element from the array, and invoke, which invokes the specified function on each element in the array.

Objects in MooTools

The Object type is JavaScript’s counterpart to objects in classic OOP languages like C#. However, this fact is not sufficient to catalog JavaScript as an object-oriented language. The definition of an object you get from JavaScript is significantly different from the commonly accepted idea of an object you get out of classic object-oriented languages such as Java, C++, or C#.

In a classic object-oriented language, an object is an instance of a class which provides the blueprint of the capabilities of the object at run time. The structure of an object is immutable. In JavaScript, instead, an object is a dictionary of name/value pairs. In other words, the blueprint of a JavaScript object is fixed and implicitly defined. As a developer, you can’t change the structure of the object to make it anything else then a dictionary. However, you can modify the content of the dictionary at will. You can add and remove methods and properties at any time-even programmatically. In this regard, MooTools extensions help a lot.

The set of extensions for the Object type overall is similar to the set of extensions for arrays. However, with objects you test, add, filter, remove, and combine properties and methods. I’ve found the pair of methods append and subset to be particularly interesting.

The append method adds the entire set of properties found on a given object to another. Here’s an example:

var dino = { FirstName: 'Dino', LastName: 'Esposito' };
var youngPerson = { Age: 20 };
    
// Copies all properties of youngPerson to dino
Object.append(dino, youngPerson);

If the object being added contains a member with the same name as an existing member, the existing member will be overridden. Note that because of the dynamic nature of the JavaScript language, this operation may determine a change of type in the stored value.

The subset method creates a new object that incorporates only a subset of the members on the input object. The subset of desired members is passed as an argument. Here’s how to work with the subset method. Suppose you have an object that fully describes a piece of data, and then imagine you need to process only a subset of its data:

var person = {
    FirstName: 'Dino',
    LastName: 'Esposito',
    Age: 20,
    Gender: 'M',
    Hometown: 'New York'
};
    
// Define the list of members to pick up
var members = ['FirstName', 'LastName'];
    
// Copies selected values into the output object
var basicInfo = Object.subset(person, members);

A sapient use of the append and subset methods makes it easy to create descriptors of business types and doesn’t spoil the code with many internal methods where you do the dirty work. It would be desirable to have similar facilities in C# as well. The different nature of C# makes the whole thing much harder to achieve, but a framework exists that gets close to this-AutoMapper.

Finally, I’d like to remark the usefulness of the toQueryString method, which serializes to a querystring format the content of a given object.

Functions in MooTools

MooTools provides a fair number of extensions around another basic JavaScript type-the Function type. In JavaScript, a function is a bit of code bundled up into a block with a given name. A function may have a name, arguments, functional body, and return value. In JavaScript, functions are first-class citizens meaning that they are treated like objects. In fact, a function is allowed to have properties and can be passed around as an argument to interact with.

MooTools provides methods to modify the structure of a function by adding a property to a given instance as well as the prototype. Here’s how you use the extend method to add a new member on the fly:

// Empty function
var func = function() {};
    
// Add a new member to the function
func.extend('showMessage', function(msg) {
    alert(msg);
});
    
// Invoke the modified function
func.showMessage('Hi there!');

MooTools is a rich set of methods that enhance the execution of functions by offering additional features to the developer. For example, the delay method waits the specified number of milliseconds before executing the given function. As a developer, you just place a single function call without having to set a timer that waits and then calls the function. Here’s the code you need:

var func = function() { ... };
    
// Waits one second and then executes the function
var token = func.delay(1000);

Internally, the library sets up a timer. The ID of the underlying timer is returned to give you a chance to cancel the request before it gets executed. To stop a request, just use the ID with the clearTimeout system function.

In a similar manner you can define timers for operations that must be repeated periodically. The function you use for this task is called periodical:

// Execute the function every second until
// the timer is cleared.
var timer = func.periodical(1000);

Another common task when invoking functions is to check the return value against null. MooTools provides a sort of try-catch block wrapped up in a single function. The function attempt tries to execute a function and returns the return value of the function if the function terminates correctly. If it fails, it returns null:

// Attempts to execute a function
var result = func.attempt(args);

The list of facilities doesn’t end here, but this should be enough to stimulate your curiosity about the library. Let’s go ahead and have a look at the OOP capabilities of MooTools.

Classes and OOP

While the JavaScript language is not a fully object-oriented language, getting flavors of object-orientation in JavaScript is not impossible at all. The whole point is in choosing a strategy and offering a framework that makes creating objects in a hierarchical manner.

MooTools provides the Class function through which you can create JavaScript objects-that is, dictionaries of values-that look like classes in other programming languages. Here’s a quick example to get the point:

// Define a the class known as Person
var Person = new Class({
    initialize: function(name, lastName) {
        this.Name = name;
        this.LastName = lastName;
    }
});
    
// Start creating instances of Person type
var dino = new Person('Dino', 'Esposito');
    
// Not Dino?
alert(dino.Name);

Even if you’re only slightly familiar with JavaScript programming, you see that Class is nothing more than a JavaScript function defined in the library. However, in this way, it offers you tools to create classes in a natural way. The Class object takes a parameter which could be an object (as in the example) or a function. If it is an object, it can contain the collection of name/values that form the “blueprint” of this class. In other words, it is the list of entries to create in the dictionary and default values. The object can contain a special function-the initialize function. The same function can be provided directly to the Class call when you want to create properties programmatically. The initialize function is something really close to the idea of a constructor as you may know it from mainstream programming languages.

How can you implement inheritance in MooTools? The Class type supports two special properties: Extends and Implements. The former accepts the name of another Class object and adds a new property to the class being created, named parent. The parent property contains an instance of the class specified as Extends. The Implements property, instead, appends all the properties in the specified class to the target. In a way, Extends simulates inheritance, whereas Implements simulates composition:

// Define the class known as PersonBase
var PersonBase = new Class({
    initialize: function(name, lastName) {
        this.Name = name;
        this.LastName = lastName;
    }
});
    
// Define a more specific class
var Person = new Class({
    Extends: PersonBase,
    initialize: function(name, lastName) {
        this.parent(name, lastName);
        this.Age = 0;
    }
});
    
// Start creating instances of Person type
var dino = new Person('Dino', 'Esposito');
dino.Age = 20;
    
// Not Dino?
alert(dino.Name + ", age " + dino.Age);

The Class type features two key properties: Extends simulates inheritance, whereas Implements simulates composition.

In the example, you start with a PersonBase class that contains and initializes only name and last name. Next, you create a Person class that extends PersonBase by adding a new property Age. In the initialize method (i.e., the constructor) of Person you also use the parent implicit property to call the constructor of the PersonBase class, which ensures that name and last name are initialized properly.

Sometimes you don’t want to create a brand new class and extend your hierarchy. Sometimes, you just want to modify an existing class to add some new members. MooTools offers a more compact syntax that gets you the same benefits of using Implements without managing two distinct classes. Here’s an example:

// Define a the class known as Person
var Person = new Class({
    initialize: function(name, lastName) {
        this.Name = name;
        this.LastName = lastName;
    }
});
    
// Extend Person to incorporate new members
Person.implement({
    Age: 0,
    ToString: function() {
       return this.Name + ", age " + this.Age;}
});
    
// Creating instances of (modified) Person type
var dino = new Person('Dino', 'Esposito');
dino.Age = 20;
    
// Not Dino?
alert(dino.ToString());

The implement method is analogous to using Object.append, except that it works for Class types.

Checking the type of an object at run time is a bit tricky in spite of the availability of common-sense functions such as typeOf and instanceOf. In particular, the typeOf function takes an instance and returns a string defining the recognized type. The recognition process is more precise than plain JavaScript but not as precise as one might expect. In fact, the following code snippet returns “object” instead of a more precise name:

// Define the class known as Person
var Person = new Class({
    initialize: function(name, lastName) {
        this.Name = name;
        this.LastName = lastName;
    }
});
    
var p = new Person('Dino', 'Esposito');
alert(typeOf(p)); // returns "object"

If you call typeOf on Person you get “class” as a response instead of “object”.

The instanceOf function returns a Boolean answer when you pass an instance and a type. The answer refers to the instance of the specified type. Here’s an example:

// Define the class known as Person
var Person = new Class({
    initialize: function(name, lastName) {
        this.Name = name;
        this.LastName = lastName;
    }
});
    
var p = new Person('Dino', 'Esposito');
alert(instanceOf(p, Person)); // returns "true"

As you can see, instanceOf correctly recognizes user-defined types. However, it returns false if you ask whether an instance of Person is also a Class:

alert(instanceOf(p, Class)); // returns "false"

The programming interface of classes in MooTools is completed by a few predefined classes that serve specific purposes of the framework. Classes like Chain, Events, and Options may be used to enrich the programming interface of your class and add specific functionality. You typically import these features using Implements. Refer to the online documentation for more details about extra classes in the framework.

Browser Detection

In MooTools, you get browser information by querying the Browser object. Note that the object doesn’t give you more than Boolean answers. In other words, you can’t ask about the current platform or capabilities, but you can query whether a given feature is supported. In the end, this is what you need to do most of the time. The Browser object returns three main types of information: features, type, and platform.

Recognized features are listed in Table 1. As you can see, there’s no attempt to provide a comprehensive API and features are limited to just the few aspects of a browser behavior that might make a difference for today’s developers.

Each of the expressions in Table 1 returns a Boolean value or, in some cases, undefined.

On the Browser object you also find the Platform property with a list of Boolean properties to let you quickly check whether the current browser is running on a given platform such as Mac, Linux, or Windows, as well as some mobile platforms such as iPhone/iPad, Android, and webOS. If you just want to know the name of the platform, you use the following code:

// Return the name of the underlying platform.
alert(Browser.Platform.name);

Working with the DOM

Writing a JavaScript application mostly means manipulating the DOM and querying for specific subsets of elements. Modern browsers support DOM selectors and natively implement complex and sophisticated searches over the DOM. The plus that JavaScript libraries can offer is providing a browser-independent API that leverages native browser capabilities when available and resorts to built-in implementations otherwise.

Overall, the DOM query capabilities of MooTools are equivalent to those of jQuery-the syntax is a bit different though. MooTools is centered on the document.id function that you use as below:

// Retrieve the DOM element with a matching name.
alert(document.id("TextBox1"));

The function retrieves the element with the specified ID. It is aliased by the popular $ function. However, using the $ function is not recommended if you’re using multiple JavaScript libraries in the same application. It may result in conflicts and subtle bugs. The id function has a double purpose: in addition to retrieving the specified DOM element (if any), it also ensures that the representation of the element is coherent with the MooTools Element class.

Most browsers-nearly all of them with the notable exception of Internet Explorer-provide a flexible representation of their DOM HTML elements that libraries can extend with custom methods. This is not possible in Internet Explorer due to the internal implementation of HTML elements, which are still based on COM objects. In MooTools, when you call id, and the browser is Internet Explorer, the retrieved element is also normalized to be an Element object as defined in MooTools. The operation requires a bit of work with Internet Explorer; it is a matter of appending properties with other browsers.

To retrieve multiple elements, you use the $$ function. The $$ function to query DOM elements supports the CSS3 syntax as in jQuery and works with all browsers that support query selectors. The $$ function returns an array of Element instances. As mentioned, Element is the MooTools type that represents a DOM element:

// Retrieve all DIVs styled as headers.
var headerElements = $$("div.header");

The $$ function to query DOM elements supports the CSS3 syntax as in jQuery and works with all browsers that support query selectors.

The Element type features many methods for you to query child elements and modify the DOM tree dynamically. You use the get method to read and the set function to update the status of a DOM element. Here’s an example:

// Read the current value of an input field.
var value = $('TextBox1').get('value');
    
// Modify the value.
value = value + " (modified)";
    
// Write back the modified value.
$('TextBox1').set('value', value);

MooTools also provides several capabilities for adding elements to the DOM and for building DOM subtrees programmatically. In particular, you might want to look at the inject method used to inject an Element in the body of another. The overall set of capabilities here is analogous to jQuery but with a different syntax. Check out the documentation at http://mootools.net.

Related to DOM manipulation is event handling. MooTools provides its own Event class that normalizes under a common API the differences in underlying browsers. Here’s a code snippet that shows how to add an event handler:

$('Button1').addEvent('keydown', function(event) {
   // Event handling happens here
});

The event handler function receives an instance of the Event type that carries all event specific data, such as mouse buttons, keyboard, window and client position, and wheel status.

Making Network Calls

Making a remote call in MooTools is an operation that passes through the Request object. The Request object is a wrapper for the browser’s implementation of XmlHttpRequest. Here’s how to use it:

// Prepares a request to a URL
var request = new Request({
    url: '/customer/details/1234'
});
// Sends the request
var response = request.send();

The constructor of the Request object gets a collection of properties through which you can customize the request at will. At a minimum, you need to specify the URL you want to connect to. You can set options to add headers, set encoding, make the request synchronous or asynchronous, cache response, pass credentials, and indicate the HTTP method and a timeout.

The Request object also lets you decide what to do in case other requests (i.e., the user follows a hyperlink) are started while a request is pending. Options are to queue the request, ignore it, or kill the current request to start the new one immediately.

MooTools fires several events during the request. Of particular interest is the progress event that returns information about the progress made during the download. Note that this event is active only on browsers that implement it-not in Internet Explorer.

A couple more specific objects exist built on top of the Request object. They are Request.HTML and Request.JSON. As you may easily guess, they are made-to-measure methods to grab HTML and JSON content respectively. Here’s how to use the Request.HTML object:

// Prepare the request.
var request = new Request.HTML({
    url: '/customer/details',
    data: {
        id: 1234,
        level: 'full'
    },
    method: 'post',
    update: 'panelDetails'
});
    
// Send the request.
request.send();

Facilities include the update property, which indicates the ID of the element to modify with the downloaded HTML. By making this call, any HTML returned will be automatically inserted inside of the DOM where specified. The Request.JSON object works similarly:

// Prepare the request.
var request = new Request.JSON({
    url: '/customer/details',
    data: {
        id: 1234,
        level: 'full'
    },
    method: 'post',
    onSuccess: 'updatePanel'
});
    
// Send the request.
request.send();

The function is optimized to return JSON data that you can access as a JSON object (responseJson property) or as plain text (responseText property). You can use the onSuccess property to define your own callback, which will be automatically invoked to give you a chance to process the response:

// Sample callback function to process JSON data
function updatePanel(response) {
    // Process the response from the server
}

You can pass plain data (integers, strings) as well as JSON objects. In the latter case, you can use JSON.encode to take a JavaScript object and transform it into a JSON string.

When you make calls from the client, most browsers restrict you to calling just the server that served the current page. Any attempt to make an AJAX call outside the boundaries of the origin site will be rejected for security reasons. However, for historical reasons no limitations are ever applied to making the <script> tag point to other domains. JSONP is a protocol developed as an extension of JSON to enable safe cross-domain calls from JavaScript. JavaScript frameworks offer different JSONP interfaces, but it always results in a script tag being created dynamically to support a JSONP call to a server that explicitly supports the JSONP protocol. In MooTools, all you need to do for a cross-domain call is using Request.JSONP instead of Request.ISON-easy and effective.

Special Effects

The first AJAX applications to appear mostly received a royal welcome but also some negative feedback. In particular, users complained about how hard it was to catch changes being made to the page. In other words, the update was so quick and seamless that users often missed it. This led to introducing transition effects in nearly every JavaScript framework out there. MooTools is no exception.

In MooTools, you have two types that implement special effects to help developers make changes easier to spot for end users and transitions and animation easier to implement.

The FX.Tween class is used to take any CSS property and make its value change from the current value to a final value. Needless to say, the change occurs over a loop; the value changes progressively and animates the view:

// Find the element to animate
var element = $('theForm');
    
// Create and configure the effect
var effect = new Fx.Tween(element);
    
// Animate property from black to red
effect.start('background-color', '#000', '#ff0000');
    
// Animate property from current color to red
effect.start('background-color', '#ff0000');

The Tween class works on a single property at a time. To animate multiple properties at the same time, you use the FX.Morph type:

// Find the element to animate
var element = $('theForm');
    
// Create and configure the effect
var effect = new Fx.Morph(element,
    {
      duration: 'long'
    });
    
// Start the effect
effect.start({
    'background-color': ['#000', '#ff0000'],
     :
});

The start method gets an object containing the list of properties to change and the values in the desired range. When defining the effect you can also indicate the duration of the transition through a relative value.

The FX.Transition class lets you control the internal algorithm that determines the succession of values within a transition. The default transition is linear, meaning that values for the animated properties move linearly from the starting value to the final value. MooTools offer alternate algorithms too. You specify the transition mode when you create the effect:

// Create and configure the effect
var effect = new Fx.Morph(element,
    {
      duration: 'long',
      transition: FX.Transitions.Linear
    });

Altogether, the FX classes allow you to create interesting animations. One of the secrets for this to work is that the FX base classes support chaining multiple actions. In the end, you create animations by concatenating transitions.

Summary

JavaScript is probably not the language of choice for anybody who wants to write web applications. However, it is the only option that you can reasonably consider if you want reach all browsers out there. At least for the time being, I firmly believe that you can’t just transform JavaScript into something that is radically different from what the language is today. However, the web has repeatedly proven to be a surprisingly dynamic and agile environment; so who really knows what could happen in five years?

Currently, the most effective approach to adding more power to the client is using ad hoc libraries full of DOM and animation facilities and adding new features to the existing JavaScript language. Interestingly, a single all-encompassing library seems to be unrealistic. Everybody wants something more or something less. So the ideal JavaScript library is often obtained by stacking up and composing together bits and pieces of existing libraries in a custom recipe that meets the need of a particular application.

jQuery excels in adding interaction to a page; MooTools is a better fit to write your own application-specific framework.

When it comes to JavaScript libraries today, the first choice is jQuery. However, jQuery is highly focused on DOM interaction and UI manipulation. Admittedly, this is what one needs to do most of the time. The jQuery library also offers a number of facilities to work with strings and primitive types. However, it doesn’t offer any mechanism for writing plain JavaScript code. While jQuery excels in adding interaction to a page, a library like MooTools is a better fit when you are writing your own application-specific framework. MooTools allows object-orientation and quick and effective manipulation of objects. It also provides a rich-enough programming interface for DOM manipulation and effects. The two libraries-jQuery and MooTools-can live side by side and there’s no reason I can think of for you to choose just one. However, if you must choose just one, and you’re writing your own framework, MooTools is probably a better choice than jQuery.