Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ajax In Action (2006).pdf
Скачиваний:
63
Добавлен:
17.08.2013
Размер:
8.36 Mб
Скачать

108CHAPTER 3

Introducing order to Ajax

callback event handlers that will be fired when the readyState of the underlying XMLHttpRequest object changes. The variable req.transport in the onComplete function is a reference to the underlying XMLHttpRequest object.

On top of Ajax.Request, Prototype further defines an Ajax.Updater type of object that fetches script fragments generated on the server and evaluates them. This follows what we describe as a “script-centric” pattern in chapter 5 and is beyond the scope of our discussion here.

This concludes our brief review of cross-browser libraries. Our choice of libraries has been somewhat arbitrary and incomplete. As we have noted, there is a lot of activity in this space at the moment, and we’ve had to limit ourselves to some of the more popular or well-established offerings. In the next section, we’ll look at some of the widget frameworks built on top of these and other libraries.

3.5.2Widgets and widget suites

The libraries that we’ve discussed so far have provided cross-browser support for some fairly low-level functionality, such as manipulating DOM elements and fetching resources from the server. With these tools at our disposal, constructing functional UIs and application logic is certainly simplified, but we still need to do a lot more work than our counterparts working with Swing, MFC, or Qt, for example.

Prebuilt widgets, and even complete widget sets for Ajax developers, are starting to emerge. In this section, we’ll look at a few of these—again, more to give a flavor of what’s out there than to provide a comprehensive overview.

Scriptaculous

The Scriptaculous libraries are UI components built on top of Prototype (see the previous section). In its current form, Scriptaculous provides two major pieces of functionality, although it is being actively developed, with several other features planned.

The Effects library defines a range of animated visual effects that can be applied to DOM elements, to make them change size, position, and transparency. Effects can be easily combined, and a number of predefined secondary effects are provided, such as Puff(), which makes an element grow larger and more transparent until it fades away completely. Another useful core effect, called Parallel(), is provided to enable simultaneous execution of multiple effects. Effects can be a useful way of quickly adding visual feedback to an Ajax user interface, as we’ll see in chapter 6.

Invoking a predetermined effect is as simple as calling its constructor, passing in the target DOM element or its ID as an argument, for example:

Third-party libraries and frameworks

109

 

 

new Effect.SlideDown(myDOMElement);

Underlying the effects is the concept of a transition object, which can be parameterized in terms of duration and event handlers to be invoked when the transition ends. Several base transition types, such as linear, sinusoidal, wobble, and pulse, are provided. Creating a custom effect is simply a matter of combining core effects and passing in suitable parameters. A detailed discussion of building custom effects is beyond the scope of this brief overview. We’ll see Scriptaculous effects in use again in chapter 6, when we develop a notifications system.

The second feature that Scriptaculous provides is a drag-and-drop library, through the Sortable class. This class takes a parent DOM element as an argument and enables drag-and-drop functionality for all its children. Options passed in to the constructor can specify callback handlers for when the item is dragged and dropped, types of child elements to be made draggable, and a list of valid drop targets (that is, elements that will accept the dragged item if the user lets go of it while mousing over them). Effect objects may also be passed in as options, to be executed when the item is first dragged, while it is in transit, and when it is dropped.

Rico

Rico, like Scriptaculous, is based on the Prototype library, and it also provides some highly customizable effects and drag-and-drop functionality. In addition, it provides a concept of a Behavior object, a piece of code that can be applied to part of a DOM tree to add interactive functionality to it. A few example Behaviors are provided, such as an Accordion widget, which nests a set of DOM elements within a given space, expanding one at a time. (This style of widget is often referred to as outlook bar, having been popularized by its use in Microsoft Outlook.)

Let’s build a simple Rico Accordion widget. Initially, we require a parent DOM element; each child of the parent will become a pane in the accordion. We define a DIV element for each panel, with two further DIVs inside that, representing the header and the body of each panel:

<div id='myAccordion'> <div>

<div>Dictionary Definition</div> <div>

<ul>

<li><b>n.</b>A portable wind instrument with a small keyboard and free metal reeds that sound when air is forced past them by pleated bellows operated by the player.</li>

<li><b>adj.</b>Having folds or bends like the bellows

110CHAPTER 3

Introducing order to Ajax

of an accordion: accordion pleats; accordion blinds.</li> </ul>

</div>

</div>

<div>

<div>A picture</div> <div>

<img src='monkey-accordion.jpg'></img> </div>

</div>

</div>

The first panel provides a dictionary definition for the word accordion and the second panel a picture of a monkey playing an accordion (see figure 3.9). Rendered as it is, this will simply display these two elements one above the other. However, we have assigned an ID attribute to the top-level DIV element, allowing us to pass a reference to it to the Accordion object, which we construct like this:

var outer=$('myAccordion'); outer.style.width='320px'; new Rico.Accordion(

outer,

{panelHeight:400,

expandedBg:'#909090',

collapsedBg:'#404040',

}

);

