3.7. Summary
In this chapter, we explored Rails' Prototype helpersstarting with simple links and moving on to Ajax links and all their
In the
|
Chapter 4. Introducing script.aculo.usMost of the last chapter dealt with the Rails helpers that interact with Prototype. In this chapter, we'll shift attention to script.aculo.us, and the Rails helpers that use it. script.aculo.us provides eye-catching visual effects and transitions and powerful drag-and-drop elements.
The relationship between Prototype and script.aculo.us is close. They're both developed in concert with Rails, and they share very similar coding styles and APIs. In fact, some of what is now script.aculo.us was originally part of Prototype. Despite the close ties, the two libraries have different goals. Prototype is designed to be an extension of JavaScriptit provides features that arguably
ought
to be part of the
We'll put the examples for this chapter into a new controller, so from your Rails project directory, run the generator: script/generate controller chapter4 index
If you already created an application-wide layout (
layouts/application.
Now let's take a look at what script.aculo.us is most famous for: its visual effects. |
4.1. Visual Effects
The most popular component of script.aculo.us is its
Effect
object, which is used to attach a variety of cinematic effects to UI events. Using script.aculo.us effects, many of the slick animated transitions that people have come to associate with Flash can be accomplished without plug-ins at all, and in a way that
What about cross-platform compatibility? In general, the script.aculo.us visual effects work reliably across different browsers (Internet Explorer 6+ for Windows, Firefox, Safari, Konqeror, Camino, and, with a few exceptions, Opera). And because the animated effects are time-based (as opposed to
The full answer to those questions will come in Chapter 6, but here's the short one. More than just mere decoration, visual effects can be essential to providing a good
The script.aculo.us'
Effect
object is where the magic resides. Let's look at it. First, we'll need an element to try our effects on, so add one to the top of the new
index.
<div id="target" class="green box"> <div>Here's a DIV with some text.</div> </div> Now let's use the link_to_function to call an effect on the new element. Add this below the DIV :
<%= link_to_function "Fade", "new Effect.Fade('target')" %>
Remember, link_to_function takes two arguments: the first is the text for the link, and the second is a JavaScript statement to be evaluated. In this example, that statement is a method call on script.aculo.us' Effect.Fade . Load the page in your browser and try out the linkyou should see the target element slowly fade away, until it's removed from the page flow altogether. Internally, the first argument to Fade( ) is passed through Prototype's $( ) functionwhich means you can pass it either the ID of an element or an element reference itself.
There's another way to trigger effects, thanks to the fact that Prototype's Element
$('target').visualEffect('fade')
script.aculo.us has five
<%= link_to_function "Opacity",
"new Effect.Opacity('target', {to:0.5})" %>
<%= link_to_function "Scale",
"new Effect.Scale('target', 200)" %>
<%= link_to_function "Move",
"new Effect.Move('target', {x:50,y:10})" %>
<%= link_to_function "Highlight",
"new Effect.Highlight('target')" %>
<%= link_to_function "Parallel",
"new Effect.Parallel([
new Effect.Move('target', {x:50,y:10}),
new Effect.Opacity('target', {to:0.5})
])" %>
In your application, you'll usually use
combination effects
, which are
To try out all the standard combination effects, you could write a link for each one. Instead, let's keep things DRY by iterating through an array instead:
<% %w( Fade Appear Highlight Fold Pulsate SlideUp SlideDown
Shrink Grow Squish Shake DropOut SwitchOff Puff BlindUp
BlindDown ).each do name %>
<%= link_to_function name, "new Effect.#{name}('target')" %>
<% end %>
4.1.1. Toggling
Some of the effects are grouped into pairs (
Fade
/
Appear
,
BlindUp
/
BlindDown
, and
SlideUp
/
SlideDown
). script.aculo.us provides a
Effect.toggle('target') /* uses Fade/Appear */
Effect.toggle('target', 'blind')
Effect.toggle('target', 'slide')
4.1.2. OptionsThe Effect.* methods take an optional second parameter: a hash of options. Some options are effect-specific, but we'll look at those that apply to every effect. duration specifies how long the effect should last, in seconds. For example:
<%= link_to_function "Fade",
"new Effect.Fade('target', { duration:5 })" %>
fps
determines the
<%= link_to_function "Choppy Fade",
"new Effect.Fade('target', { duration:10, fps:2 })" %>
Note that because script.aculo.us effects are time-based, rather than frame-based, slower systems will automatically drop frames as necessary. delay specifies the time in seconds before the effect will be started. For example:
<%= link_to_function "Fade",
"new Effect.Fade('target', { delay:2 })" %>
from and to define the starting and ending points of the effect as values between and 1 . For example, you could jump directly to the halfway point of an effect, then gradually fade to 25 percent, and then stop:
<%= link_to_function "Fade with from",
"new Effect.Fade('target', { from:0.5, to:0.25 })" %>
4.1.3. QueuesIn some circumstances, you may want to chain effects, so that they occur sequentially. As a first attempt, you might simply call one effect after the other:
<%= link_to_function "Blind Up/Down",
"new Effect.BlindUp('target');
new Effect.BlindDown('target')" %>
Unfortunately, this won't have the desired result. As new effects are created, script.aculo.us adds them to a global queue. By default, these effects are executed in parallelwhich means these two effects will collide with each other. To specify an effect's position in the queue, use the queue option:
<%= link_to_function "Blind Up/Down",
"new Effect.BlindUp('target');
new Effect.BlindDown('target', { queue: 'end' })" %>
Now the two effects will execute sequentially, rather than at once. If you want more than two effects sequentially, just keep adding them with a queue of end . The queue option can also take a value of front , which causes the effect to be executed before anything else in the queue. script.aculo.us also supports multiple queues, so that you can create named scopes for effects queues that run independently. For more information on creating queue scopes, see Chapter 11. 4.1.4. Callbacks
The options hash can also take parameters for callbacks that are executed through the effect's life cycle.
beforeStart
is called before the main effects rendering loop is started.
beforeUpdate
is called on each iteration of the effects rendering loop, before the
<%= link_to_function "Fade with callback",
"new Effect.Fade('target', { afterUpdate: function(effect) {
effect.element.innerHTML = effect.currentFrame;
}
})" %>
Chapter 11 covers Effect callbacks in more detail. 4.1.5. TransitionsThe transition option determines the pattern of changea constant linear rate of change, gradual speed up, or anything else. There are eight standard transitions, and you can easily define new ones. To override the default transition for an effect, use the transition option like this:
<%= link_to_function "Fade with wobble",
"new Effect.Fade('target',
{ transition: Effect.Transitions.wobble })" %>
The available transitions are: linear , reverse , none , full , sinoidal , pulse , wobble , and flicker . Chapter 11 describes them in detail and explains how to create custom transitions. To get a feel for the possibilities, create a demo for yourself of each transition:
<% %w( linear reverse none full sinoidal pulse
wobble flicker ).each do name %>
<%= link_to_function "Fade with #{name}",
"new Effect.Fade('target',
{ transition: Effect.Transitions.#{name} })" %>
<% end %>
4.1.6. Visual Effect HelperSo far, we've been using script.aculo.us's Effect object directly, without the aid of Rails helpers. Rails also provides a helper to generate visual effects, allowing you to create effects without writing JavaScript. The helper is visual_effect , and it's used like this: visual_effect(:fade, :target) The first argument is the name of a script.aculo.us effect (almostsee the note below), and the second is the ID of a DOM element. The visual_effect helper outputs a JavaScript snippet, so it's usually used in combination with another helper, like link_to_function : <li><%= link_to_function "Fade", visual_effect(:fade, :target) %></li> The toggle effects can be used from the helper method as well:
<%= link_to_function "Toggle Blind",
visual_effect(:toggle_blind, :target) %>
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %} The visual_effect helper is especially useful when combined with Ajax helpers, such as link_to_remote . For example, you might use the Highlight effect to draw the user's attention to a portion of the page that has been updated via Ajax. To see it in action, first add a new action to chapter4_controller.rb : def get_time render :text => Time.now end And then create an Ajax link to it in views/chapter4/index.rhtml :
<%= link_to_remote "Get Time",
:update => "current_time",
:url => { :controller => "chapter3", :action => "get_time" },
:complete => visual_effect(:highlight, :current_time) %>
<div id="current_time"></div>
Notice that, unlike the examples in the last chapter, we aren't writing custom JavaScript in the :complete optioninstead, we let the visual_effect helper write it for us. |