Making jQuery and Prototype play nice in Rails

Written by on Dec 30 2006

For those of you not in the know, there is a relatively new (about a year old) javascript library called jQuery. Over the past year I have really fallen in love with jQuery, it makes me happy coding in it, the way rails makes me happy. Sadly, Prototype now makes me feel like I feel when I am writing c# code, I’ll leave it to your imagination what that feels like.

So for a while now I have been using Prototype and jQuery together in my rails apps. I am kinda stuck with pPrototype, because it is fairly well embedded in rails. Which is fine with me because I don’t have to use it directly, just let rails render it. There is a problem with using them together though: Prototype came up with this nice function called $() which is slightly more than a shortcut to document.getElementById(). This function is the main function in Prototype. Well, John Resig, the creator of jQuery, also used to be a Prototype fan, so the main method in jQuery is also called $(). The jQuery website says that all you have to do to get them to play nice is to include jQuery after you include Prototype. Unfortunately, this is not enough. There is just a little bit more you have to do:

In the jQuery core code (which includes ajax, animations, et al.) there is a method called jQuery(). The $() method is aliased for the jQuery() in the code. This means that all you have to do is remove the part of jQuery that alias the $() method. In jQuery 1.0.4 uncompressed the lines you need to comment out start at line 60:

Change:

// Map over the $ in case of overwrite if ( typeof $ != “undefined” ) jQuery._$ = $;

// Map the jQuery namespace to the ‘$’ one var $ = jQuery;

To:

// Map over the $ in case of overwrite //if ( typeof $ != “undefined” ) //jQuery._$ = $;

// Map the jQuery namespace to the ‘$’ one //var $ = jQuery;

Once this is done, jQuery will no longer interfere with Prototype. You will have to use the jQuery() method to create a jQuery object, unless you alias the method to something else. I alias it to jq like this:

Change:

var $ = jQuery;

To:

var jq = jQuery;

One last thing: Although all of the core uses JQuery() internally, there is no guaranty that any plugin will do the same, in my experience none do. The solution that works for me is to do a find/replace in the downloaded plugin, replacing any $( with jQuery(.

That’s it. Now you can easily use jQuery and prototype in your rails app, even in the same view. I regularly use in_line_edit (which produces Prototype code) and jQuery in the same view, no problems.

7 Comments

Sohum
Sohum said on December 31, 2006

Hey Steve, it’s me again. Excellent post, fulfilling one specialized, unique need in a clear and simple way.
A nitpick, though: you alternately refer to jQuery as jquery, jQuery, and JQuery. JQuery is actually an eclipse plugin for Java development; I’ll point you to an InfoWorld article that gets it right.
Also, I reckon it looks cleaner if you alias jQuery() to _$(), although it is slightly harder to see if you’ve corrected it or not. Luckily I have good old Venkman to tell me what’s wrong.
Look forward to more posts in the future!

—Sohum

Pedro
Pedro said on December 31, 2006

Vote for me.

And I like just aliasing jQuery to ~.

weepy
weepy said on January 02, 2007

you can use a single underscore: _

but that’s probably a bit confusing (doesnt take up much space)

Sohum
Sohum said on January 12, 2007

Also, you might want to search-and-replace ‘$.’, as many plugins apparently use the namespace internally.
(Thanks Katz — as a comment on my blog)

dan
dan said on March 27, 2007

just to let you know, my own instinct was also to use ‘jq()’ as the alias:
1: it has some sort of resonance with ‘jQuery’ (unlike ‘$’)
2: it’s easy to pick up on as first time user when you see an import called ‘jquery.js’
3: it looks nicer
4: it’s only 1 more character than ‘$’…

so, big thumbs up to that small point.

Dave
Dave said on November 07, 2007

As well, there is a nice little function that JQuery has now, might not been around in the time of this writting:

$j = JQuery.noConflict()

$j can be what ever you wish.. :)

Steven Bristol
Steven Bristol said on November 07, 2007

Thanks Dave. I always meant to update this post, but I guess I never have. :P

Meet
Steven

Hi I'm Steven,

I wrote the article you're reading... I lead the developers, write music, used to race motorcycles, and help clients find the right features to build on their product.

Get Blog Updates