File Under: Frameworks, JavaScript

Get Started With Prototype

Much of the web counts on JavaScript for its interactivity and for many years it was difficult to write. Browser inconsistencies and complicated code made even advanced coders grimace. JavaScript frameworks, such as Prototype, jQuery and MooTools have taken much of the pain away.

These frameworks sit on top of JavaScript and make common tasks a whole lot easier. Prototype is the granddaddy of JavaScript frameworks. It was the first to gain wide popularity, probably due to its pairing with the Ruby on Rails server-side programming framework.

In this tutorial, I’ll provide an introduction to the Prototype way of writing JavaScript. We’ll find objects on the page in various ways and manipulate them. You’ll still be writing JavaScript, but in an abbreviated form using Prototype shorthand. The best part is the stuff that caused the headaches–like the differences in browser implementations–is taken care of for you.

Let’s get started learning Prototype and writing shorter, hassle-free JavaScript.

Contents

  1. What You Need
  2. Start With Some HTML
  3. Find Your Elements
    1. Find by ID
    2. Find by Class
    3. Find by Tag
    4. Filter What You Find
      1. Filter for the First Object of Many
      2. Filter out a Specific ID
  4. Observe Events
    1. The dom:ready Event
    2. Click Events
  5. Re-order an Ordered List
    1. Start with HTML
    2. Observe Clicks on All List Items
    3. Swap Clicked Item with Above Item
  6. Where to go From Here

What You Need

  • Knowledge of HTML and CSS
  • Basic JavaScript experience
  • A copy of the Prototype source file. Name it prototype.js (at least for these examples)

Start With Some HTML

Before we dive into Prototype, we need to set up the HTML for the examples I’ll show you in this tutorial. Make sure the file you create is in the same directory as the prototype.js file you downloaded. Then put this HTML into your new file:

<html>

<head>

	<title>Testing Prototype</title>

	<script src="prototype.js"></script>

	<style>



		/* CSS goes here */

	</style>

	<script>

		// JavaScript goes here

	</script>

</head>

<body>



</body>



</html>


Opened in a browser, the above is blank. That’s because it’s only a starting place for the code you’ll be adding into it. Even though it’s empty, Prototype is being loaded. Check out the script line where src="prototype.js" — that’s where we’re loading it.

Another note about scripts. The code we create in this tutorial will be written within one main HTML file. According to convention, we’d import an external JavaScript file instead via a link (just as we’ve done with the prototype.js file). The same goes for CSS, which we’ll put between the style tags. For this tutorial I’m including scripts and styles inline because I want to make the code easy to read and manipulate.

Before we move on to the code, let’s set up the HTML and CSS you’ll be using in the next section.

Add this between the body tags:

<div id="container">

<span>SPAN<br />No id</br />No class</span>



<span class="test" id="second">SPAN<br />id="second"</br />class "test"</span>

<div class="test">DIV<br />No id</br />class "test"</div>

</div>



<p>

<strong>Toggles:</strong>

</p>


And put this between the style tags:

#container div, #container span

{

	width: 150px;

	height: 150px;

	display: block;

	float: left;

	border: 1px solid black;

}

#container .highlight

{

	border: 3px solid orange;

}

p

{

	clear: left;

}

p input

{

	display: block;

}


Reload the HTML file you created and you’ll see a few squares on your screen. Presto! You’re all prepped for Prototype. If you want to skip the copy and paste, you can download the file directly from Wired servers instead.


Find Your Elements

At the core of the Prototype features is its ability to find pieces of the page. We can call elements by ID, class name and type of tag. Then we can filter down granularly from there.

In this section, I’ll show you several examples, so you can see the power of Prototype yourself.

Find by ID

To find a single object, we search for its ID. Prototype does this with the dollar sign function. In our basic HTML file, there is a div with id="second". To grab that div, we just need this one line: $("second")

Let’s check this out in our example HTML file. Add the following underneath the “toggles” section near the bottom of the HTML:

<input type="button" onClick="javascript:test_byid();" value="id='second'" />


This line adds a button to the page that, when clicked, calls the test_byid() function. We need to make sure that function will be there when we call it, so add this between the script tags in the example HTML file:

	function test_byid()

	{

		$("second").toggleClassName("highlight");

	}


Save the file, reload, and click the new button. The second span (the one with id="second") highlights.

Find by Class

Let’s take it up a notch and get a little more useful. Using CSS classes can make your code simpler. For one, there aren’t as many IDs floating around. This one requires the double dollar sign function. The syntax is similar to CSS, where we put a period in front of the class name. To grab an object of class “test,” use this code: $$(“.test”)

Now test it in your example HTML. Here’s the code for the testing button:

<input type="button" onClick="test_byclass();" value="class='test'" />


