Ruby and Rails » Rails RJS Templates

I gave a short presentation at work recently describing how to use RJS Templates.

Presentation Media:

presentation_rjs_templates-20060131.mp3

About

RJS Templates are similar to .rhtml templates except they contain Javascript commands and have an .rjs file extension. The action/view base naming scheme remains the same. Unlike conventional templates which are used to render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax and make updates to the page where the request originated from.

Currently supported RJS methods/features:

  • insert_html
  • replace_html
  • show
  • hide
  • visual_effect
  • alert
  • redirect_to
  • call
  • assign
  • «
  • toggle
  • delay

Install

There are currently two ways to enable RJS templates in your rails app. The simplest way is to update your rails app to use edge rails. The second, slightly more involved way is to install RJS templates as a plugin.

Edge Rails

Edge Rails is a term that means you are running a local copy of the latest SVN trunk of Rails, instead of using gems. By checking out the trunk into your /vendor dir, Rails will automatically use that instead of the gems installed on your machine.

The easiest way to get your rails app running on edge rails is to unpack the latest edge rails into your application vendor directory using the following commands:

rake freeze_edge
rake update_javascripts

This puts the entire rails framework into your application. This also allows you to run on computers without rails installed.

To undo it:

rake unfreeze_rails

More info on Edge Rails can be found here: http://wiki.rubyonrails.com/rails/pages/EdgeRails

Plugin

To install RJS Templates as a plugin, do the following:

script/plugin discover

This will question you whether or not you want to add the plugin repositories that have been listed on the Rails Plugins wiki page to your local list of plugin repositories. Ensure that you add the codyfauser.com repository when prompted. You can ensure that you have the correct repositories by executing:

script/plugin sources

Now do:

script/plugin install javascript_generator_templates

Alternately if you don't want to add the codyfauser.com repository to your list of plugin sources you can install the plugin in one shot as follows:

script/plugin install \
  http://www.codyfauser.com/svn/projects/plugins/
  javascript_generator_templates/

Example

Categories List

SQL:

CREATE TABLE categories (
  id serial NOT NULL,
  name character varying(64)
);

Initial Setup:

rails rjs_demo
cd rjs_demo
rake freeze_edge
rake update_javascripts
script/generate controller home index add
script/generate model category

View Template app/views/home/index.rhtml:

<%= form_remote_tag :url => { :action => 'add' } %>
Category: <%= text_field 'category', 'name' %>
<%= submit_tag 'Add' %>
<%= end_form_tag %>

<ul id="categories">
<% @categories.each do |category| -%>
  <li><%= category.name %></li>
<% end -%>
</ul>

Nothing special, just a category list and a form to add more categories. Note the <ul> tag is identified as 'categories'. This would work the same if it were a <table> or <tbody>.

Controller Methods app/controllers/home_controller.rb:

class HomeController < ApplicationController

  def index
    @categories = Category.find( :all )
  end

  def add
    @category = Category.new
    if request.post?
      @category = Category.create( params[:category] )
    end
  end

end

Posting adds the category to the database and assigns it to @category which will be used in the RJS template. After the action completes it looks for a template named add.*, and ours is called add.rjs so it uses that.

RJS Template app/views/home/add.rjs:

if @category && @category.errors.empty?
  li = content_tag( 'li', @category.name )
  page.insert_html :bottom, 'categories', li
  page.visual_effect :highlight, 'categories',
    :duration => 3
end

If the category was created with no errors then we add it to the bottom of the 'categories' list. The magic here is the 'page' object. With the page object you can work on most any element in the html document. All the methods listed at the top are available.