The first line looks rather curious. $ is actually a valid JavaScript variable name and simply refers to a function in the core Prototype library. $() resolves DOM nodes in a way similar to the x library’s xGetElementById() function that we discussed in the previous section. We pass a reference to the resolved DOM element to the Accordion object constructor, along with an array of options, in the standard idiom for Prototype-derived libraries. In this case, the options simply provide some styling of the Accordion widget’s visual elements, although callback handler functions to be triggered when panels are opened or closed can also be passed in here. Figure 3.9 shows the effect of styling the DOM elements using the Accordion object. Rico’s Behaviors provide a simple way of creating reusable widgets from common markup and also separate the content from the interactivity. We’ll explore the topic of applying good design principles to the JavaScript UI in chapter 4.

The final feature of the Rico framework to mention is that it provides very good support for Ajax-style requests to the server, through a global Rico AjaxEngine object. The AjaxEngine provides more than just a cross-browser wrapper around the XMLHttpRequest object. It defines an XML response format that

Third-party libraries and frameworks

111

 

 

Figure 3.9 The Rico framework Behaviors allow plain DOM nodes to be styled as interactive widgets, simply by passing a reference to the top-level node to the Behavior object’s constructor. In this case, the Accordion object has been applied to a set of DIV elements (left) to create an interactive menu widget (right), in which mouse clicks open and close the individual panels.

consists of a number of <response> elements. The engine will automatically decode these, and it has built-in support for two types of response: those that directly update DOM elements and those that update JavaScript objects. We’ll look at a similar mechanism in greater detail in section 5.5.3, when we discuss client/server interactions in depth. For now, let’s move on to the next type of framework: one that spans both client and server.

3.5.3Application frameworks

The frameworks that we have looked at so far are executed exclusively in the browser and can be served up as static JavaScript files from any web server. The final category of frameworks that we will review here are those that reside on the server and generate at least some of the JavaScript code or HTML markup dynamically.

These are the most complex of the frameworks that we are discussing here, and we won’t be able to discuss them in great detail but will give a brief overview of their features. We will return to the topic of server-side frameworks in chapter 5.

112CHAPTER 3

Introducing order to Ajax

DWR, JSON-RPC, and SAJAX

We’ll begin by looking at three small server-side frameworks together, because they share a common approach, although they are written for different serverside languages. SAJAX works with a variety of server-side languages, including PHP, Python, Perl, and Ruby. DWR (which stands for Direct Web Remoting) is a Java-based framework with a similar approach, exposing methods of objects rather than standalone functions. JSON-RPC (JavaScript Object Notation-based Remote Procedure Calls) is also similar in design. It offers support for server-side JavaScript, Python, Ruby, Perl, and Java.

All three allow objects defined on the server to expose their methods directly as Ajax requests. We will frequently have a server-side function that returns a useful result that has to be calculated on the server, say, because it looks up a value from a database. These frameworks provide a convenient way to access those functions or methods from the web browser and can be a good way of exposing the server-side domain model to the web browser code.

Let’s look at an example using SAJAX, exposing functions defined on the server in PHP. We’ll use a straightforward example function that simply returns a string of text, as follows:

<?php

function sayHello(name){

return("Hello! {$name} Ajax in Action!!!!");

?>

To export this function to the JavaScript tier, we simply import the SAJAX engine into our PHP and call the sajax_export function:

<?php

require('Sajax.php'); sajax_init(); sajax_export("sayHello"); ?>

When we write our dynamic web page, then, we use SAJAX to generate some JavaScript wrappers for the exported functions. The generated code creates a local JavaScript function with identical signatures to the server-side function:

<script type='text/javascript'> <?

sajax_show_javascript(); ?>

...

alert(sayHello("Dave"));

...

</script>

Third-party libraries and frameworks

113

 

 

When we call sayHello("Dave") in the browser, the generated JavaScript code will make an Ajax request to the server, execute the server-side function, and return the result in the HTTP response. The response will be parsed and the return value extracted to the JavaScript. The developer need not touch any of the Ajax technologies; everything is handled behind the scenes by the SAJAX libraries.

These three frameworks offer a fairly low-level mapping of server-side functions and objects to client-side Ajax calls. They automate what could otherwise be a tedious task, but they do present a danger of exposing too much server-side logic to the Internet. We discuss these issues in greater detail in chapter 5.

The remaining frameworks that we’ll look at in this section take a more sophisticated approach, generating entire UI layers from models declared on the server. Although they use standard Ajax technologies internally, these frameworks essentially provide their own programming model. As a result, working with these frameworks is quite different from writing generic Ajax, and we will be able to provide only a broad overview here.

Backbase

The Backbase Presentation Server provides a rich widget set that binds at runtime to XML tags embedded in the HTML documents generated by the server. The principle here is similar to the Rico behavior components, except that Backbase uses a custom set of XHTML tags to mark up the UI components, rather than standard HTML tags.

Backbase provides server-side implementations for both Java and .NET. It is a commercial product but offers a free community edition.

Echo2

NextApp’s Echo2 framework is a Java-based server engine that generates rich UI components from a model of the user interface that is declared on the server. Once launched in the browser, the widgets are fairly autonomous and will handle user interactions locally using JavaScript or otherwise send requests back to the server in batches using a request queue similar to the one employed by Rico.

Echo2 promotes itself as an Ajax-based solution that requires no knowledge of HTML, JavaScript, or CSS, unless you want to extend the set of components that are available. In most cases, the development of the client application is done using only Java. Echo2 is open source, licensed under a Mozilla-style license, allowing its use in commercial applications.