And now the JavaScript, which you should paste below the previous function:

	function test_byclass()

	{

		$$(".test").each(function(elmt) { elmt.toggleClassName("highlight") });

	}


Reload the file and click the new button. The two right boxes (the ones with class="test") highlight.

You may notice that here I introduced a new piece of Prototype, the /each/ function. Since we are calling the double dollar sign function, there may be several results. In fact, we’re getting two objects back. So, the each function helps us perform an action on each result, one at a time.

I created an anonymous function, which means it is declared inline and has no name. That’s because the function is only used this one place, though it is used many times, once for each result. In our example, every item that has the “test” class gets passed to the anonymous function. Then, the toggleClassName function from Prototype is used to add an additional class name, “highlight,” to the element.

It may look a bit like gibberish, but it’s an important part of programming with Prototype. If you don’t completely get it now, that’s okay. There will be more anonymous functions coming up soon.

Find by Tag

Like grabbing by class, if we want tags, the call to the double dollar sign function looks like CSS. So, in this case, just pass along the tag you want, like this: $$("span")

Paste this code into the example HTML file:

<input type="button" onClick="test_bytag();" value="tag is 'span'" />




	function test_bytag()

	{

		$$("span").each(function(elmt) { elmt.toggleClassName("highlight") });

	}


Reload and click the new button. You’l see the two left boxes (the ones that are span tags) highlight.

As with finding by class name, finding by tag needs to use the each function to iterate through all the results.

Filter What You Find

Are you getting the hang of finding objects on the page using Prototype? Now we’ll start filtering the results. The best part is that it can still happen in a single line by adding a bit after our normal call to the double dollar sign function.

Filter for the First Object of Many

As we know from above, there are two spans. In the first example, we want to only grab the first span. To achieve this, we use the /first-child/ filter. Let’s see it in action. First, the HTML:

<input type="button" onClick="test_byfirstresult();" value="the first object where tag is 'span'" />


	function test_byfirstresult()

	{

		$$("span:first-child").each(function(elmt) { elmt.toggleClassName("highlight") });

	}


Reload and click the new button. Sure enough, only the first span highlights. But notice that in the code, I still called the each function. That’s because $$ always returns an array-like object, holding one or more page objects. It may be annoying, sure, but it’s worth the effort for all the other times, when we want more than one object.

Filter out a Specific ID

Now let’s use a slightly more advanced filter. Here, we are again going to grab all the spans, but this time we want to filter out the one with id="second". To do this, we’ll use the /not/ filter, which requires a CSS call in parentheses. I know it’s starting to look pretty complicated, but think of all the work we’ve crammed into a tiny amount of JavaScript.

Here’s the HTML:

<input type="button" onClick="test_byfunction();" value="tag is 'span', but id is not 'second'" />


And the JavaScript:

	function test_byfunction()

	{

		$$("span:not(#second)").each(function(spanobj) {

		  spanobj.toggleClassName("highlight");

		});

	}


Reload, click the button, and be amazed. The left span highlights, but the other one, the one with class="second",does not highlight. Thank you, Prototype.

Now that you’re able to grab page objects, it’s time to start doing something with them. It requires using some events. Continue on and see how Prototype can do something when the page first loads and also how to react to mouse clicks.

Observe Events

JavaScript event handling with Prototype is easy. Any differences among browsers is handled for you. In Prototype, you /observe/ an object, waiting for its events.

The dom:ready Event

Prototype adds a special event called /dom:ready/. This can be used to know when it’s okay to initialize the page. The dom:ready event happens when the document object model (DOM) is ready to be accessed. If you put all JavaScript code that needs to happen when the page loads inside the dom:ready event, then you ensure that it will run as early as possible, but not too early.

To add the dom:ready event, put this code in the JavaScript section of your page:

		document.observe('dom:loaded', function() {

			alert('DOM is loaded!');

		});


If you save and reload your file, you’ll get a message that says the DOM is loaded. Sure, there isn’t much happening here, but this event is a building block for future events. For example, read on to see how you can observe click events.

Click Events

Sometimes we want to react to a mouse click from the user. Often the click will be on specific objects, so let’s add some HTML:

<div id="myclicker">Click me!</div>


In the example from the previous section, replace the dom:loaded section with this new code:

	document.observe('dom:loaded', function() {

		$("myclicker").observe("click", function() { alert('Clicked!'); });

	});


Reload and try clicking around. When you click on the new section (the text that says “Click me!”) the browser will alert you that it saw the click.

Let’s take a step back and take stock of what’s going on. First, we wait for the dom:loaded event. Then, once the DOM has loaded, we tell it to look out for any clicks on the object with id=”myclicker” and respond with an alert.

