Table of Contents

Prototype and Scriptaculous: Taking the Pain out of JavaScript
Prototype and Scriptaculous: Taking the Pain out of JavaScript
by Chris Angus
Publisher: O'Reilly
Pub Date: November 01, 2006
Print ISBN-10: 0-596-52919-8
Print ISBN-13: 978-0-59-652919-2
Pages: 56

Copyright
Introduction
Chapter 1. Why Use Prototype and Scriptaculous?
Section 1.1. Writing Event Handlers Without Prototype
Section 1.2. Making Ajax Calls Without Prototype
Section 1.3. Creating Effects Without Scriptaculous
Section 1.4. Dragging and Dropping Without Scriptaculous
Chapter 2. Techniques Used When Calling the APIs
Section 2.1. Defining Classes
Section 2.2. JavasScript Is a Prototype Rather than OO Language
Section 2.3. Closures / Anonymous Functions and Functions as Objects
Section 2.4. Objects as Bags of Properties, Duck Typing, and JSON
Section 2.5. What Is 'this'
Chapter 3. Using Prototype
Section 3.1. Utility Functions
Section 3.2. Creating Classes in a More Object-Oriented style
Section 3.3. Extensions to Core JavaScript Objects
Section 3.4. Manipulating Documents
Section 3.5. Enumerable Objects and Iterator Functions
Section 3.6. Hashes
Section 3.7. Ajax
Section 3.8. General Principles
Chapter 4. Using Scriptaculous
Section 4.1. Getting Started
Section 4.2. Visual Effects
Section 4.3. Toggling Effects
Section 4.4. Controls
Section 4.5. AutoCompletion
Section 4.6. Drag-and-Drop
Section 4.7. Putting Everything Together
Chapter 5. Prototype and Scriptaculous Members
Section 5.1. Conventions Used
Section 5.2. Ajax members (Prototype)
Section 5.3. Ajax.Base members (Prototype)
Section 5.4. Ajax options members (Prototype)
Section 5.5. Ajax.PeriodicalUpdater members (Prototype)
Section 5.6. Ajax.Request members (Prototype)
Section 5.7. Ajax.Responders members (Prototype)
Section 5.8. Ajax.Updater members (Prototype)
Section 5.9. Array members (Prototype)
Section 5.10. Autocompleter members (Scriptaculous)
Section 5.11. Class members (Prototype)
Section 5.12. Document members (Prototype)
Section 5.13. Draggable members (Scriptaculous)
Section 5.14. Draggables members (Scriptaculous)
Section 5.15. Droppables members (Scriptaculous)
Section 5.16. Effect members (Scriptaculous)
Section 5.17. Effect.Highlight members (Scriptaculous)
Section 5.18. Effect.MoveBy members (Scriptaculous)
Section 5.19. Effect.Opacity members (Scriptaculous)
Section 5.20. Effect options members (Scriptaculous)
Section 5.21. Effect.Parallel members (Scriptaculous)
Section 5.22. Effect.Scale members (Scriptaculous)
Section 5.23. Element members (Prototype)
Section 5.24. Element.ClassNames (Prototype)
Section 5.25. Enumerable members (Prototype)
Section 5.26. Event members (Prototype)
Section 5.27. Field members (Prototype)
Section 5.28. Form members (Prototype)
Section 5.29. Form.Element (Prototype)
Section 5.30. Form.Element.Observer members (Prototype)
Section 5.31. Form.Element.EventObserver members (Prototype)
Section 5.32. Form.Element.Serializers members (Prototype)
Section 5.33. Form.Observer members (Prototype)
Section 5.34. Form.EventObserver members (Prototype)
Section 5.35. Function members (Prototype)
Section 5.36. Global members (Prototype)
Section 5.37. Hash members (Prototype)
Section 5.38. Insertion.After members (Prototype)
Section 5.39. Insertion.Before members (Prototype)
Section 5.40. Insertion.Bottom (Prototype)
Section 5.41. Insertion.Top members (Prototype)
Section 5.42. Number members (Prototype)
Section 5.43. Object members (Prototype)
Section 5.44. ObjectRange members (Prototype)
Section 5.45. PeriodicalExecuter members (Prototype)
Section 5.46. Prototype members (Prototype)
Section 5.47. String members (Prototype)
Section 5.48. Try members (Prototype)


Copyright

Copyright © 2006, O'Reilly Media, Inc.. All rights reserved.


Introduction

As the number of interfaces developed using browser technology is increasing, user expectations for UI sophistication are also increasing. Techniques that might be suitable for an occasional-use website or a non-interactive news site quickly become tedious when used on a daily basis. JavaScript helps developers break users out of this tedium, allowing the creation of more powerful user interfaces while still keeping the zero-install advantages of a browser.

JavaScript, however, is neither the easiest language in which to develop nor the most forgiving. Supporting the quirks and API differences of various browsers often drives developers to tear their hair out. Difficulty doing easy things soon leads to near impossibility of doing hard things.

Prototype and Scriptaculous pull JavaScript back from this brink and make it a much stronger technology for creating reasonably complex user interfaces. It offers more powerful abstractions and a consistent API.

This document is a jump-start into using Prototype and Scriptaculous that will allow readers to start using these libraries and provide enough insight to understand the Prototype and Scriptaculous resources available on the Web. As such, is it not meant as authoritative documentation, but more as a guide to what these technologies can do and how to get started using them.


Chapter 1. Why Use Prototype and Scriptaculous?

If you've ever written cross-browser JavaScript then you'll know how poorly JavaScript interfaces on different browsers are matched. Prototype takes a lot of these headaches away, leaving a consistent, standards-compliant API that is compatible with multiple browsers. It supports tasks including:

  • Event handling and observation

  • DOM manipulation

  • String processing

  • Event observation

  • Form processing

  • Asyncronous JavaScript and XML (Ajax)

In addition, it provides generally useful facilities around loops, array processing and higher-order combining forms that allow code to be glued together in more powerful ways.

Scriptaculous takes this one step further, adding. It adds controls, composable effects, and drag-and-drop, making it easier to use JavaScript for more complex tasks and richer user interfaces.

Prototype and Scriptaculous do not bring anything new to JavaScript; they simply make it quicker, easier, and less complex. In this section we will discuss a few areas where using Prototype and Scriptaculous drastically simplifies code.

1.1. Writing Event Handlers Without Prototype

Prior to Prototype, writing cross-browser event-handling code probably meant writing code like:

function clickHandler(evt)
{
       evt = (evt) ? evt : ((event) ? event : null);
       if (evt)
       {
              var elem = (evt.target) ? evt.target :
                           ((evt.srcElement) ? evt.srcElement : null);
              if (elem)
              {
                     // act on event
                     ...
              }
       }
}

Figuring this out is painful! Fortunately, with Prototype, you can forget all this and work with portable events. Consider the following cross-browser JavaScript that finds the enclosing DIV element closest to the element that fired the event, and then cancels the default action associated with that event.:

Code View: Scroll / Show All
function clickHandler(evt)
{
       evt = (evt) ? evt : ((event) ? event : null);
       if (evt)
       {
              var elem = (evt.target) ? evt.target :
                           ((evt.srcElement) ? evt.srcElement : null);

              while (elem != null && elem.tagName != 'DIV')
              {
                     elem = elem.parent;
              }
              if (elem)
              {
                     // some processing on this DIV element
              }
              if (evt.returnValue)
              {
                     evt.returnValue = false;
              }
              else if (evt.preventDefault)
              {
                     evt.preventDefault();
              }
              else
              {
                     return false;
              }
       }
}

Using Prototype this can be written as:

function clickHandler(evt)
{
       var elem = Event.findElement(evt,'DIV')
       if (elem)
       {
              // some processing on this DIV element
       }
       Event.stop(evt);
}

Which is far simpler and far more understandable.


Section 1.1. Writing Event Handlers Without Prototype

Why Use Prototype and Scriptaculous? > Writing Event Handlers Without Prototype

Chapter 1. Why Use Prototype and Scriptaculous?

If you've ever written cross-browser JavaScript then you'll know how poorly JavaScript interfaces on different browsers are matched. Prototype takes a lot of these headaches away, leaving a consistent, standards-compliant API that is compatible with multiple browsers. It supports tasks including:

  • Event handling and observation

  • DOM manipulation

  • String processing

  • Event observation

  • Form processing

  • Asyncronous JavaScript and XML (Ajax)

In addition, it provides generally useful facilities around loops, array processing and higher-order combining forms that allow code to be glued together in more powerful ways.

Scriptaculous takes this one step further, adding. It adds controls, composable effects, and drag-and-drop, making it easier to use JavaScript for more complex tasks and richer user interfaces.

Prototype and Scriptaculous do not bring anything new to JavaScript; they simply make it quicker, easier, and less complex. In this section we will discuss a few areas where using Prototype and Scriptaculous drastically simplifies code.

1.1. Writing Event Handlers Without Prototype

Prior to Prototype, writing cross-browser event-handling code probably meant writing code like:

function clickHandler(evt)
{
       evt = (evt) ? evt : ((event) ? event : null);
       if (evt)
       {
              var elem = (evt.target) ? evt.target :
                           ((evt.srcElement) ? evt.srcElement : null);
              if (elem)
              {
                     // act on event
                     ...
              }
       }
}

Figuring this out is painful! Fortunately, with Prototype, you can forget all this and work with portable events. Consider the following cross-browser JavaScript that finds the enclosing DIV element closest to the element that fired the event, and then cancels the default action associated with that event.:

Code View: Scroll / Show All
function clickHandler(evt)
{
       evt = (evt) ? evt : ((event) ? event : null);
       if (evt)
       {
              var elem = (evt.target) ? evt.target :
                           ((evt.srcElement) ? evt.srcElement : null);

              while (elem != null && elem.tagName != 'DIV')
              {
                     elem = elem.parent;
              }
              if (elem)
              {
                     // some processing on this DIV element
              }
              if (evt.returnValue)
              {
                     evt.returnValue = false;
              }
              else if (evt.preventDefault)
              {
                     evt.preventDefault();
              }
              else
              {
                     return false;
              }
       }
}

Using Prototype this can be written as:

function clickHandler(evt)
{
       var elem = Event.findElement(evt,'DIV')
       if (elem)
       {
              // some processing on this DIV element
       }
       Event.stop(evt);
}

Which is far simpler and far more understandable.


Section 1.2. Making Ajax Calls Without Prototype

Why Use Prototype and Scriptaculous? > Making Ajax Calls Without Prototype

1.2. Making Ajax Calls Without Prototype

As with most things in JavaScript, using the XMLHttpRequest object (the heart of Ajax) is straightforward but verbose. If you've ever called an HTTP-based service, your code probably looks something like this:

Code View: Scroll / Show All
xhr=null;

