Introducing Prototype and Scriptaculous Part 2
Editor's Note: This piece picks up where the article Introducing Prototype and Scriptaculous Part 1 left off.
What is Scriptaculous?
Prototype provides an extremely solid foundation for developing complex, well-structured code, but on its own does little beyond that. The onus of developing the functionality that the end user will see still rests firmly with the developer.
Scriptaculous is a library that makes use of Prototype to deliver a rich set of high-level functionality that the developer can put to work directly in creating polished interactive user interfaces. On its own, Prototype smoothes out many of the wrinkles of Ajax development. When used with Scriptaculous, it transforms the way in which we approach the web user interface, by making features such as animation and dragging and dropping as simple as a few lines of code.
It is common when writing any computer application to wish to draw the user's attention to some part of the interface, in order to provide visual feedback. A button may wish to announce that it is clickable when the mouse moves over it. Lists of items may wish to notify the user when new items arrive or old ones vanish, particularly if it is the result of a background process. It's easy to overdo this type of functionality and end up with a user interface that distracts users or gets in their way, but such effects, if well done, can make an application more pleasant to use. In the world of web applications, in which a user may go elsewhere with a few keystrokes, making an application easy to use is imperative.
Scriptaculous makes it easy to create visual feedback of this type through its Effects library. This library is remarkable not only for the quality and range of effects that it enables, but for the high quality of the underlying design of the code, which makes it easy to compose multiple effects, run arbitrary code before, during, and after the effect, and synchronize effects with one another. Needless to say, this good design is made possible by the language features provided by Prototype.
In addition to being directly available to the coder, the Effects package is used within Scriptaculous to add visual feedback to the other main packages. Let's look at them now.
Drag and drop
Before Ajax, clicking on hyperlinks or submitting HTML forms could only initialize requests to the server. Now that requests can be fired programmatically, other types of user interaction can be used to trigger requests too, so a wider range of user interaction techniques are finding their way into web applications.
The good news is that Scriptaculous implements a feature-complete drag-and-drop system that can be applied to most types of DOM element with relatively little code. The look and feel of the interaction can be customized using the Effects library, and custom event handlers provide callbacks for all stages of the drag-and-drop event.
The features that we've discussed so far are frameworks that can be used to enhance a coder's application. Scriptaculous also provides a number of complete widgets, in the Components library. At the time of writing, the Components library contains two components: the Auto- Completer can attach a predictive drop-down element to any text field, which can endow an ordinary HTML Form element with features similar to Google Suggest; the in-place editor allows any DOM element to transform itself into a text input field and back again.
In addition to these high-level components, Scriptaculous provides a few helpers and utilities of its own. We'll conclude our initial review of the library with a look at these.
Utilities and Testing Frameworks
In addition, Scriptaculous provides a complete unit-testing framework that runs inside the browser. This is designed mainly for internal use by the Scriptaculous development team, as the entire library is well covered by tests, but it can be used as a standalone testing library too.
This concludes our initial review of the Prototype and Scriptaculous libraries. Before we look in more detail at the features of each in subsequent chapters, we'll quickly demonstrate what Prototype and Scriptaculous can do to help an ordinary Ajax application.
Applying Prototype and Scriptaculou
Introducing the Ratings example
The Ratings example is a simple widget built using Ajax and DHTML techniques that can be easily inserted into a web page to show an interactive display of the rating that the user has assigned to an item. Figure 1.1 shows the widget's visual components.
Figure 1 Ratings widget embedded in a web page. The small arrow icons are buttons allowing the user to increase or decrease the number of stars assigned to an item-in this case an article. (Icons are from the "Nuvola" icon set by David Vignoni, http://www.icon-king.com.)
Operating the widget is simple enough. The user can increase or decrease the rating by clicking on the blue arrow buttons with the mouse, and the number of stars is incremented or decremented, within the range of zero to five. When the user changes the rating, the widget also makes an asynchronous call to the server to update the central records. We won't worry for now about what the server does with that information, or what the response is.
That's our brief, then. As coders, we're more interested in getting under the hood and seeing how the implementation is done. Let's run through a few highlights of the code now. The complete code for the app is available for download from the Manning web page for this book.
Using the component
To incorporate the widget into a page, then, the designer needs to add a few lines of code in the header of the page:
That's everything that our design team needs to do to use the widget. Let's see what goes on behind the scenes, when the widget is activated.
Initializing the user interface
The constructor function for the Rating object is relatively simple, taking a note of the main arguments and then delegating to a second function updateUI(). Listing 1 shows the code for these functions.
There is quite a lot going on here, so let's pick through it piece by piece. The updateUI() method takes an optional argument delta, which we'll ignore when we initially call it in the constructor . It then proceeds to build up a set of HTML markup as a string, defining the UI that we saw in figure 1 as an HTML table. This string is then assigned to the target element using the innerHTML property .
We go on to assign event handlers to the buttons. The next line looks quite strange-we are defining a variable called rating that is a direct reference to this . The reason for this is rather arcane. We are going to create a closure when we define the event handler, and the special variable this cannot be passed in to a closure. We create rating as a copy in order to pass it in.
In the next few lines we're back on fairly safe ground. We've added unique IDs to our buttons in the big innerHTML string that we just wrote, so now we can programmatically reference the button elements .
Page 1 of 4