At the Forge - Prototype
During the last few months, we have looked at ways to use JavaScript, a version of which is included in nearly every modern Web browser. For most of its life, JavaScript has been used to create simple client-side effects and actions on Web pages. But during the past year or two, JavaScript has taken center stage as part of the Ajax (Asynchronous JavaScript and XML) paradigm. It is no longer enough to create Web applications that reside on the server. Modern Web applications must include Ajax-style behavior, which probably means integrating JavaScript into the mix of server-side programs, HTML and relational databases.
As we have seen in the last few installments of this column, however, using JavaScript requires a fair amount of repeated code. How many times must I invoke document.getElementById(), just to grab nodes that I want to modify? Why must I create a library that handles the basic Ajax calls that I will be making on a regular basis? Must I create all of my own widgets and graphic effects?
Fortunately for Web developers everywhere, the explosive interest in Ajax has led to equally productive work on libraries to answer these questions and needs. Many of these libraries have been released under open-source licenses and are thus available for Web developers to include in a variety of different types of sites.
This month, we look at one of the best-known JavaScript libraries, known as Prototype. Prototype, developed by Sam Stephenson (a member of the Ruby on Rails core team), has been included in all copies of Ruby on Rails for some time. Prototype aims to make it easier to work with JavaScript, offering a number of shortcuts for some of the most common uses.
If you are using Ruby on Rails for your Web applications, Prototype is already included. You can begin to use it in your applications by adding the following inside a Rails view template:
<%= javascript_include_tag 'prototype' %>
If you are not using Rails, you still can use Prototype. Simply download it from its site (see the on-line Resources). Then use:
<script type="text/javascript" src="/javascript/prototype.js"></script>
The above assumes, of course, that you have put prototype.js in the /javascript URL on your Web server. You might have to adjust that URL to reflect the configuration of your system.
Once you have included Prototype, you can start to take advantage of its functionality right away. For example, Listing 1 shows simpletext.html. This file contains some simple JavaScript that changes the headline to the contents of the text field when you click on the submit button.
Listing 1. simpletext.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Title</title>
<script type="text/javascript">
function removeText(node) {
if (node != null)
{
if (node.childNodes)
{
for (var i=0 ; i < node.childNodes.length ; i++)
{
var oldTextNode = node.childNodes[i];
if (oldTextNode.nodeValue != null)
{
node.removeChild(oldTextNode);
}
}
}
}
}
function appendText(node, text) {
var newTextNode = document.createTextNode(text);
node.appendChild(newTextNode);
}
function setText(node, text) {
removeText(node);
appendText(node, text);
}
function setHeadline () {
var headline = document.getElementById("headline");
var fieldContents = document.forms[0].field1.value;
setText(headline, fieldContents);
}
</script>
</head>
<body>
<h2 id="headline">Simple form</h2>
<form id="the-form" action="/cgi-bin/foo.pl" method="post">
<p>Field1: <input type="text" id="field1" name="field1" /></p>
<p><input type="button" value="Change headline"
onclick="setHeadline()"/></p>
</form>
</body>
</html>We do this by defining a function (setHeadline) and then by setting that function to be invoked when we click on the button:
<p><input type="button" value="Change headline"
onclick="setHeadline()"/></p>Now, what happens inside setHeadline? First, we grab the node containing the headline:
var headline = document.getElementById("headline");Then, we get the contents of the text field, which we have called field1:
var fieldContents = document.forms[0].field1.value;
Notice how we must grab the value by going through the document hierarchy. First, we get the array of forms from the document (document.forms), then we grab the first form (forms[0]), then we grab the text field (field1), and then we finally get the value.
Now we can set the value of the headline by attaching a text node to the h2 node. We do this with a function called setText, which I have included in simpletext.html; setText depends in turn on removeText and appendText, two other helper functions that make it easy to work with text nodes in JavaScript.
All of this is very nice and is typical of the type of JavaScript coding I often do. How can Prototype help us? By simplifying our code using two built-in functions. The first, $(), looks a bit strange but is legitimate—its full name is $ (dollar sign), and it performs much the same task as document.getElementById, returning the node whose ID matches its parameter. The second, $F, returns the value from the form element whose ID matches the parameter.
In other words, we can rewrite our function as:
function setHeadline() {
var headline = $("headline");
var fieldContents = $F("field1");
setText(headline, fieldContents);
}Sure enough, this works just as well as the previous version. However, it's a bit easier to read (in my opinion), and it allows us to avoid traversing the document hierarchy until we reach the form element.
We can improve our code even further by removing our setText, updateText and removeText functions, all of which were included simply because JavaScript doesn't provide any easy way to manipulate the text of a node. But Prototype does through its Element class, allowing us to rewrite setHeadline as:
function setHeadline() {
Element.update($("headline"), $F("field1"));
}The code invokes Element.update, handing it two parameters: the node whose text we want to modify and the text we want to insert in place of the current text. We have just replaced 30 lines of our code with one line, thanks to Prototype. You can see the result in Listing 2.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- New Products
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




5 min 8 sec ago
4 hours 36 min ago
4 hours 37 min ago
6 hours 37 min ago
15 hours 22 min ago
15 hours 56 min ago
16 hours 55 min ago
17 hours 45 min ago
21 hours 47 min ago
1 day 1 hour ago