function getData(url)
{
       if (window.XMLHttpRequest)
       {
         xhr=new XMLHttpRequest()
       }
       else if (window.ActiveXObject)
       {
         xhr=new ActiveXObject("Microsoft.XMLHTTP")
       }
       if (xhr)
       {
         xhr.onreadystatechange=callback
         xhr.open("GET",url,true)
         xhr.send(null)
       }
       else
       {
         alert("XMLHTTP not supported")
       }
}

function callback()
{
       // when finished
       if (xhr.readyState==4)
       {
              //  OK
              if (xhr.status==200)
              {
              // process the result.
       }
       else
       {
              alert("error")
       }
  }
}

With Prototype, this can be written as:

Code View: Scroll / Show All
function getData(url)
{
       var ar = new Ajax.Request(url,{ method: "get", onComplete : callback});
}

function callback(request)
{
       // process the result.
       var text = request.responseText;
       ...
}


Section 1.3. Creating Effects Without Scriptaculous

Why Use Prototype and Scriptaculous? > Creating Effects Without Scriptaculous

1.3. Creating Effects Without Scriptaculous

Writing visual effects in raw JavaScript is hard—very hard! If you want to know how hard it is, then just have a go. The good news is that with Scriptaculous, it is trivial. To create a simple wipe-down effect, we may do the following:

<div id="e1"><p>element to wipe</p></div>

<script>

          function wipeDown()
          {
                 Effect.BlindDown("el");
          }

</script>

<a href="javascript; void (wipeDown())">click to run effect</a>

Doing this in raw JavaScript is left as a very optional and not-particularly-recommended exercise for the reader.


Section 1.4. Dragging and Dropping Without Scriptaculous

Why Use Prototype and Scriptaculous? > Dragging and Dropping Without Scriptaculous

1.4. Dragging and Dropping Without Scriptaculous

if you thought writing effects in raw JavaScript was hard, coding drag-and-drop is even worse! Again, the good news is that with Scriptaculous, this complexity is dealt with. To create a simple drag-and-drop, example we may do the following:

<img id="dragTarget" class="cdragTarget" src=" dragTarget.jpg"/>

<div id="dropTarget" class="cdropTarget">
          <img src="dropTarget.jpg" />
</div>

<script type="text/javascript">

         new Draggable('dragTarget',{revert:true});

         Droppables.add(
                'dropTarget',
                {
                     accept: 'cdragTarget',
                     onDrop: function(element)  { alert('dropped');}
                }
         );

</script>

Hopefully by now you'll be hooked, and want to know more about how to avoid the challenges of raw JavaScript coding. However, before diving into the APIs, it's a good idea to review some JavaScript concepts that are used when calling each library. If you are already a JavaScript Guru, feel free to jump ahead.


Chapter 2. Techniques Used When Calling the APIs

As previously mentioned, Prototype and Scripaculous do not bring anything new to JavaScript. They do, however, use all of its features and stretch them to their limits. This section discusses some of the more advanced JavaScript features that both libraries use.

2.1. Defining Classes

Since JavaScript is a prototype-based language rather than an object-oriented language, defining classes is a bit long winded.

Consider a simple Point class that has two attributes, x and y.

This may be defined in raw JavaScript as:

var Point = function(x,y)
{
       this.x = x;
       this.y = y;
}

function Point_toString()
{
       return "Point(" +this.x+","+this.y+")";
}

Point.prototype.toString = Point_toString;

New instances may be created using the new keyword:

var myPoint = new Point(0,0);


Section 2.1. Defining Classes

Techniques Used When Calling the APIs > Defining Classes

Chapter 2. Techniques Used When Calling the APIs

As previously mentioned, Prototype and Scripaculous do not bring anything new to JavaScript. They do, however, use all of its features and stretch them to their limits. This section discusses some of the more advanced JavaScript features that both libraries use.

2.1. Defining Classes

Since JavaScript is a prototype-based language rather than an object-oriented language, defining classes is a bit long winded.

Consider a simple Point class that has two attributes, x and y.

This may be defined in raw JavaScript as:

var Point = function(x,y)
{
       this.x = x;
       this.y = y;
}

function Point_toString()
{
       return "Point(" +this.x+","+this.y+")";
}

Point.prototype.toString = Point_toString;

New instances may be created using the new keyword:

var myPoint = new Point(0,0);


Section 2.2. JavasScript Is a Prototype Rather than OO Language

Techniques Used When Calling the APIs > JavasScript Is a Prototype Rather than OO Language

2.2. JavasScript Is a Prototype Rather than OO Language

It is temping to think of Point as a class that we have defined, but that is not really the case. Point is actually simply a reference to a function, and we could quite as easily defined the instance as:

var myPoint = new Object();
myPoint["x"]           = 0;
myPoint["y"]           = 0;
myPoint["toString"]    = Point_toString;
myPoint["constructor"] = Point;

Here we have created a generic hash-like object and set on it different values and functions. When we define class by defining a constructor and filling in the prototype object, we simply give an instruction about how the object should initially be wired up. The functions that are defined on the class are not actually related in any way to the class.


Section 2.3. Closures / Anonymous Functions and Functions as Objects

Techniques Used When Calling the APIs > Closures / Anonymous Functions and Functions as Objects

2.3. Closures / Anonymous Functions and Functions as Objects

In JavaScript, the definition:

function add(x,y)
{
      return x+y;
}

is equivalent to:

var add = function(x,y)
{
      return x+y;
}

Both create a variable named add to reference a function object. In the second version, however, the function is anonymous. The ability to create anonymous functions means that we can create specialized functions (or closures).

var createAdditionClosure = function(x,y)
{
      return function() {x+y;}
}

And then call this via:

var fn = createAdditionClosure(1,2);
var value = fn();

This ability allows us to capture contextual state and wrap it up into an event handler:

