HOWTO: Unobtrusive JavaScript with Rails 3
This post is by Rizwan Reza. See footer for more info.
One 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.
May 24th, 2010 at 2:16 pm
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-
May 25th, 2010 at 2:11 am
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?
May 25th, 2010 at 3:15 am
Your post has been linked at the DrinkRails blog as one of the top ruby on rails blogs of the day.
May 28th, 2010 at 4:20 pm
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.
May 28th, 2010 at 8:12 pm
@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!
June 11th, 2010 at 7:35 pm
@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
June 13th, 2010 at 9:00 am
[...] HOWTO: Unobtrusive JavaScript with Rails 3 [...]
July 6th, 2010 at 1:28 am
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
August 3rd, 2010 at 11:53 pm
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.
October 10th, 2010 at 6:01 pm
In Rails 3.0.0, the
ActionView::Helpers::AssetTagHelper::JAVASCRIPT_DEFAULT_SOURCES
is no longer used. The recommended way to so this (documented inasset_tag_helper.rb
, though not in RDoc) is to put the following line inconfig/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.)