Article
Painless JavaScript Using Prototype
Prototype is an object oriented JavaScript library (written by Sam Stephenson and friends) that makes JavaScript fun. So it says on the site, anyway. Those of you who are familiar with the open source community's latest and greatest application framework, Rails, may recognise Prototype as it actually forms the backbone of Rails' JavaScript helper. However, Prototype can be used independently of Rails to aid the coding of many JavaScript doodads and Web 2.0 thingy wangles.
Personally, I think the jury's out on the whole 'fun' JavaScript thing, but nevertheless Prototype is a really well executed JavaScript library which, although the situation has been improving of late, has had notoriously sparse documentation. This article provides a whirlwind tour of the whole library. It aims to give you enough examples and resources to get started using Prototype in your DOM scripting projects.
First, we'll examine the basic building blocks of Prototype: its $ functions, its additions to the String, Number, Array and Function objects, its form handling capabilities and its DOM functions. Then, we'll move on to look at Prototype's well-known AJAX helpers. Finally, we'll finish with a brief discussion of other interesting projects that are based on it.
I'd like to note that the current stable version of Prototype at time of writing is 1.4.0. I have a feeling that the library will change quite quickly in response to Rails' lightning-quick development cycle, so things will change. The final boring note is that at this time Prototype only supports the newer browsers -- as you might expect of a DOM and XMLHttpRequest based library. See the Prototype site for details of browser support.
Getting Started
The latest version of Prototype can be downloaded from the prototype site. Simply download prototype.js and link it to your pages with a <script> tag:
<script type="text/javascript" src="path/to/prototype.js"></script>
If you're on Rails, you don't need to download Prototype: it's included in the distribution. You can include it into your views by putting this into the <head> of your pages:
<%= javascript_include_tag 'prototype' %>
Now, let's get into it!
Prototype's Little Helpers
One of the really nice things about using Prototype is the deadly simple helper functions that it provides for very common scripting tasks. The $ function has already been getting some attention. Give it one or more element IDs, and it'll return references to them:
// reference to the element with the ID 'nav'
$("nav")
// an array of element references
$("img1", "img2", "img3")
It's like a souped-up document.getElementById and it's amazing how much more convenient coding seems when you use it.
Another incredibly useful function is document.getElementsByClassName, which does what it says on the tin: it takes a CSS class name and returns a list of all elements with that class:
// all elements with class 'navlink'
document.getElementsByClassName("navlink")
// all elements with class navlink and inside the element with ID 'nav'
document.getElementByClassName("navlink", $("nav"))
Also, as this article was being written, Prototype version 1.5.0_rc0 gained the powerful $$ function, which allows you to select elements using standard CSS selector syntax:
// an array of all input elements inside 'commentform'
$$("#commentform input")
// an array of all links with the class 'external'
$$("a.external")
Please note that, at the time of writing, unless you download the very latest version of Prototype from Subversion, this function won't be available to you.
$F takes an ID and returns the value of any form field, for instance, a select box like this:
<select name="country" id="country">
<option selected="selected" value="UK">United Kingdom</option>
<option value="FR">France</option>
...
</select>
$F('country') // 'UK'
Making JavaScript Suck Less
Oops, I've stolen another JavaScript library's tag line. JavaScript library developers just can't seem to keep from trying to make JavaScript be like another language. The Mochikit guys want JavaScript to be Python, countless programmers have tried to make JavaScript like Java, and Prototype tries to make it like Ruby. Prototype makes extensions to the core of JavaScript that can (if you choose to use them) have a dramatic effect on your approach to coding JavaScript. Depending on your background and the way your brain works, this may or may not be of help to you.
OO the Ruby(ish) way: Class.create and Object.extend
The Class.create method allows you to define classes in a more Ruby-like way, although this is purely aesthetic as it essentially just calls the initialize method you define as the constructor, rather than the taking the traditional JavaScript approach of creating objects with constructor functions.
var DOMTable = Class.create();
DOMTable.prototype = {
initialize : function(el) {
this.el = el;
},
...
}
However, much more powerful is the stupidly simple but effective Object.extend method. All it does is copy one object's properties and methods to another object, but its uses are many. Here's a quick taster:
// make a (shallow) copy of obj1
var obj2 = Object.extend({}, obj1);
var options = {
method : "post",
args : ""
};
// merges in the given options object to the default options object
Object.extend(options, {
args : "data=454",
onComplete : function() { alert("done!"); }
});
options.method // "post"
options.args // "ata=454"
options.onComplete // function() { alert("done!"); }
It's most commonly used to "mix in" methods from one object with another. For instance, you could create a set of functions that make certain DOM elements sortable:
var Sortable = {
sortBy : function(func) {
...
},
sortByReversed : function(func) {
...
},
reset : function() {
...
}
};
Then, if we wanted to make our DOMTable from above sortable, we could mix in these methods to the DOMTable object:
var myTable = new DOMTable("table-id");
Object.extend(myTable, Sortable);
Now we can call those methods on the table:
// sort the table using the given function
myTable.sortBy(function (itemA, itemB) { ... });
Dan is a rehabilitated DHTML hacker turned web application developer for