element.onClick = function() { // operations on current context }


Section 2.4. Objects as Bags of Properties, Duck Typing, and JSON

Techniques Used When Calling the APIs > Objects as Bags of Properties, Duck Typing, and JSON

2.4. Objects as Bags of Properties, Duck Typing, and JSON

In JavaScript, objects are really no more than bags of properties. There is no real concept of class and no type checking. This fact leads to code that has a contract around the properties that an object has rather than the type that it is. This is sometime called duck typing from the idea that if it looks like a duck and quacks like a duck, then for all intents and purposes it can be considered is a duck. This also means that we could create a Point object as:

var point = new Object();
point.x = 0;
point.y = 0;

JavaScript, however, has a shortcut notation for this kind of thing, called JavaScript Object Notation (JSON). JSON lets us write this as:

var point = {x:0,y:0};

JSON allows objects to be nested to an arbitrary level. It may contain all valid JavaScript objects, making it ideal for defining configuration.:

var config = {
                     param1: 0.0,
                     functionToRun: function() { ...},
                     args: [0.0,'x',{x:0,y:0}]
             };


Section 2.5. What Is 'this'

Techniques Used When Calling the APIs > What Is 'this'

2.5. What Is 'this'

If you're used to using languages like C++, C#, or Java™, then you'll probably be used to the idea that inside a method, this refers to the object that the method belongs to. It's very different in JavaScript, as methods do not belong to objects. Instead, this refers to the object that a method is called on - that may change from object to object.

var fn = function()
{
       return this.x;
}

var widget = new Widget();
var person = new Person();

widget.getX = fn;
person.returnX = fn;

widget.getX(); // here this is the widget.
person.returnX(); // here this is the person.

This can be confusing when we are using event handlers.

. Consider a counting class:

function Count()
{
       this.count = 0;
}

Count.prototype.add = function() { this.count++;}

Now assume we have a link on an HTML page:

<a href='#' id = 'a0'>count</a>

If we were to wire up an event handler like:

document.getElementById('a0').onClick = myCount.add;

Then we would not increment the count object, but instead attempt to increment a property called count on the a object. This is because the above code actually gets called on the a object, not the Count object. To make sure it gets called on the count object, we must instead use a closure.

 document.getElementById('a0').onClick = function() {myCount.add();}


Chapter 3. Using Prototype

The Prototype distribution is available from http://prototype.conio.net. The file prototype-x.x.x.js (at the time of writing: prototype-1.4.0.js) should be saved to a convenient location and renamed prototype.js.

Figure 3-1. Prototype download page

Using Prototype involves making the script in prototype.js visible to your own JavaScript. This is usually done via the script tag specifying the URL of prototype.js:

<script src="URL" content="text/javascript"></script>

Although Prototype can be referenced directly from the prototype distribution site, it is preferable and faster to work locally.

The following example assumes that prototype.js has been placed in a js directory and that the HTML file is alongside that directory.

C:\javascriptBook>dir /s /b
C:\javascriptBook\js
C:\javascriptBook\referencingPrototype.html
C:\javascriptBook\js\prototype.js

The example shows a sample HTML file that uses Prototype and may be used as a simple sanity check.

Example 3-1. referencingPrototype.html

Code View: Scroll / Show All
<html>
<head>
    <title>Using Prototype</title>
    <script src="js/prototype.js" content="text/javascript"></script>
</head>
    <body id='body'>
    <script content="text/javascript">
    new Insertion.Top($('body'),'Using Prototype version:'+Prototype.Version);
    </script>
</body>
</html>

If you are using a JavaScript as your only scripting language, you may alternatively set this up using the defaulting mechanism of HTML 4:

Example 3-2. referencingPrototype2.html

Code View: Scroll / Show All
<html>
<meta http-equiv="Content-Script-Type" content="text/javascript">
<head>
    <title>Using Prototype</title>
    <script src="js/prototype.js"></script>
</head>
    <body id='body'>
    <script>
    new Insertion.Top($('body'),'Using Prototype version:'+Prototype.Version);
    </script>
</body>
</html>

When loaded into a JavaScript-enabled browser, the page produces the following output.

Figure 3-2. Example running

Congratulations! You have just written your first Prototype-enabled JavaScript.

3.1. Utility Functions

Prototype adds a handful of utility functions into JavaScript that although simple, are very useful.

3.1.1. The $ function

The global function $ plays a similar role to document.getElementById. However, as well as being much more terse, $ has the following advantages.

  • It can be passed either ids or the elements themselves.

  • It can be passed multiple arguments to yield an array of Elements.

  • The objects it returns "mix in" the Element Prototype object.

Code View: Scroll / Show All
var el = $(id); // finding the element by id
el = $(el);     // finding an element by the element
var images = $("mouseoverimage","mouseoutimage"); // finding multiple elements by ids

Locating an element, given the element itself, may seem pretty pointless until you consider the situation when you don't know if you have an element id or the element itself. By using the $ function, you know you definitely have the element. This technique is used to allow other prototype functions to work on either the element or the id.

3.1.2. The $F function

The global function $F allows quick access to form values. It takes the id of the form field and returns the value. In the extract below, the values for the name and gender from the form:

<FORM>
             <INPUT name="name" id="name" TYPE="text" value="textval">
             <SELECT name="gender" id="gender">
                       <OPTION value="M">male</option>
                       <OPTION value="F">female</option>
             </SELECT>
</FORM>

may be accessed via $F("name") and $F("name"). Again, the $F function can take either the id or the element itself.

3.1.3. Prototype functions

The Prototype object has two predefined functions, K and emptyFunction.

  • K is the identity function that returns anything passed to it.

  • emptyFunction is a do-nothing function.

Prototype typically uses these to implement the null-object pattern over functions. Rather than producing code that flows like:

var fn=...
if (fn)
{
       fn(...);
}
else
{
       // default action
}

We instead write code like:

var fn=...
(fn||Prototype.K)(...);

which reads as:

if fn is undefined/null then call K

This means that functional parameters may often be defaulted.

3.1.4. The $H function

The global function $H turns its object into a Hash, meaning that its keys and values may be accessed.

3.1.5. The $A function

The global function $A turns its object into an array, which is useful when the passed object is a non-array collection.


Section 3.1. Utility Functions

Using Prototype > Utility Functions

Chapter 3. Using Prototype

The Prototype distribution is available from http://prototype.conio.net. The file prototype-x.x.x.js (at the time of writing: prototype-1.4.0.js) should be saved to a convenient location and renamed prototype.js.

Figure 3-1. Prototype download page

Using Prototype involves making the script in prototype.js visible to your own JavaScript. This is usually done via the script tag specifying the URL of prototype.js:

<script src="URL" content="text/javascript"></script>

Although Prototype can be referenced directly from the prototype distribution site, it is preferable and faster to work locally.

The following example assumes that prototype.js has been placed in a js directory and that the HTML file is alongside that directory.

C:\javascriptBook>dir /s /b
C:\javascriptBook\js
C:\javascriptBook\referencingPrototype.html
C:\javascriptBook\js\prototype.js

The example shows a sample HTML file that uses Prototype and may be used as a simple sanity check.

Example 3-1. referencingPrototype.html

Code View: Scroll / Show All
<html>
<head>
    <title>Using Prototype</title>
    <script src="js/prototype.js" content="text/javascript"></script>
</head>
    <body id='body'>
    <script content="text/javascript">
    new Insertion.Top($('body'),'Using Prototype version:'+Prototype.Version);
    </script>
</body>
</html>

If you are using a JavaScript as your only scripting language, you may alternatively set this up using the defaulting mechanism of HTML 4:

Example 3-2. referencingPrototype2.html

Code View: Scroll / Show All
<html>
<meta http-equiv="Content-Script-Type" content="text/javascript">
<head>
    <title>Using Prototype</title>
    <script src="js/prototype.js"></script>
</head>
    <body id='body'>
    <script>
    new Insertion.Top($('body'),'Using Prototype version:'+Prototype.Version);
    </script>
</body>
</html>

When loaded into a JavaScript-enabled browser, the page produces the following output.

Figure 3-2. Example running

Congratulations! You have just written your first Prototype-enabled JavaScript.

3.1. Utility Functions

Prototype adds a handful of utility functions into JavaScript that although simple, are very useful.

3.1.1. The $ function

The global function $ plays a similar role to document.getElementById. However, as well as being much more terse, $ has the following advantages.

  • It can be passed either ids or the elements themselves.

  • It can be passed multiple arguments to yield an array of Elements.

  • The objects it returns "mix in" the Element Prototype object.

Code View: Scroll / Show All
var el = $(id); // finding the element by id
el = $(el);     // finding an element by the element
var images = $("mouseoverimage","mouseoutimage"); // finding multiple elements by ids

Locating an element, given the element itself, may seem pretty pointless until you consider the situation when you don't know if you have an element id or the element itself. By using the $ function, you know you definitely have the element. This technique is used to allow other prototype functions to work on either the element or the id.

3.1.2. The $F function

The global function $F allows quick access to form values. It takes the id of the form field and returns the value. In the extract below, the values for the name and gender from the form:

<FORM>
             <INPUT name="name" id="name" TYPE="text" value="textval">
             <SELECT name="gender" id="gender">
                       <OPTION value="M">male</option>
                       <OPTION value="F">female</option>
             </SELECT>
</FORM>

may be accessed via $F("name") and $F("name"). Again, the $F function can take either the id or the element itself.

3.1.3. Prototype functions

The Prototype object has two predefined functions, K and emptyFunction.

  • K is the identity function that returns anything passed to it.

  • emptyFunction is a do-nothing function.

Prototype typically uses these to implement the null-object pattern over functions. Rather than producing code that flows like:

var fn=...
if (fn)
{
       fn(...);
}
else
{
       // default action
}

We instead write code like:

var fn=...
(fn||Prototype.K)(...);

which reads as:

if fn is undefined/null then call K

This means that functional parameters may often be defaulted.

3.1.4. The $H function

The global function $H turns its object into a Hash, meaning that its keys and values may be accessed.

3.1.5. The $A function

The global function $A turns its object into an array, which is useful when the passed object is a non-array collection.


Section 3.2. Creating Classes in a More Object-Oriented style

Using Prototype > Creating Classes in a More Object-Oriented style

3.2. Creating Classes in a More Object-Oriented style

Previously we saw how to create classes in raw JavaScript. The good news is that by using Prototype, we may do this is a more streamlined manner. One thing to note is that the notion of class and object in JavaScript is blurred and there is no real notion of class, so it is better thinking of one object sharing properties with other objects rather than one class extending another.

3.2.1. Class.create and the initialize method

Rather than taking the JavaScript approach of defining a constructor function and separately defining its methods, we can define a class in one go using:

Class.create.
var Point = Class.create();

This creates a class template that delegates to a method called initialize,, which can be considered from Prototype's point of view as its constructor.

We then define the prototype object for this class, defining its constructor (initialize) and methods in one go.

Point.prototype =
{
       initialize : function(x, y)
       {
              this.x = x;
              this.y = y;
       },
       toString : function()
       {
              return "Point(" +this.x+","+this.y+")";
       }
}

3.2.2. Extending classes

Like most OO langauges, Prototype allows us to create an object by extending an existing object, although the way it achieves this is quite different. Prototype uses the method Object.extend to implement extension.

This method takes two objects—a source and a destination—and copies each of the properties from the source to the destination before returning the destination. This means that it can be used to "implement interfaces" by copying properties from the abstract object onto the concrete one.

This is common in Prototype. For example, the core JavaScript Event object is extended to add extra members using this mechanism.

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,

  element: function(event) {
    return event.target || event.srcElement;
  },
      ...
});


Section 3.3. Extensions to Core JavaScript Objects

Using Prototype > Extensions to Core JavaScript Objects

3.3. Extensions to Core JavaScript Objects

Prototype also extends the following core JavaScript objects:

  • Document

  • Function

  • String

  • Array

  • Number

  • Event

3.3.1. Extensions to document

Document is extended to support finding elements via their CSS class. This is implemented by the method: getElementsByClassName(id[,parent])

which returns all elements of a certain CSS class. It takes an additional optional element (or id) parameter that limits the search to within that element.

3.3.2. Extensions to function

Functions are extended to better support binding an event handler onto the method of a particular object instance. Consider the counting class from earlier:

function Count()
{
       this.count=0;
}
Count.prototype.add = function() { this.count++;}
Var myCount = new Count();

We discussed earlier the fact that if we directly mapped an event handler onto myCount.add via:

element.onClick = myCount.add

it would not run on the correct instance. At the time, we solved this by adding an anonymous function:

element.onClick = function() {myCount.add();}

Prototype, however, extends Function to support this via the bind method call.

Using the bind method, we may instead write:

element.onClick = myCount.add.bind(myCount);

and avoid having to explicitly create anonymous functions.

Additionally, Function also contains a bindAsEventListener function, which does a similar job to bind, but instead is applied to functions that take events.

Using bindAsEventListener allows us to write cross-browser code such as:

MyMethod = function (event)
{
      Event.stop(event);
}

element.onclick = myMethod.bindAsEventListener(someObject);

The event is passed into the method transparently without the need for additional plumbing code.

3.3.3. Extensions to string

Prototype's String extensions provide extra utility functions.

Camelize | Converts get-x to getX
escapeHTML | Returns a string with characters like < >, etc., escaped
evalScripts | Evaluates each <script> in the string
extractScripts | Returns an array of <script> tags found in the string
parseQuery | Turns a string like x=1&y=2 to {x:1,y:2}
stripScripts | Teturns a string with <script> tags removed
stripTags | Returns a string with markup removed
toArray | Returns a character array
toQueryParms | Turns a string like x=1&y=2 to {x:1,y:2}
unescapeHTML | Returns a string with HTML escaping reversed

3.3.4. Extensions to array

Prototype extends Array by adding extra functions, but by far its most useful feature is that arrays implement the Enumerable interface. This interface allows one to write functional code like:

function whereEven(value)
{
       return ((value % 2)==0);
}

var array = [1,2,3,4,5,6,7,8];
var evens = array.findAll(whereEven);

3.3.5. Extensions to number

Prototype extends Number by adding extra functions, but by far its most useful feature is that it adds the times function, allowing loops to be written as:

function run(index)
{
       alert('iteration number:' + index);
}

var N = 10;
N.times(run);

3.3.6. Extensions to events and observers

Prototype extends events by adding utility methods and constants. It also, however, implements the observer pattern over events, meaning that multiple actions can be associated with an event.

Normally in JavaScript, you may only install one event handler.

element.onClick = handler;

If you have two handlers, you could do something like:

element.onClick = function() {handler1();handler2();}

But this starts to get messy. Prototype allows the code to be written:

Event.observe(element,'click',handler1,false);
Event.observe(element,'click',handler2,false);

Meaning that multiple observers can consume the same events. Additionally, we can stop observing an event via:

Event.stopObserving(element,'click',handler1,false);
Event.stopObserving(element,'click',handler2,false);


Section 3.4. Manipulating Documents

Using Prototype > Manipulating Documents

3.4. Manipulating Documents

Prototype provides utilities for manipulating documents via the Insertion objects.

Insertion.Before | Inserts content before an element
Insertion.After | Inserts content after an element
Insertion.Top | Inserts content at the top of an element
Insertion.Bottom | Inserts content at the bottom of an element

These are called via:

new Insertion.function('id',content);

For example, the code:

Code View: Scroll / Show All
<span id='result'>The result is:</span>
<a href="javascript:void (new Insertion.Bottom('result','100'))">click for result</a>

results in the text The result is:100 being displayed.


Section 3.5. Enumerable Objects and Iterator Functions

Using Prototype > Enumerable Objects and Iterator Functions

3.5. Enumerable Objects and Iterator Functions

Prototype brings higher-order functions to mainstream JavaScript in the form of enumerable objects. The Enumeration interface represents a collection objects and exposes a set of functions that allow the manipulation of these objects using iterator functions.

An iterator function is a normal JavaScript function of the form:

var iterator = function(value,index)
{
       ...
}

where the arguments to this function represent a value from the collection and the index that the value is at within the collection. Armed with an iterator function, we may make use of the functions on Enumerable.

