Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

Using jQuery in Rails (Part I)

This is the first in a series of posts about using jQuery together with Ruby on Rails. In my professional life, I work on Procore, a project management tool for the construction industry. The application is massive by any standard. And before I came on, it made heavy use of the Prototype library, Rails’ native JavaScript mechanism.

When I came onboard, I introduced the team to jQuery, and they loved it. But it was far too much work to backtrack and remove all Prototype instances and replace them with jQuery. So our massive, complex app uses both, with no difficulties. Both libraries live side-by-side, causing no problems.

In this series, I will discuss setting up jQuery in Rails, and some techniques I’ve developed to make working with jQuery easier in Ruby on Rails applications.

First up, installation:

You’ll need to download a working copy of jQuery from jQuery.com. You can either get the most recent release (recommended), or, if you’re particularly adventuresome, you can build your own copy of bleeding-edge jQuery.

Drop jquery.js into public/javascripts, and add <%= javascript_include_tag "jquery", "application" %> to your main layout file.

Your site will now be loading in jQuery, as well as application.js in every page (application.js is your application’s default JavaScript file and is created by default when you run the “rails” command). If you want to run Prototype alongside jQuery, use <%= javascript_include_tag :defaults, "jquery" %>. This will load in the default prototype files, application.js, and jQuery.

In application.js, add the following:

jQuery.noConflict()

That will call jQuery.noConflict(), which relinquishes control of the $ alias to Prototype.

jQuery Commands

Virtually all jQuery commands won’t function correctly unless they’re run after the DOM has fully loaded. jQuery’s way of solving this is something called a “document ready block.”

jQuery(document).ready(function() {
  // commands go here 
})

This waits until the document is ready, the fires off the function passed to ready. Here’s a shortcut syntax:

jQuery(function() { 
  // commands go here 
})

This does exactly what jQuery(document).ready(…) does, but is shorter. The strategy for using jQuery in Rails is to treat JavaScript in much the way you treat CSS. You’re binding behavior, not style, to a particular set of elements identified by particular markup.

In CSS, you might give an “a” tag the class “external” to indicate that the link goes to a page external to your site. Through a site-wide CSS page, you can then indicate that you want the tag to use a special graphic (like in Wikipedia), to illustrate to users that the link is external.

Using jQuery, you can then indicate what behavior you want this link to have. For instance, you might the link to open in a new window. Inside the document ready block, you would use:

jQuery("a.external").click(function() { 
  window.open(this.url, "_blank") 
})

I will use jQuery, not $, throughout this tutorial series, because some of you will be using Prototype alongside jQuery in your Rails apps. If you’re not, feel free to convert any instance of “jQuery” to “$”

The above snippet will bind a click handler to all links with class “external,” and open them in a new window. And what’s great is that with JavaScript turned off, the link opens the page perfectly well, just in the same window.
Now, let’s say you like this a lot, and want a simple Rails way to create links with the appropriate markup throughout your app (without having to train all other developers on the new markup requirements).

You might create a simple helper in application_helpers.rb. Say, something like:

def external_link_to name, options = {}, html_options = nil, *parameters_for_method_reference
  (html_options ||= {}).merge!({:class => "external"})
  link_to name, options, html_options, *parameters_for_method_reference
end

As you can see, I’ve grabbed the call signature from link_to, made some modifications to html_options (added :class => external), and then fired off a call to the original link_to.

This is a very simple example, but this is the strategy we will use throughout this series: create some markup that is used to identify a particular behavior, instantiate the behavior via jQuery, and then, if desired, write a helper to make markup generation easier.

Next up: Create a sortable list using jQuery and Interface. We will look at how to create the markup, write a helper, and write a single, reusable controller method to use the returned results to update a model.

13 Responses to “Using jQuery in Rails (Part I)”

interesting – are there versions of the rails helpers that work with jquery rather than prototype?

I think we’ll have to write our own helpers :/

Nope. In time for RailsConf, I’ll be releasing helpers that work with jQuery rather than Prototype, and a much more interesting unobtrusive framework.

Stay Tuned.

Looking forward to it :-)

Hi there,sounds great yehuda.

Any chance of a private release of anything you’ve done b4 RailsConf (which is quite a long time away). I can help you out as well

jonah

I’m looking forward to seeing this. The default approach Rails uses with embedded JS really grates on me, I’d like to see things move toward unobtrusive scripting. While I’m glad for the UJS project moving things in the right direction for Rails + Prototype, I’m not a big fan of the way it relies on sessions to store behaviour data.

Agreed on getting hold of your jQuery on Rails work; was sad when the svn disappeared from visualjquery.com

Let us help you write it!! :)

I just looked at the sessions list in and I didn’t see your presentation listed. Am I missing something?

Hey guys! Thanks for your enthusiasm. I posted today about the status of the project, and you can check out the Birds of a Feather at 9:30 tonight: http://conferences.oreillynet.com/cs/rails2007/view/e_sess/14591

Please comment on the latest post!

I just completed a plugin called jRails that makes using jQuery with Rails very easy. It is essentially a drop-in jQuery replacement for Prototype/script.aculo.us on Rails and you get all of the same default Rails helpers using the lighter jQuery library.
http://www.ennerchi.com/projects/jrails

I couldn’t find the link for the part-II.
Does part-II exists or not? Can anyone paste in the url, plz.

Geart article ! I new in rails development and jquery. This type of help is very import for us (beguinners in language)!

it heilp me a lot

thanks!

How about for Rails 3? There’s not much about this online yet, could you show this some love in a post?

Leave a Reply

Archives

Categories

Meta