ProblemYou want to enhance your user's experience by adding visual effects to the interactive elements of your application. Specifically, you have a list of terms that are links, and you want the definition of each term to slide down when a term is clicked. SolutionUse the visual_effect JavaScript helper to define the :blind_down callback of the script.aculo.us library. Create a table called terms, and populate it with some terms and their definitions. The following migration sets this up: db/migrate/001_create_terms.rb: class CreateTerms < ActiveRecord::Migration def self.up create_table :terms do |t| t.column :name, :string t.column :definition, :text end Term.create :name => 'IPv6', :definition => <<-EOS The successor to IPv4. Already deployed in some cases and gradually spreading, IPv6 provides a huge number of available IP Numbers - over a sextillion addresses (theoretically 2128). IPv6 allows every device on the planet to have its own IP Number.' EOS Term.create :name => 'IRC', :definition => <<-EOS Basically a huge multi-user live chat facility. There are a number of major IRC servers around the world which are linked to each other. Anyone can create a channel and anything that anyone types in a given channel is seen by all others in the channel. Private channels can (and are) created for multi-person conference calls. EOS Term.create :name => 'ISDN', :definition => <<-EOS Basically a way to move more dataover vexisting regular phone lines. ISDN is available to much of the USA and in most markets it is priced very comparably to standard analog phone circuits. It can provide speeds of roughly 128,000 bits-per-second over regular phone lines. In practice, most people will be limited to 56,000or 64,000 bits-per-second. EOS Term.create :name => 'ISP', :definition => <<-EOS An institution that provides access to the Internet in some form, usually for money. EOS end def self.down drop_table :terms end end Next, include the Prototype and script.aculo.us libraries in your layout by passing :defaults to the javascript_include_tag helper method. Additionally, define a style for the term definition element that will appear when a term is clicked. app/views/layouts/terms.rhtml: <html> <head> <title>Terms: <%= controller.action_name %></title> <%= javascript_include_tag :defaults %> <%= stylesheet_link_tag 'scaffold' %> <style type="text/css"> .def { position: relative; width: 400px; background-color: #ffc; border: 1px solid maroon; margin-top: 20px; padding: 10px; } </style> </head> <body> <%= yield %> </body> </html> Define two actions in your TermsController named list and define. app/controllers/terms_controller.rb: class TermsController < ApplicationController def list @terms = Term.find :all end def define term = Term.find(params[:id]) render :partial => 'definition', :locals => { :term => term } end end Next, create a view that iterates over the terms and displays them as links: app/views/terms/list.rhtml: <h1>Term Definitions</h1> <% for term in @terms %> <h3><%= link_to_remote term.name, :update => "summary#{term.id}", :url => { :action => "define", :id => term.id }, :complete => visual_effect(:blind_down, "summary#{term.id}", :duration => 0.25, :fps => 75 ) %></h3> <div style="display: none;"></div> <% end %> To display each term definition, define a partial called definition.rhtml. This file should also include a link for hiding each definition. app/views/terms/_definition.rhtml: <%= term.definition %> <i><%= link_to_remote 'hide', :update => "summary#{term.id}", :url => { :action => "define", :id => term.id }, :complete => visual_effect(:blind_up, "summary#{term.id}", :duration => 0.2 ) %></i> DiscussionThe :blind_down effect is named after a window blind; each definition is "printed" on a blind that rolls down when it is needed. Once a definition is fully visible, it can be rolled up (hidden) with the :blind_up option. The solution defines a list method in the Terms Controller that passes an array of terms to the view. The view, list.rhtml, iterates over the @terms array, creating a link_to_remote call and a corresponding, hidden div element for each term definition. The id of each of these div elements is uniquely named using the term.id (e.g., summary1, summary2). The link_to_remote call uses this unique id to pair the term links with their definition elements. The :url option of link_to_remote points to the define action of the Terms Controller. This action gets a term object and renders the definition partial, passing the term object as a local variable to that partial. Finally, the definition.rhtml partial is rendered, unveiling the term definition over a period of a quarter second (at 75 frames per second). The displayed definition elements contain a "hide" link that rolls the element back up when clicked. The blind effect in the solution can really help with an application's usability if it is used thoughtfully. For example, there is little question that the definition of each term applies to the term above it because this where the unrolling definition originates. The script.aculo.us library includes a number of other interesting effects including puff, switch_off, slide_down, and pulsate, etc. Figure 8-10 shows the terms from the solution as links that "blind down" their definitions when clicked. Figure 8-10. A term's definition appearing via the blind-down visual effectSee Also
|