each | Calls the iterator on each element
all | Returns true if all iterators return true
any | Returns true if any iterator returns true
collect | Maps the iterator across the collection, returning a collection of results in the same order
detect | Returns first element for which the iterator returns true
entries | Returns an array of elements
find | Same as detect
findAll | Returns all elements for which the iterator returns true
grep | Returns all elements for which a regular expression matches
include | Returns true if a given object is in the collection
inject | Collapses the collection into a value using the iterator with an additional initial accumulating parameter as an accumulator.
invoke | Invokes a member function (passing in arguments) on each element in the collection
map | Same as collect
max | Returns the maximum element
member | Same as include
min | Returns the minimum element
partition | Returns a two-element array containing the collection elements partitioned according to the iterator's Boolean return value.
pluck | Returns a collection containing the passed property for each element in the collection
reject | Returns all elements for which the iterator returns false
select | Same as findAll
sortBy | Returns a sorted array (sorted by iterator return values)
toArray | Same as entries
zip | Merges collections

These functions allow complex looping logic to be removed from the code, leaving the more readable remainder. As mentioned earlier, Prototype makes JavaScript Arrays instances of Enumerable, meaning that these techniques can be applied to arrays also, which is what we did in the code:

function whereEven(value)
{
       return ((value % 2)==0);
}

var array = [1,2,3,4,5,6,7,8];
var evens = array.findAll(whereEven);


Section 3.6. Hashes

Using Prototype > Hashes

3.6. Hashes

In Prototype, Hash objects extend Enumerable objects by adding utility functions around HTTP queries and by allowing access to key and value arrays.


Section 3.7. Ajax

Using Prototype > Ajax

3.7. Ajax

Prototype simplifies working with Ajax via Ajax.Request and related objects, which simplify by using the XmlHttpRequest object. To make an Ajax call, we create an Ajax.Request object, passing in the URL of the web service along with configuration options:

var ajaxRequest = new Ajax.Request(url, options)

Method | HTTP method (GET, POST, PUT, etc)
Parameters | String holding URL parameters
Aynchronous | True/false
postBody | The body to post if the method is POST
requestHeaders | Flattened array of key value pairs for header values
onComplete | Callback
onLoaded | Callback
onLoading | Callback
onInteractive | Callback
onUninitialized | Callback
onSuccess | Callback
onFailure | Callback
onException | Callback

An example of using Ajax is given below. As this document is about JavaScript and not web services, we will use a static document as the server to allow testing. The file is called rate.json and contains:

({rate:1.85})

Example 3-3. Calling a JSON service using Ajax

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>

</head>
<body>
<script type="text/javascript">
       function callbackComplete(from,to,request)
       {
              var json = request.responseText;
              var obj = eval(json );
              alert('the rate from '+from+' to '+to+' is currently ' + obj.rate);
       }

       function getRate()
       {
              var from = 'UK';
              var to   = 'US';

              var url = "rate.json?from=" + from + "&to=" + to;
              var ajaxRequest = new Ajax.Request(url,
              {
                     method: 'post',
                     nComplete : function(req) {callbackComplete(from,to,req);}

              });
       }
</script>
<a href="javascript:void getRate()">get Rate</a>
</body>
</html>

3.7.1. Walkthrough

In the example above, we initially call the function getRate.

Code View: Scroll / Show All
       function getRate()
       {
              var from = 'UK';
              var to   = 'US';

              var url = "rate.json?from=" + from + "&to=" + to;
              var ajaxRequest = new Ajax.Request(url,
              {
                     method: 'post',
                     onComplete : function(req) {callbackComplete(from,to,req);}

              });
       }

This function constructs and URL and creates a new instance of Ajax.Request, passing in the fact that we want to do a HTTP POST rather than a GET

                     method: 'post',

and the handler function to run when the call returns:

Code View: Scroll / Show All
                     onComplete : function(req) {callbackComplete(from,to,req);}

This makes the HTTP call. When the call returns successfully, a callback is made on the handler function, which in turn calls callbackComplete.

Code View: Scroll / Show All
function callbackComplete(from,to,request)
       {
              var json = request.responseText;
              var obj = eval(json );
              alert('the rate from '+from+' to '+to+' is currently ' + obj.rate);
       }

This function takes grabs the response as text and evaluates this JSON expression to create a JavaScript object, which it then interrogates to yield the rate.

Using Ajax with dynamic content is handled in exactly the same manner. However, this is outside the scope of this document. Mark Pruett's "Ajax and Web Services" Short Cut explores this in much greater depth, including how to deal with complications like proxying.

A more complex version of the above example that makes use of an existing free web service provided by xmethods.net is given below.

Example 3-4. Calling a SOAP service using Ajax

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Ajax</title>
    <script src="js/prototype.js" ></script>

</head>
<body>
<script type="text/javascript">
       var SOAP_URL = "http://services.xmethods.net:80/soap";
       var SOAP_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>'+
                           '<soap:Envelope
xmlns:mrns0="urn:xmethods-CurrencyExchange" '+

       'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" '+

       'xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" '+
                                  'xmlns:xs="http://www.w3.org/2001/XMLSchema" '+
                                  'xmlns:xsi="http://www.w3.org/
2001/XMLSchema-instance">'+
                                  '<soap:Body
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'+
                                  '<mrns0:getRate>'+
                                  '<country1 xsi:type="xs:string">_FROM_</country1>'+
                                  '<country2 xsi:type="xs:string">_TO_</country2>'+
                                  '</mrns0:getRate>'+
                                  '</soap:Body>'+
                                  '</soap:Envelope>';

       function callbackComplete(from,to,request)
       {
              var dom = request.responseXML;
              if (window.netscape)
              {
       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
              }
              var rate =
($A(dom.getElementsByTagName('Result')))[0].firstChild.nodeValue;
              alert('the rate from ' + from + ' to ' + to + ' is currently ' + rate);

       }

       function getRate()
       {
              var from = 'UK';
              var to   = 'US';

              if (window.netscape)

       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

              var soapRequest =
SOAP_TEMPLATE.replace(/_FROM_/,from).replace(/_TO_/,to);
              var url = SOAP_URL;
              var ajaxRequest = new Ajax.Request(url,
              { method: 'post',
                     requestHeaders : [
                     'Content-Type' , 'text/xml; charset="utf-8"',
                            'SOAPAction',     '""'
                     ],
                     postBody:soapRequest,
                     onComplete : function(req) {callbackComplete(from,to,req);}

              });
       }
</script>
<a href="javascript:void getRate()">get Rate</a>
</body>
</html>

Figure 3-3. Results of soap-ajax.html

3.7.2. Monitoring progress

One of the handier features helps keep track of the progress of Ajax calls by adding a responder:

Ajax.Responders.register({
              onCreate:   function(){ $('activity').show(); },
              onComplete: function() {
                     if(Ajax.activeRequestCount == 0){
                           $('activity').hide();
                     }
              }
       });


Section 3.8. General Principles

Using Prototype > General Principles

3.8. General Principles

As you may have noticed, Prototype applies a few general principles that users should be aware of, and that make Prototype code look slightly different from other JavaScript.

Interchangeable elements and ids

Elements and ids can be interchangeable in function calls, if a function expects a document id. It can normally take the element directly in place of the id.

Configuration via JSON

Options are typically passed to functions as JSON objects.

Loops are codes as higher-order functions

Loops are often replaced by Enumerations.

Higher-order combining forms are used

Prototype uses unusual combining forms, such as combining functions prior to their application.


Chapter 4. Using Scriptaculous

    Section 4.1. Getting Started

    Section 4.2. Visual Effects

    Section 4.3. Toggling Effects

    Section 4.4. Controls

    Section 4.5. AutoCompletion

    Section 4.6. Drag-and-Drop

    Section 4.7. Putting Everything Together

4.1. Getting Started

The Scriptaculous distribution is available from http://script.aculo.us/downloads.

Figure 4-1. Scriptaculous downloads page

The file scriptaculous-js-x.x.x.zip (at the time of writing: scriptaculous-js-1.6.2.zip) should be saved and unpacked to a convenient location.

The distribution contains a lib directory containing the file prototype.js and a src directory containing the following Scriptaculous files:

  • scriptaculous.js

  • builder.js

  • effects.js

  • dragdrop.js

  • controls.js

  • slider.js

  • unittest.js

These files (including prototype.js) should be copied to a convenient location (the file unittest,js is optional).

NOTE

The version of Prototype may differ from the version of Prototype you already have. If this is the case, the later version of Prototype should be used. At the time of writing, Scriptaculous 1.6.2 uses Prototype-1.5.1rc0, while the latest released version of Prototype is 1.4.0. In this case, if we want to use Scriptaculous, we should use prototype-1.5.1rc0 as prototype.js throughout.

Using Scriptaculous involves making the script in prototype.js and scriptaculous.js visible to your own JavaScript. This is usually done via the script tag, specifying the URLs of prototype.js and scriptaculous.js in that order.

<script src=prototypeURL content="text/javascript"></script>
<script src=scriptaculousURL content="text/javascript"></script>

The following example assumes that:

  • scriptaculous.js

  • builder.js

  • effects.js

  • dragdrop.js

  • controls.js

  • slider.js

have been placed in a js directory and that the HTML file is alongside the directory.

            C:\javascriptBook>dir /s /b
C:\javascriptBook\js
C:\javascriptBook\referencingScriptaculous.html
C:\javascriptBook\js\builder.js
C:\javascriptBook\js\controls.js
C:\javascriptBook\js\dragdrop.js
C:\javascriptBook\js\effects.js
C:\javascriptBook\js\prototype.js
C:\javascriptBook\js\scriptaculous.js
C:\javascriptBook\js\slider.js

It shows a sample HTML file that uses Scriptaculous and may be used as a simple sanity check.

Example 4-1. referencingScriptaculous.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Using Scriptaculous</title>
    <script content="text/javascript" src="js/prototype.js" ></script>
    <script content="text/javascript" src="js/scriptaculous.js"></script>
</head>
<body>
    <a href="javascript:void Effect.toggle('d1',blind');">
open/close blind</a>
<div id="d1" style="background-color:green;height:300px;width:200px"></div>
</body>
</html>

If you are using a JavaScript as your only scripting language, you may alternatively set this up using the defaulting mechanism of HTML 4:

Example 4-2. referencingScriptaculous2.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
<meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>
</head>
<body>
    <a href="javascript:void Effect.toggle('d1',blind');">
open/close blind</a>
<div id="d1" style="background-color:green;height:300px;width:200px"></div>
</body>
</html>

When loaded into a JavaScript-enabled browser, the page produces the following output.

Figure 4-2. Example running (click open/close blind to run effect)

Clicking on the open/close blind link fires the Scriptaculous Blind effect. Congratulations! You've just written your first Scriptaculous effect.


Section 4.1. Getting Started

Using Scriptaculous > Getting Started

Chapter 4. Using Scriptaculous

    Section 4.1. Getting Started

    Section 4.2. Visual Effects

    Section 4.3. Toggling Effects

    Section 4.4. Controls

    Section 4.5. AutoCompletion

    Section 4.6. Drag-and-Drop

    Section 4.7. Putting Everything Together

