New to Rails 3? Check out the Ruby on Rails 3 Tutorial book and screencast.

A book and screencast series showing you how to develop and deploy industrial-strength Rails apps in a direct, step by step way. The screencast series includes 12 lessons over more than 15 hours! Get the best "over the shoulder" experience of following what a top Rails 3 developer does when building an app today. Click here to learn more.

HOWTO: Unobtrusive JavaScript with Rails 3

In Tips

This post is by Rizwan Reza. See footer for more info.

sanjuanoil.pngOne of the big surprises and accomplishments is the fact that Unobtrusive Javascript made it into Rails 3. At first, we thought UJS wasn’t going to be included in Rails 3. Well, just before the first beta came out, the community responded well and a bunch of enthusiastic developers finished up one of the most wanted feature in Rails 3.

Rails has always been about staying on the cutting edge and Rails 3 is no surprise, UJS implementation in Rails 3 takes benefit of the new HTML5 data-*@ attributes. So Rails doesn’t spit out Prototype-based Javascript inline (the old helpers are still here). Rather, the helpers just define an appropriate data attribute in the tag, and that’s where Javascript comes in.

This literally means you can pick the data attributes in any Javascript framework and write generic code to support Ajax implementation of any kind. As you can imagine, this can be a highly flexible approach for demanding applications. But there’s more, the generic Prototype implementation is included with Rails 3 and the jQuery version is maintained officially here.

Let’s see how easy it is to swap jQuery in Rails 3. In the root of a Rails 3 application, run:

curl -L http://code.jquery.com/jquery-1.4.2.min.js > public/javascripts/jquery.js
curl -L http://github.com/rails/jquery-ujs/raw/master/src/rails.js > public/javascripts/rails.js

Here’s an initializer I got to know from Yehuda that you can define in config/initializers so javascript_include_tag :defaults uses jQuery instead of Prototype.

module ActionView::Helpers::AssetTagHelper
  remove_const :JAVASCRIPT_DEFAULT_SOURCES
  JAVASCRIPT_DEFAULT_SOURCES = %w(jquery.js rails.js)

  reset_javascript_include_default
end

With that set, Rails is now unaware of Prototype, all of the helpers with :remote => true will be grabbed by rails.js and worked through jQuery. You might also want to remove the Prototype libraries inside public/javascripts if you’re not going to use them.

As you can see, UJS in Rails 3 is pretty easy. Though there is a bit of a configuration to be done if you’re going against the default option in Rails, it’s far easier to work with than in the previous versions. You should also look at the fantastic Rails 3 Release Notes for changes in the concerned helpers and the section on Unobtrusive Javascript in my article on RailsDispatch.

[post by] Rizwan Reza is a passionate, self-taught developer and designer who’s been working with Rails since early 2005. He had his first Rails patch accepted in mid 2008, and has been contributing code and fixes ever since. Rizwan focuses on the start-to-finish product experience, all the way from branding to the application backend. Get in touch with him at contact at rizwanreza.com.

Post to Twitter Tweet This Post

Vaguely Related Posts (Usually)

10 Comment Responses to “HOWTO: Unobtrusive JavaScript with Rails 3”

  1. #1
    Phil McClure Says:

    Nice article. I did a bit of a write up on UJS a while ago. Might be of use to someone... http://therailworld.com/posts/26-Using-Prototype-and-JQuery-with-Rails3-UJS-

  2. #2
    Lee Says:

    Hmm...I thought UJS was the term used to describe how you write javascript separate from your html (like how css is separate from html). This article seems to illustrate how Rails 3 is modular, letting you pick what javascript framework you want (or what ORM your want, etc). How is that UJS?

  3. #3
    Sohan Says:

    Your post has been linked at the DrinkRails blog as one of the top ruby on rails blogs of the day.

  4. #4
    iGEL Says:

    Thanks for the article. I really look forward to use jQuery this easily in Rails 3.

    But I prefer to load jQuery from Google. From the users point of view, it doesn't make sense to have to download the same 72KB (24KB if your server delivers JS with gzip) library for every site again. Using the Google AJAX API, there is a good chance that the user already has the lib in his cache.

    Also, Google has one of the best content delivery networks in the world, so it will download probably deliver faster than your site, from everywhere in the world.

    Just load jQuery using http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js for the latest 1.4 release or http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js, if you don't want to update to the next point release automatically.

    See http://code.google.com/apis/ajaxlibs/ for details.

  5. #5
    Rizwan Reza Says:

    @Lee:

    Before Rails 3, Rails spitted out the code inline in HTML rather than allowing us developers to write code in Javascript files unobtrusively. This post is meant to announce that Rails 3 helpers now appreciate UJS rather than otherwise. The 'letting you pick any framework' part is a bonus. :)

    iGel:

    I agree. Thanks!

  6. #6
    kritic Says:

    @iGel or whoever,

    How do I apply the Google AJAX API way to this tutorial?

    Would I just put:

    JAVASCRIPT_DEFAULT_SOURCES = %w(http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js rails.js)

    ?
    I'm new to this stuff... obviously

  7. #7
    Unobtrusive JavaScript in Rails 3 « kswebdev Says:

    [...] HOWTO: Unobtrusive JavaScript with Rails 3 [...]

  8. #8
    martinisoft Says:

    I made a gist of these setup steps in a Rake file you can drop into your rails app and run. http://gist.github.com/464890

  9. #9
    Roland Says:

    Thanks for documenting it.

    It's not very easy to find rails.js yet — hopefully it will be promoted better on the launch of rails 3.

  10. #10
    Ed Ruder Says:

    In Rails 3.0.0, the ActionView::Helpers::AssetTagHelper::JAVASCRIPT_DEFAULT_SOURCES is no longer used. The recommended way to so this (documented in asset_tag_helper.rb, though not in RDoc) is to put the following line in config/application.rb:


    config.action_view.javascript_expansions[:defaults] = ['http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js', 'jquery-ujs']

    (As @iGEL suggests, I load jQuery from Google, and I chose not name jquery-ujs's JavaScript file as rails.js, since that's the name of the "stock" rails JavaScript file.)

Leave a Reply