This is a bit complicated, yes. There are two anonymous functions in a row! Prototype can’t keep you from having to write JavaScript, which is sometimes complicated. But it can make it as simple as possible. In this case, just a few lines to achieve so much.

At this point in the tutorial, you should be able to find most elements on the page using Prototype. Your code should resemble our copy residing in the code library. Here’s a live example of the code in action:

Now let’s put your new-found Prototype prowess to use in an example–re-ordering an ordered list.

Re-order an Ordered List

Easy access to the objects on a page will change how you approach user interfaces. One thing we’ve seen over the last few years is the ability to easily re-order lists, such as your Netflix queue on the DVD rental site.

In this example, we’ll use a list of Sylvester Stallone’s Rambo movies. I picked Stallone because he has a few things in common with Prototype:

  1. Redefined a genre–action movies for Stallone, JavaScript for Prototype.
  2. Make big things happen on the screen — both movie and computer screens.
  3. Still going strong despite young new stars.

Let’s get to re-ordering Rambo.

Start with HTML

I’ve put together some simple HTML to show the Rambo movies in the order they were produced. Let’s write some code to let users change the order to their liking.

<html>

<head>



	<title>Testing Prototype</title>

	<script src="prototype.js"></script>

	<script>

	document.observe('dom:loaded', function() {

		// Code to run when DOM is loaded goes here

	});

	</script>

</head>



<body>



<ol id="rambolist">

<li>First Blood (1982)</li>

<li>Rambo: First Blood Part II (1985)</li>

<li>Rambo III (1988)</li>



<li>Rambo (2008)</li>

</ol>



</body>

</html>


Note there’s a dom:loaded event, but nothing inside it. It’s time to change that.

Observe Clicks on All List Items

In a previous section, I showed how to observe a single click event and respond. Now we need to add a click event for each of the items in the list. You may be inclined to give each list item its own ID and add four observe events, one for each. Instead, we’ll use the power of Prototype to make the code simpler and more versatile.

Inside the dom:loaded event, add this code:

		$$('ol#rambolist li').each(function(elmt) {

			elmt.observe('click', function(ev) {

				// Code to respond to each click goes here

				alert(ev.target.innerHTML);

			});

		});


Reload the file and click a list item. You should see its contents in an alert message. That is just to prove it’s working. We’ll remove the alert in the next section. First, a little about how this new code works.

Using the double dollar sign function, we call up each list item using a CSS selector. Note that it’s a slightly more complicated selection than in previous examples. We’re finding every list item that is a child of the ordered list with id="rambolist". Just as that would work for styling in CSS, it works for grabbing objects using Prototype.

Then I used the /each/ function to go through all of the list items that we found. On each of those elements, I observe a click. So, we’re still observing four separate events, but we didn’t need to add IDs to our list items. And the best part, should there be another Rambo movie (and one is rumored), all we need to do is add it to the list. No need to mess with the JavaScript.

Swap Clicked Item with Above Item

Now that we are able to respond to a click on any list item, we need to decide what to do with it. My plan for this example is to move any item clicked up one spot in the list. So, if I wanted to move Rambo III to the top slot, I’d need to click it twice.

To find the item above the one clicked, we’ll use a special Prototype function called /previousSiblings/, which tells us every item that comes before the one clicked.

Go ahead and remove the alert line from the previous example and replace it with this code for swapping the clicked item with the one right above it:

				var listitem = ev.target;

				var aboveitems = listitem.previousSiblings();

				if (aboveitems.length > 0)

				{

					var itemtext = aboveitems[0].innerHTML;

					aboveitems[0].innerHTML = listitem.innerHTML;

					listitem.innerHTML = itemtext;

				}


The output from the call to previousSiblings goes into a new variable I created called /aboveitems/. The rest of the code only gets called if the length of aboveitems is more than 0. What’s that about? If there are no items occuring before the clicked item, it can only mean one thing: the user clicked on one in the top of the list!

If there are items above the clicked item, we perform a three step process to swap the values:

  1. Save the text of the above item
  2. Set the new text of the above item to the text of our clicked item
  3. Set the new text of the clicked item to be what we saved in step one

The outcome is that now the clicked item is up one slot, just like we wanted.

If you got lost along the way, we’ve got a copy of the code in the code library. Here’s what it should look like:

Where to go From Here

Now that you have the basic concepts of Prototype down, you’re ready to start building something with it. I hope this introduction to Prototype has given you some ideas of how it can help you write simpler JavaScript with fewer browser inconsistencies.

To get more ideas of some amazing things that can be done with Prototype, check out the add-on effects library script.aculo.us, which lets you drag and drop objects and fade elements in and out of view.

Even with just Prototype, options are endless because it is a framework upon which to build. Try to improve upon my list re-ordering example (how can you move something down?), create a puzzle game, or an expanding menu.