4.1. Getting Started

The Scriptaculous distribution is available from http://script.aculo.us/downloads.

Figure 4-1. Scriptaculous downloads page

The file scriptaculous-js-x.x.x.zip (at the time of writing: scriptaculous-js-1.6.2.zip) should be saved and unpacked to a convenient location.

The distribution contains a lib directory containing the file prototype.js and a src directory containing the following Scriptaculous files:

  • scriptaculous.js

  • builder.js

  • effects.js

  • dragdrop.js

  • controls.js

  • slider.js

  • unittest.js

These files (including prototype.js) should be copied to a convenient location (the file unittest,js is optional).

NOTE

The version of Prototype may differ from the version of Prototype you already have. If this is the case, the later version of Prototype should be used. At the time of writing, Scriptaculous 1.6.2 uses Prototype-1.5.1rc0, while the latest released version of Prototype is 1.4.0. In this case, if we want to use Scriptaculous, we should use prototype-1.5.1rc0 as prototype.js throughout.

Using Scriptaculous involves making the script in prototype.js and scriptaculous.js visible to your own JavaScript. This is usually done via the script tag, specifying the URLs of prototype.js and scriptaculous.js in that order.

<script src=prototypeURL content="text/javascript"></script>
<script src=scriptaculousURL content="text/javascript"></script>

The following example assumes that:

  • scriptaculous.js

  • builder.js

  • effects.js

  • dragdrop.js

  • controls.js

  • slider.js

have been placed in a js directory and that the HTML file is alongside the directory.

            C:\javascriptBook>dir /s /b
C:\javascriptBook\js
C:\javascriptBook\referencingScriptaculous.html
C:\javascriptBook\js\builder.js
C:\javascriptBook\js\controls.js
C:\javascriptBook\js\dragdrop.js
C:\javascriptBook\js\effects.js
C:\javascriptBook\js\prototype.js
C:\javascriptBook\js\scriptaculous.js
C:\javascriptBook\js\slider.js

It shows a sample HTML file that uses Scriptaculous and may be used as a simple sanity check.

Example 4-1. referencingScriptaculous.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Using Scriptaculous</title>
    <script content="text/javascript" src="js/prototype.js" ></script>
    <script content="text/javascript" src="js/scriptaculous.js"></script>
</head>
<body>
    <a href="javascript:void Effect.toggle('d1',blind');">
open/close blind</a>
<div id="d1" style="background-color:green;height:300px;width:200px"></div>
</body>
</html>

If you are using a JavaScript as your only scripting language, you may alternatively set this up using the defaulting mechanism of HTML 4:

Example 4-2. referencingScriptaculous2.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
<meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>
</head>
<body>
    <a href="javascript:void Effect.toggle('d1',blind');">
open/close blind</a>
<div id="d1" style="background-color:green;height:300px;width:200px"></div>
</body>
</html>

When loaded into a JavaScript-enabled browser, the page produces the following output.

Figure 4-2. Example running (click open/close blind to run effect)

Clicking on the open/close blind link fires the Scriptaculous Blind effect. Congratulations! You've just written your first Scriptaculous effect.


Section 4.2. Visual Effects

Using Scriptaculous > Visual Effects

4.2. Visual Effects

The Scriptaculous Visual effects library consists of five core effects:

  • Effect.Highlight

  • Effect.MoveBy

  • Effect.Opacity

  • Effect.Parallel

  • Effect.Scale

Each of these effects can be called via a constructor, passing in an element id, any mandatory parameters, and, finally, options:

new Effect.Highlight('id'[,options]);
new Effect.MoveBy('id',toTop,toLeft,[,options]);
new Effect.Opacity('id'[,options]);
new Effect.Parallel('id'[,options]);
new Effect.Scale('id',percent,[,options]);

The Effect options object is a class with known properties.

Table 4-1. Scriptaculous properties
Property | Type | Values | Description
duration | Number | Number > 0 | Duration of effect in seconds
delay | Number | Number > 0 | Delay before starting effect in seconds
from | Number | In range [0..1.0] | Amount of effect to start from
to | Number | In range [0..1.0] | Amount of effect to end at
transition | Function(number) -> number
queue | String

The fact that there are only five effects might seem a bit strange until you realize that these effects can be composed to make combination effects. A combination effect is a composition of one or more core effects, and although there are a number of packaged combination effects, these are really code examples showing how to write your own.

That aside, the packaged combination effects include:

  • Effect.Appear

  • Effect.Fade

  • Effect.Puff

  • Effect.DropOut

  • Effect.Shake

  • Effect.Highlight

  • Effect.SwitchOff

  • Effect.BlindDown

  • Effect.BlindUp

  • Effect.SlideDown

  • Effect.SlideUp

  • Effect.Pulsate

  • Effect.Squish

  • Effect.Fold

  • Effect.Grow

  • Effect.Shrink

and maybe called via:

Effect.methodName('id'[,options]);

So making an element with id el1 appear over a duration of two sections would be written as:

Effect.Appear('el1',{duration:2});


Section 4.3. Toggling Effects

Using Scriptaculous > Toggling Effects

4.3. Toggling Effects

Scriptaculous offers a neat utility function, Effect.toggle, which allows elements to be shown or hidden using different animations. If an element is hidden, it shows it, and if it is visible, then it hides it.

Effect.toggle('id'[,effectType = 'appear');

property | type | values | description
effectType | string | 'appear' | toggle between Effect.Appear and Effect.Fade
 |  | 'blind' | toggle between Effect.BlindUp and Effect.BlindDown
 |  | 'slide' | toggle between Effect.SlideUp and Effect.SlideDown

We may user the methods above to create an activity indicator. We first create a div tag, representing that activity is occurring:

<div id='activity' style='display:none'><img src="activity.gif"></div>

We may activate this using Appear:

Effect.Appear('activity',{duration:0.5,queue:'end'};

And deactivate this using Fade:

Effect.Fade('activity',{duration:0.5,queue:'end'};

Example 4-3. activity.html

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
       <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>
    <script>

       function start()
       {
              $('activity').hide();
              Effect.Appear('activity',{duration:0.5,queue:'end'});
              showInfo();
       }
       function stop()
       {
              Effect.Fade('activity',{duration:0.5,queue:'end'});
       }
    </script>
</head>
<body>
       <div id='activity' style="display:none; position:absolute; left: 100px;
top:50px"><img src="activity.gif"></div>
       <a href="javascript:void start();">
start activity</a>
<a href="javascript:void stop();">
end activity</a>
</body>
</html>

Where activity.gif is an animated gif activity indicator, such as those found at http://mentalized.net/activity-indicators/.

We can also use these methods to create information boxes that roll down and up over time by using a div element

Example 4-4. activityWithRollDown.html

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
       <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Activity with info</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>
    <script>

       function showInfo()
       {
              $('info').hide();
              Effect.BlindDown('info',{duration:0.5,queue:'end'});
              new Effect.Highlight('info',{duration:2,queue:'end'});
              Effect.BlindUp('info',{duration:0.5,queue:'end'});
       }
       function start()
       {
              $('activity').hide();
              Effect.Appear('activity',{duration:0.5,queue:'end'});
              showInfo();
       }
       function stop()
       {
              Effect.Fade('activity',{duration:0.5,queue:'end'});
       }
    </script>
</head>
<body>
       <div id='activity' style="display:none; position:absolute; left: 100px;
top:50px"><img src="activity.gif"></div>
       <div id='info' style="display:none; position:absolute; left: 120px; top:50px;
border: 1px solid black"><P>click on end activity to stop</P></div>
       <a href="javascript:void start();">
start activity</a>
<a href="javascript:void stop();">
end activity</a>
</body>
</html>

Figure 4-3. Running activity with rolldown.html


Section 4.4. Controls

Using Scriptaculous > Controls

4.4. Controls

Alongside effects, Scriptaculous defines a set of controls. Among the most useful are Autocompletions and drag-and-drop.


Section 4.5. AutoCompletion

Using Scriptaculous > AutoCompletion

4.5. AutoCompletion

Creating an auto-completing text box in Scriptaculous works as follows. First, create a input field and a div to hold the option set:

Code View: Scroll / Show All
<input  id="input_name" name="autocomplete_param" size="30" type="text" value="" />
<div class="auto_complete" id="input_name_auto_complete">

We then create an autocompleter object, which references this:

Code View: Scroll / Show All
new Ajax.Autocompleter('input_name', 'input_name_auto_complete', 'options.html', {})

Rather than reference a web service, we create a file options.html containing:

<ul>
    <li>option1</li>
    <li>option2</li>
    <li>option3</li>
    <li>option4</li>
    <li>option5</li>
    <li>option6</li>
</ul>

Finally, we style the retuned list to look like a combo:

Code View: Scroll / Show All
<style>   div.auto_complete {
            width: 350px;
            background: #fff;
          }
          div.auto_complete ul {
            border:1px solid #888;
            margin:0;
            padding:0;
            width:100%;
            list-style-type:none;
          }
          div.auto_complete ul li {
            margin:0;
            padding:3px;
          }
          div.auto_complete ul li.selected {
            background-color: #ffb;
          }
          div.auto_complete ul strong.highlight {
            color: #800;
            margin:0;
            padding:0;
          }
  </style>

Example 4-5. autocomplete.html

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>

</head>
<body>
<p> Autocomplete </p>
<style>          div.auto_complete {
            width: 350px;
            background: #fff;
          }
          div.auto_complete ul {
            border:1px solid #888;
            margin:0;
            padding:0;
            width:100%;
            list-style-type:none;
          }
          div.auto_complete ul li {
            margin:0;
            padding:3px;
          }
          div.auto_complete ul li.selected {
            background-color: #ffb;
          }
          div.auto_complete ul strong.highlight {
            color: #800;
            margin:0;
            padding:0;
          }
  </style><input  id="input_name" name="autocomplete_parm" size="30" type="text"
value="" />
  <div class="auto_complete" id="input_name_auto_complete"></div><script
type="text/javascript">new Ajax.Autocompleter('input_name',
'input_name_auto_complete',
'options.html', {})</script>
</body>
</html>

As this is a static page, it does not respond dynamically to the data typed in. A server version of this would obviously take advantage of the submitted value of autocomplete_param to generate appropriate results returned as an unordered list.

Figure 4-4. Running autocomplete.html


Section 4.6. Drag-and-Drop

Using Scriptaculous > Drag-and-Drop

4.6. Drag-and-Drop

In Scriptaculous, drag-and-drop is accomplished by adding draggable objects and adding droppable objects in Scriptaculous' droppables list.

Creating a draggable object is achieved by calling the Draggable object's constructor, passing in the document id of the element we want to drag.

new Draggable(obj.id,{revert:true});

Creating a Droppable object is achieved by adding the document id of the droppable object to the Scriptaculous Droppables list.

              Droppables.add(obj.id,
              {
                     accept: 'cdragTarget', // css class to accept
                     onDrop: function(dragTarget)      { // action }
              }
              );

The following example displays a list of countries and allows one country to be dropped on the next, showing an alert when this happens.

Example 4-6. dragDrop.html

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Using Scriptaculous</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>

</head>
<body>
<P> Drag and drop countries </P>
<div id="US" class="country cdropTarget cdragTarget"><P>US</P></div>
<div id="UK" class="country cdropTarget cdragTarget"><P>UK</P></div>
<div id="france" class="country cdropTarget cdragTarget"><P>France</P></div>
<div id="germany" class="country cdropTarget cdragTarget"><P>Germany</P></div>

<script type="text/javascript">
       var countries = document.getElementsByClassName('country');

       function message(dragTarget,dropTarget)
       {
              var from = dragTarget.id;
              var to   = dropTarget.id;
              alert(from + ' dropped on to ' + to);
       }

       countries.each(function(obj,at)
       {
              new Draggable(obj.id,{revert:true});
              Droppables.add(obj.id,
              {
                           accept: 'cdragTarget',
                     onDrop: function(dragTarget)
                     { message(dragTarget,obj);}
              }
              );
       });

</script>
</body>
</html>

Figure 4-5. Running drag-drop.html


Section 4.7. Putting Everything Together

Using Scriptaculous > Putting Everything Together

4.7. Putting Everything Together

For a more realistic example, we combine the web service accessed earlier with Scriptaculous drag-and-drop and effects.

Code View: Scroll / Show All
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript"/>
    <title>Ajax exchange rates</title>
    <script src="js/prototype.js" ></script>
    <script src="js/scriptaculous.js"></script>

</head>
<body>
<P> Drag and drop countries to get exchange rates</P>
<div id="US" class="country cdropTarget cdragTarget"><P>US</P></div>
<div id="UK" class="country cdropTarget cdragTarget"><P>UK</P></div>
<div id="france" class="country cdropTarget cdragTarget"><P>France</P></div>
<div id="germany" class="country cdropTarget cdragTarget"><P>Germany</P></div>

<script type="text/javascript">

var SOAP_URL = "http://services.xmethods.net:80/soap";
var SOAP_TEMPLATE = '<?xml version="1.0" encoding="UTF-8"?>'+
 '<soap:Envelope xmlns:mrns0="urn:xmethods-CurrencyExchange" '+
 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" '+
 'xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" '+
 'xmlns:xs="http://www.w3.org/2001/XMLSchema" '+
 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+
 '<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'+
 '<mrns0:getRate>'+
 '<country1 xsi:type="xs:string">_FROM_</country1>'+
 '<country2 xsi:type="xs:string">_TO_</country2>'+
 '</mrns0:getRate>'+
 '</soap:Body>'+
 '</soap:Envelope>';

function callbackComplete(from,to,request) {
  if (window.netscape)
       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

  var rate =
  request.responseXML.getElementsByTagName('Result')[0].firstChild.nodeValue;
       showRate(from,to,rate);
}

function showInfo() {
       $('info').hide();
       $('result').hide();
       Effect.BlindDown('info',{duration:0.5,queue:'end'});
       new Effect.Highlight('info',{duration:2,queue:'end'});
       Effect.BlindUp('info',{duration:0.5,queue:'end'});
}
function start() {
       $('activity').hide();
       Effect.Appear('activity',{duration:0.5,queue:'end'});
       showInfo();
}
function stop() {
       Effect.Fade('activity',{duration:0.5,queue:'end'});
}

function showRate(from,to,rate) {
       $('result').hide();
       $('info').hide();
       $('result').innerHTML = 'the rate from '+from+' to '+to+' is currently '+rate;
       Effect.BlindDown('result',{duration:0.5,queue:'end'});
       new Effect.Highlight('result',{duration:2,queue:'end'});
}
Ajax.Responders.register(  {
              onCreate: start,
              onComplete: function() {
                     if(Ajax.activeRequestCount == 0){stop();}}});

function getExchangeRate(dragTarget,dropTarget)
{
       var from = dragTarget.id;
       var to   = dropTarget.id;
       if (window.netscape)
       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

       var soapRequest = SOAP_TEMPLATE.replace(/_FROM_/,from).replace(/_TO_/,to);
       var url = SOAP_URL;
       var ajaxRequest = new Ajax.Request(url,
       { method: 'post',
              requestHeaders : [
              'Content-Type' , 'text/xml; charset="utf-8"',
                     'SOAPAction',     '""'
              ],
              postBody:soapRequest,
              onComplete : function(req) {callbackComplete(from,to,req);}

       });
}

var countries = document.getElementsByClassName('country');
countries.each(function(obj,at)
{
       new Draggable(obj.id,{revert:true});
       Droppables.add(obj.id,
       {
              accept: 'cdragTarget',
              onDrop: function(dragTarget) { getExchangeRate(dragTarget,obj);}
       }
       );
});

</script>
<div id='activity' style="display:none; position:absolute; left: 100px;
top:50px"><img src="activity.gif"></div>
<div id='info' style="display:none; position:absolute; left: 120px; top:50px; border:
1px solid black"><P>Getting exchange rate</P></div>
<div id='result' style="display:none; position:absolute; left: 120px; top:50px;
border: 1px solid black"></div>
</body>
</html>

Figure 4-6. Running drag-and-drop Ajax example

4.7.1. Walkthrough

We begin by defining a set of countries as a set if div elements.

Code View: Scroll / Show All
<P> Drag and drop countries to get exchange rates</P>
<div id="US" class="country cdropTarget cdragTarget"><P>US</P></div>
<div id="UK" class="country cdropTarget cdragTarget"><P>UK</P></div>
<div id="france" class="country cdropTarget cdragTarget"><P>France</P></div>
<div id="germany" class="country cdropTarget cdragTarget"><P>Germany</P></div>

These are given three classes, - country, cdropTarget, and cdragTarget ,- denoting that each is a valid country, a target for dropping, and a target for dragging. We then make them draggable and droppable as follows:

Code View: Scroll / Show All
var countries = document.getElementsByClassName('country');
countries.each(function(obj,at)
{
       new Draggable(obj.id,{revert:true});
       Droppables.add(obj.id,
       {
              accept: 'cdragTarget',
              onDrop: function(dragTarget) { getExchangeRate(dragTarget,obj);}
       }
       );
});

The above code finds all elements of class country (i.e., all countries) and iterates through them using the array as an enumeration and calling each. For each object obj, we make this object draggable via:

       new Draggable(obj.id,{revert:true});

And tell it that after it has been dragged, it should revert to its original position.

We also make each element droppable and tell it that it should accept drops from targets having a class of cdragTarget, and on a drop it should run the passed handler function.

Code View: Scroll / Show All
Droppables.add(obj.id,
       {
              accept: 'cdragTarget',
              onDrop: function(dragTarget) { getExchangeRate(dragTarget,obj);}
       }
       );

The handler function calls getExchangeRate, passing in the drag-and-drop targets.

Code View: Scroll / Show All
function getExchangeRate(dragTarget,dropTarget)
{
       var from = dragTarget.id;
       var to   = dropTarget.id;
       if (window.netscape)
       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

       var soapRequest = SOAP_TEMPLATE.replace(/_FROM_/,from).replace(/_TO_/,to);
       var url = SOAP_URL;
       var ajaxRequest = new Ajax.Request(url,
       { method: 'post',
              requestHeaders : [
              'Content-Type' , 'text/xml; charset="utf-8"',
                     'SOAPAction',     '""'
              ],
              postBody:soapRequest,
              onComplete : function(req) {callbackComplete(from,to,req);}

       });
}

This collects the ids (names of countries) and makes an Ajax call to get the rate.

When the Ajax call is done, it calls callbackComplete:

Code View: Scroll / Show All
function callbackComplete(from,to,request) {
  if (window.netscape)
       netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
  var rate =
  request.responseXML.getElementsByTagName('Result')[0].firstChild.nodeValue;
       showRate(from,to,rate);
}

which collects the rate:

var rate =
request.responseXML.getElementsByTagName('Result')[0].firstChild.nodeValue;

and shows it via:

       showRate(from,to,rate);

The function showRate initially hides the div elements it will use to display the rates and then updates the content of the div with id 'result'. Following this, it runs a couple of Scriptaculous effects, which make the result appear as blind-rolldown for 0.5 seconds, and then make it highlighted for 2 seconds.

Code View: Scroll / Show All
function showRate(from,to,rate) {
       $('result').hide();
       $('info').hide();
       $('result').innerHTML = 'the rate from '+from+' to '+to+' is currently '+rate;
       Effect.BlindDown('result',{duration:0.5,queue:'end'});
       new Effect.Highlight('result',{duration:2,queue:'end'});
}

This completes the example, apart from the fact that there is also an activity indicator around the Ajax call:

function showInfo() {
       $('info').hide();
       $('result').hide();
       Effect.BlindDown('info',{duration:0.5,queue:'end'});
       new Effect.Highlight('info',{duration:2,queue:'end'});
       Effect.BlindUp('info',{duration:0.5,queue:'end'});
}
function start() {
       $('activity').hide();
       Effect.Appear('activity',{duration:0.5,queue:'end'});
       showInfo();
}
function stop() {
       Effect.Fade('activity',{duration:0.5,queue:'end'});
}

Ajax.Responders.register(  {
              onCreate: start,
              onComplete: function() {
                     if(Ajax.activeRequestCount == 0){stop();}}});

This causes the activity icon to appear and an info box to drop down, be highlighted, and then roll up when the HTTP call is made; and the activity icon fades when the call is complete.


Chapter 5. Prototype and Scriptaculous Members

This section is a quick member reference. For a more in-depth Prototype references, refer to http://www.sergiopereira.com/articles/prototype.js.html.

5.1. Conventions Used

Since JavaScript is a largely untyped language, it has no syntax for specifying the type of its identifiers. Since Prototype has many aspects that are functional in nature, we will use the following ad hoc syntax to denote types.

A type declaration is a qualified name followed by a type:

Code View: Scroll / Show All
            <type-decl> ::= <name>::<type>                  // underlining denotes static
member

Where a type is one of the following:

<type> ::= number                               // a primitive number
         | string                               // a primitive string
         | boolean                              // a primitive boolean
         | undefined                            // undefined (void)
         | Function()               -> <type>   // a function taking no arguments
         | Function(
            <arg>(,
            <arg>)*) -> <type>   // a function taking
N arguments
         | Constructor()                        // a constructor taking no arguments
         | Constructor(
            <arg>
            (,
            <arg>)*)          // a constructor taking
N arguments
         | (
            <type>
            )                             // a bracketed type for clarity
         | any                                  // a wild card
         | <class-name>[of <type>]              // a class e.g. Array

<arg> ::= [<name>
            ::]<type> | (
            <arg>
            )            // a named type or
bracketed argument


Section 5.1. Conventions Used

Prototype and Scriptaculous Members > Conventions Used

Chapter 5. Prototype and Scriptaculous Members

This section is a quick member reference. For a more in-depth Prototype references, refer to http://www.sergiopereira.com/articles/prototype.js.html.

5.1. Conventions Used

Since JavaScript is a largely untyped language, it has no syntax for specifying the type of its identifiers. Since Prototype has many aspects that are functional in nature, we will use the following ad hoc syntax to denote types.

A type declaration is a qualified name followed by a type:

Code View: Scroll / Show All
            <type-decl> ::= <name>::<type>                  // underlining denotes static
member

Where a type is one of the following:

<type> ::= number                               // a primitive number
         | string                               // a primitive string
         | boolean                              // a primitive boolean
         | undefined                            // undefined (void)
         | Function()               -> <type>   // a function taking no arguments
         | Function(
            <arg>(,
            <arg>)*) -> <type>   // a function taking
N arguments
         | Constructor()                        // a constructor taking no arguments
         | Constructor(
            <arg>
            (,
            <arg>)*)          // a constructor taking
N arguments
         | (
            <type>
            )                             // a bracketed type for clarity
         | any                                  // a wild card
         | <class-name>[of <type>]              // a class e.g. Array

<arg> ::= [<name>
            ::]<type> | (
            <arg>
            )            // a named type or
bracketed argument


Section 5.2. Ajax members (Prototype)

Prototype and Scriptaculous Members > Ajax members (Prototype)

5.2. Ajax members (Prototype)

Member Type
activeRequestCount

number

getTransport

Function() -> XMLHttpRequest


Section 5.3. Ajax.Base members (Prototype)

Prototype and Scriptaculous Members > Ajax.Base members (Prototype)

5.3. Ajax.Base members (Prototype)

Member Type
setOptions

Function(Ajax options) -> undefined

responseIsSuccess

Function() -> boolean

reponseIsFailure

Function() -> boolean


Section 5.4. Ajax options members (Prototype)

Prototype and Scriptaculous Members > Ajax options members (Prototype)

5.4. Ajax options members (Prototype)

Member Type
method

String='post'

parameters

String=''

aynchronous

Boolean=true

postBody

String

requestHeaders

Array

onComplete

Function(request::XMLHttpRequest,header::Object} -> undefined

onLoaded

Function(request::XMLHttpRequest,header::Object} -> undefined

onLoading

Function(request::XMLHttpRequest,header::Object} -> undefined

onInteractive

Function(request::XMLHttpRequest,header::Object} -> undefined

onUninitialized

Function(request::XMLHttpRequest,header::Object} -> undefined

onSuccess

Function(request::XMLHttpRequest,header::Object} -> undefined

onFailure

Function(request::XMLHttpRequest,header::Object} -> undefined

onException

Function(request::XMLHttpRequest,exception::Object} -> undefined

insertion

Insertion

evalScripts

Boolean=false

decay

Number=1


Section 5.5. Ajax.PeriodicalUpdater members (Prototype)

Prototype and Scriptaculous Members > Ajax.PeriodicalUpdater members (Prototype)

5.5. Ajax.PeriodicalUpdater members (Prototype)

extends Prototype::Ajax.Base

Member Type
Ajax.PeriodicalUpdater

Constructor(container::Object,url::string,Ajax options)

Container

object

url

string

Frequency

number

Decay

number

Stop

Function() -> undefined


Section 5.6. Ajax.Request members (Prototype)

Prototype and Scriptaculous Members > Ajax.Request members (Prototype)

5.6. Ajax.Request members (Prototype)

extends Prototype::Ajax.Base

Member Type
Ajax.Request

Constructor(url::string,ajaxOptions::Object)

Events

Array

transport

XMLHttpRequest

url

String

header

Function(headerName::string) -> string


Section 5.7. Ajax.Responders members (Prototype)

Prototype and Scriptaculous Members > Ajax.Responders members (Prototype)

5.7. Ajax.Responders members (Prototype)

extends Prototype::Enumerable

Member Type
responders

Array

register

Function(responder::object) -> undefined

unregister

Function(responder::object) -> undefined

dispatch

Function(callback::string,Object,json::Object)-> undefined


Section 5.8. Ajax.Updater members (Prototype)

Prototype and Scriptaculous Members > Ajax.Updater members (Prototype)

5.8. Ajax.Updater members (Prototype)

extends Prototype::Ajax.Request

Member Type
Ajax.Updater

Constructor(container::string,url::string,ajaxOptions::Object)
Constructor(container::Element,url::string,ajaxOptions::Object)
Constructor(successFailure::Object,url::string,ajaxOptions::Object)


Section 5.9. Array members (Prototype)

Prototype and Scriptaculous Members > Array members (Prototype)

5.9. Array members (Prototype)

extends JavaScript::Array
extends Prototype::Enumerable

Member Type
clear

Function() -> Array

compact

Function() -> Array

first

Function() -> any

flatten

Function() -> Array

indexOf

Function(valueToFind::any) -> number

inspect

Function() -> string

last

Function() -> any

reverse

Function(revSelf::boolean=true) -> Array

without

Function(exclude0::any[,exclude1::any[,...,exclude::any]]) -> Array


Section 5.10. Autocompleter members (Scriptaculous)

Prototype and Scriptaculous Members > Autocompleter members (Scriptaculous)

5.10. Autocompleter members (Scriptaculous)

Member Type
Autocompleter

Code View: Scroll / Show All
Constructor(inputId::string,divToUpdate::string,url::string,options:: Ajax Options);


Section 5.11. Class members (Prototype)

Prototype and Scriptaculous Members > Class members (Prototype)

5.11. Class members (Prototype)

Member Type
                           create

Function([a0::any,..,an::any)]) -> Object


Section 5.12. Document members (Prototype)

Prototype and Scriptaculous Members > Document members (Prototype)

5.12. Document members (Prototype)

extends JavaScript::document

Member Type
getElementsByClassName

Function(className::string[,parentId::string]) -> Array
Function(className::string[,parent::Object])   -> Array


Section 5.13. Draggable members (Scriptaculous)

Prototype and Scriptaculous Members > Draggable members (Scriptaculous)

5.13. Draggable members (Scriptaculous)

Member Type
Draggable

Constructor(id::String,options::Object);


Section 5.14. Draggables members (Scriptaculous)

Prototype and Scriptaculous Members > Draggables members (Scriptaculous)

5.14. Draggables members (Scriptaculous)

Member Type
register

Function(draggable::Draggable) -> undefined

unregister

Function(draggable::Draggable) -> undefined

activate

Function(draggable::Draggable) -> undefined

deactivate

Function() -> undefined

updateDrag

Function(Event) -> undefined

endDrag

Function(Event) -> undefined

keyPress

Function(Event) -> undefined

addObserver

Function(Object)-> undefined

removeObserver

Function(Object)-> undefined

notify

Function(eventName::string,Draggable,Evenet) -> undefined


Section 5.15. Droppables members (Scriptaculous)

Prototype and Scriptaculous Members > Droppables members (Scriptaculous)

5.15. Droppables members (Scriptaculous)

Member Type
add

Function(Object) -> undefined

remove

Function(Object[,options::Object]) -> undefined


Section 5.16. Effect members (Scriptaculous)

Prototype and Scriptaculous Members > Effect members (Scriptaculous)

5.16. Effect members (Scriptaculous)

Member Type
                           Appear

Function(element::id or Object[,options::Object]) -> Object

                           Fade

Function(element::id or Object[,options::Object]) -> Object

                           Puff

Function(element::id or Object[,options::Object]) -> Object

                           DropOut

Function(element::id or Object[,options::Object]) -> Object

                           Shake

Function(element::id or Object) -> Object

                           Highlight

Function(element::id or Object[,options::Object]) -> Object

                           SwitchOff

Function(element::id or Object) -> Object

                           BlindDown

Function(element::id or Object[,options::Object]) -> Object

                           BlindUp

Function(element::id or Object[,options::Object]) -> Object

                           SlideDown

Function(element::id or Object[,options::Object]) -> Object

                           SlideUp

Function(element::id or Object[,options::Object]) -> Object

                           Pulsate

Function(element::id or Object[,options::Object]) -> Object

                           Squish

Function(element::id or Object[,options::Object]) -> Object

                           Fold

Function(element::id or Object[,options::Object]) -> Object

                           Grow

Function(element::id or Object[,options::Object]) -> Object

                           Shrink

Function(element::id or Object[,options::Object]) -> Object


Section 5.17. Effect.Highlight members (Scriptaculous)

Prototype and Scriptaculous Members > Effect.Highlight members (Scriptaculous)

5.17. Effect.Highlight members (Scriptaculous)

Member Type
Effect.Hightlight

Constructor(id::String[,options::Effect options])


Section 5.18. Effect.MoveBy members (Scriptaculous)

Prototype and Scriptaculous Members > Effect.MoveBy members (Scriptaculous)

5.18. Effect.MoveBy members (Scriptaculous)

Member Type
Effect.MoveBy

Code View: Scroll / Show All
Constructor(id::String,toTop::number,toLeft::number,[,options::Effect options])


Section 5.19. Effect.Opacity members (Scriptaculous)

Prototype and Scriptaculous Members > Effect.Opacity members (Scriptaculous)

5.19. Effect.Opacity members (Scriptaculous)

Member Type
Effect.Opacity

Constructor(id::String[,options::Effect options]);


Section 5.20. Effect options members (Scriptaculous)

Prototype and Scriptaculous Members > Effect options members (Scriptaculous)

5.20. Effect options members (Scriptaculous)

Member Type
duration

number

delay

number

from

number

to

number

transition

Function(number)->number

queue

string ('parallel' or 'front' or 'end')


Section 5.21. Effect.Parallel members (Scriptaculous)

Prototype and Scriptaculous Members > Effect.Parallel members (Scriptaculous)

5.21. Effect.Parallel members (Scriptaculous)

Member Type
Effect.Parallel

Constructor(id::String[,options::Effect options]);


Section 5.22. Effect.Scale members (Scriptaculous)

Prototype and Scriptaculous Members > Effect.Scale members (Scriptaculous)

5.22. Effect.Scale members (Scriptaculous)

Member Type
Effect.Scale

Constructor(id::String,percent::number[,options::Effect options]);


Section 5.23. Element members (Prototype)

Prototype and Scriptaculous Members > Element members (Prototype)

5.23. Element members (Prototype)

Member Type
                           addClassName

Function(Element or id::string,className::string) -> undefined

                           classNames

Function(Element or id::string)    -> Element.ClassNames

                           cleanWhitespace

Function(Element or id::string) -> undefined

                           getDimensions

Function(Element or id::string) -> Object

                           getHeight

Function(Element or id::string) -> number

                           getStyle

Function(Element or id::string,cssPropertyName::string) -> string

                           hasClassName

Function(Element or id::string,className::string) -> Boolean

                           hide

Function(Element or id::string,...,Element or id::string) -> undefined

                           makeClipping

Function(Element or id::string) -> undefined

                           makePositioned

Function(Element or id::string) -> undefined

                           remove

Function(Element or id::string) -> undefined

                           removeClassName

Function(Element or id::string,className::string) -> undefined

                           scrollTo

Function(Element or id::string) -> undefined

                           setStyle

Function(Element or id::string,cssProperties::Hash) -> string

                           show

Function(Element or id::string,...,Element or id::string) -> undefined

                           toggle

Function(Element or id::string,...,Element or id::string) -> undefined

                           undoClipping

Function(Element or id::string) -> undefined

                           update

Function(Element or id::string,html::string) -> undefined

                           visible

Function(Element or id::string) -> boolean


Section 5.24. Element.ClassNames (Prototype)

Prototype and Scriptaculous Members > Element.ClassNames (Prototype)

5.24. Element.ClassNames (Prototype)

extends Prototype::Enumerable

Member Type
Element.ClassNames

Constructor(Element or id::string)

add

Function(className:string) -> undefined

remove

Function(className:string) -> undefined

set

Function(className:string) -> undefined


Section 5.25. Enumerable members (Prototype)

Prototype and Scriptaculous Members > Enumerable members (Prototype)

5.25. Enumerable members (Prototype)

Member Type
each

Function(Function(val::Object,at::number)->undefined)->undefined

all

Function([Function(val::Object,at::number)->Boolean])->boolean

any

Function([Function(val::Object,at::number)->Boolean])->boolean

collect

Function(Function(val::Object,at::number)->any)->Array

detect

Function([Function(val::Object,at::number)->Boolean])->any

entries

Function() -> Array

find

Function([Function(val::Object,at::number)->Boolean])->any

findAll

Function([Function(val::Object,at::number)->Boolean])->Array

grep

Function(RegExp,Function(val::Object,at::number)->any)->Array

include

Function(objectToFind::Object) -> boolean

inject

Function(unit::Object,
             Function(accum::Object,val::Object,index::number)-> any)
         -> any

invoke

Function(method::string,[,arg0::any,...,argN::any]) -> Array

map

Function(Function(val::Object,at::number)->any)->Array

max

Function([fn:Function(val::Object,at::number)->number])->any

member

Function(objectToFind::Object) -> boolean

min

Function([Function(val::Object,at::number)->number])->any

partition

Function(Function(val::Object,at::number)->boolean)->Array of Array

pluck

Function(property::string) -> Array

reject

Function(Function(val::Object,at::number)->Boolean)->Array

select

Function(Function(val::Object,at::number)->Boolean)->Array

sortBy

Function(Function(val::Object,at::number)->any)->Array

toArray

Function() -> Array

zip

Function(e0::Enumerable,..,eN::Enumerable[,Function(Array->any)]->Array


Section 5.26. Event members (Prototype)

Prototype and Scriptaculous Members > Event members (Prototype)

5.26. Event members (Prototype)

Extends JavaScript::Event

Member Type
                           KEY_BACKSPACE

number

                           KEY_TAB

number

                           KEY_RETURN

number

                           KEY_ESC

number

                           KEY_LEFT

number

                           KEY_UP

number

                           KEY_RIGHT

number

                           KEY_DOWN

number

                           KEY_DELETE

number

                           element

Function(Event) -> Element

                           isLeftClick

Function(Event) -> Boolean

                           pointerX

Function(Event) -> number

                           pointerY

Function(Event) -> number

                           stop

Function(Event) -> undefined

                           findElement

Function(Event,tagName::string) -> Element

                           observe

Function(Object,evt::string,Function,capture::boolean) -> undefined
Function(string,evt::string,Function,capture::boolean) -> undefined

                           stopObserving

Function(Object,evt::string,Function,capture::boolean) -> undefined
Function(string,evt::string,Function,capture::boolean) -> undefined


Section 5.27. Field members (Prototype)

Prototype and Scriptaculous Members > Field members (Prototype)

5.27. Field members (Prototype)

Member Type
clear

Function(Object or string,...) -> undefined

present

Function(Object or string,...) -> boolean

focus

Function(Object or string) -> undefined

select

Function(Object or string) -> undefined

activate

Function(Object or string) -> undefined


Section 5.28. Form members (Prototype)

Prototype and Scriptaculous Members > Form members (Prototype)

5.28. Form members (Prototype)

Member Type
serialize

Function(form::Object) -> string

findFirstElement

Function(form::Object) -> Object

getElements

Function(form::Object) -> Array

getInputs

Function(form::Object [,type::string[,name::string]]) -> Array

disable

Function(form::Object) -> undefined

enable

Function(form::Object) -> undefined

focusFirstElement

Function(form::Object) -> undefined

reset

Function(form::Object) -> undefined


Section 5.29. Form.Element (Prototype)

Prototype and Scriptaculous Members > Form.Element (Prototype)

5.29. Form.Element (Prototype)

Member Type
serialize

Function(element::Object) -> string

getValue

Function() -> string


Section 5.30. Form.Element.Observer members (Prototype)

Prototype and Scriptaculous Members > Form.Element.Observer members (Prototype)

5.30. Form.Element.Observer members (Prototype)

extends Prototype::Abstract.TimedObserver

Member Type
Form.Element.Observer

Constructor(Object,frequency::number,callback::Function);


Section 5.31. Form.Element.EventObserver members (Prototype)

Prototype and Scriptaculous Members > Form.Element.EventObserver members (Prototype)

5.31. Form.Element.EventObserver members (Prototype)

extends Prototype::Abstract.EventObserver

Member Type
Form.EventObserver


Section 5.32. Form.Element.Serializers members (Prototype)

Prototype and Scriptaculous Members > Form.Element.Serializers members (Prototype)

5.32. Form.Element.Serializers members (Prototype)

Member Type
inputSelector

Function(Object) -> Array

textarea

Function(Object) -> Array

select

Function(Object) -> Array


Section 5.33. Form.Observer members (Prototype)

Prototype and Scriptaculous Members > Form.Observer members (Prototype)

5.33. Form.Observer members (Prototype)

extends Prototype::Abstract.TimedObserver

Member Type
Form.Observer

Constructor(Object,frequency::number,callback::Function);


Section 5.34. Form.EventObserver members (Prototype)

Prototype and Scriptaculous Members > Form.EventObserver members (Prototype)

5.34. Form.EventObserver members (Prototype)

extends Prototype::Abstract.EventObserver

Member Type
Form.EventObserver

Constructor(Object,callback::Function);


Section 5.35. Function members (Prototype)

Prototype and Scriptaculous Members > Function members (Prototype)

5.35. Function members (Prototype)

extends JavaScript::Function

Member Type
bind

Function(owner::Object) -> (Function(any) -> any)

bindAsEventListener

Function(owner::Object) -> (Function(event::Event) -> any)


Section 5.36. Global members (Prototype)

Prototype and Scriptaculous Members > Global members (Prototype)

5.36. Global members (Prototype)

Member Type
$

Function(string or Object) -> Element
Function(string or Object,...) -> Array

$F

Function(string or Object) -> string

$A

Function(Object) -> Array

$H

Function(Object) -> Hash

$R

Function(start::Object,end::Object,exclusive::Boolean) -> ObjectRange


Section 5.37. Hash members (Prototype)

Prototype and Scriptaculous Members > Hash members (Prototype)

5.37. Hash members (Prototype)

extends Prototype::Enumerable

Member Type
keys

Function() -> Array

values

Function() -> Array

merge

Function(other::Hash) -> Hash

toQueryString

Function() -> string

inspect

Function() -> string


Section 5.38. Insertion.After members (Prototype)

Prototype and Scriptaculous Members > Insertion.After members (Prototype)

5.38. Insertion.After members (Prototype)

extends Prototype::Abstract.Insertion

Member Type
Insertion.After

Constructor(Element or id::string,content::string)


Section 5.39. Insertion.Before members (Prototype)

Prototype and Scriptaculous Members > Insertion.Before members (Prototype)

5.39. Insertion.Before members (Prototype)

extends Prototype::Abstract.Insertion

Member Type
Insertion.Before

Constructor(Element or id::string,content::string)


Section 5.40. Insertion.Bottom (Prototype)

Prototype and Scriptaculous Members > Insertion.Bottom (Prototype)

5.40. Insertion.Bottom (Prototype)

extends Prototype::Abstract.Insertion

Member Type
Insertion.Bottom

Constructor(Element or id::string,content::string)


Section 5.41. Insertion.Top members (Prototype)

Prototype and Scriptaculous Members > Insertion.Top members (Prototype)

5.41. Insertion.Top members (Prototype)

extends Prototype::Abstract.Insertion

Member Type
Insertion.Top

Constructor(Element or id::string,content::string)


Section 5.42. Number members (Prototype)

Prototype and Scriptaculous Members > Number members (Prototype)

5.42. Number members (Prototype)

extends JavaScript::Number

Member Type
toColorPart

Function() -> number

succ

Function() -> number

times

Function(Function(number)->undefined)


Section 5.43. Object members (Prototype)

Prototype and Scriptaculous Members > Object members (Prototype)

5.43. Object members (Prototype)

extends JavaScript::Object

Member Type
                           extend

Function(extension::Object,base::Object) -> Object

                           inspect

Function(objectToPrint::Object) -> string


Section 5.44. ObjectRange members (Prototype)

Prototype and Scriptaculous Members > ObjectRange members (Prototype)

5.44. ObjectRange members (Prototype)

Member Type
ObjectRange

Constructor(start::any,end::any,exclusive::Boolean)

start

any

end

any

exclusive

Boolean

include

Function(valueToFind::any) -> boolean


Section 5.45. PeriodicalExecuter members (Prototype)

Prototype and Scriptaculous Members > PeriodicalExecuter members (Prototype)

5.45. PeriodicalExecuter members (Prototype)

Member Type
PeriodicalExecuter

Constructor(callback::Function() -> undefined,frequency::number)

callback

Function()-> undefined

frequency

number


Section 5.46. Prototype members (Prototype)

Prototype and Scriptaculous Members > Prototype members (Prototype)

5.46. Prototype members (Prototype)

Member Type
                           Version

string

                           emptyFunction

Function()    -> undefined

                           K

Function(any) -> any


Section 5.47. String members (Prototype)

Prototype and Scriptaculous Members > String members (Prototype)

5.47. String members (Prototype)

extends JavaScript::String

Member Type
stripTags

Function() -> string

stripScripts

Function() -> string

escapeHTML

Function() -> string

unescapeHTML

Function() -> string

extractScripts

Function() -> Array

evalScripts

Function() -> undefined

toQueryParms

Function() -> Array

parseQuery

Function() -> Array

toArray

Function() -> Array


Section 5.48. Try members (Prototype)

Prototype and Scriptaculous Members > Try members (Prototype)

5.48. Try members (Prototype)

Member Type
these

Function(fn1::Function()-> any,...,fnN::Function()->any)-> any