Unobtrusive Javascript Plugin
Posted by rick August 21, 2006 @ 04:36 PM
Dan Webb and Luke Redpath have release the latest version of their Unobtrusive Javascript Plugin for Rails. It solves several of the main problems people run into when working with unobtrusive javascript:
- Development isn’t as intuitive with Rails when you’re defining your custom javascript behaviors in an external file.
- When working with pages with lots of images and content, the behaviors won’t be enabled until everything is downloaded and window.onload is called. It’s been solved with some nasty cross-browser javascript hacks, all handled transparently by Dan’s LowPro extension for prototype. This has been a big deal for me personally, so it’s nice to see it all solved.
UJS attempts to solve this by taking defined behaviors in the view and creating a tailored javascript file for it. Smart conditional GET and page caching techniques can be used to save bandwidth and time.
All in all, it looks like Dan and Luke did an excellent job on the plugin. Anyone using it? How’s it working out for everyone?

Yes, that’s the real question, is anyone using this in production yet? I love this idea and it seems to be well implemented. But it’s a bit scary to use a plugin like this because what happens if the next version of Rails breaks it? Then you have to wait for updates, etc. This is the main reason I’ve steered clear of using Engines.
Rick, what are the chances of something like this getting into core? Is it being considered, or is this purely destined to be a plugin? I’m not making a judgement call on whether or not it belongs in core, I haven’t thought it through. But I am curious if you guys have.
Cheers, John
Haven’t started using it yet, cause I just found out about it via the mailing list…but what an exciting project! I can’t wait to start implementing it. Obtrusive javascript has been one of the biggest hangups in the back of my mind, but I simply did not have the time to extract all my behaviors into external files.
Thanks for all the hard work on such an awesome plugin Dan & Luke! Now my client side code can be as clean, standards-compliant and accessible as my backend code is elegant!
I’ve used the LowPro script in my projects and love the simplicity of adding behaviors. However, I’ve steered clear of this plugin because I’m hesitant with the idea of keeping behaviors in each view. Just like css, I keep a separate directory structure that defines behaviors for controllers, individual views if needed, and shared behaviors (similar to the views directory structure).
And in the same way models, views, and controllers are separated in rails, I like to see the same structure in the individual pages. Instead of M-V-C, you H-C-B (Html, CSS, Behavior). Well, that at least makes most sense to me.
Johnpg – I can’t speak for the core (although I can guess what their answer will be) but I’ll give you my opinion – this is best left as a plugin. I’m as big a fan as the core team of keeping the Rails core as lean as possible (there are several things I’d like to see removed from the core and plugin-ized). I understand your concern about new Rails releases breaking the plugin, so let me tell you this.
Both Dan and I are using this in real projects; we both have a vested interest in the plugin and we will make certain that this plugin is compatible with new releases. We constantly monitor the core and run our plugin against the trunk and will aim to have fixes for changes to the core whilst they are in trunk, before they are part of an official release.
For example, the plugin current doesn’t work with edge rails past revision 4727 due to the new dependencies system. However I feel that this is because of fundamental issues with the new dependencies system that are yet to be worked out. When these issues are resolved, we will be aiming to have the plugin working before the changes make it into an official 1.2 release.
Luke
- That’s reassuring to hear, thanks. As for core, I didn’t make a judgement call one way or the other. But I was curious what their thinking on it might be. In many ways this method seems more like the “right way” so maybe it’s not such a bad idea. But in general I agree with the “make it a plugin” approach nine times out of ten. Maybe even nine and a half times out of ten. :)Cheers, John
Some of the core team is interested in this, but it is a big change. Having a plugin lets us keep our choices open, allow users on older versions to use it without upgrading (possibly, I don’t know how UJS works on Rails 1.1.6), and finally, keeps the Rails book authors from killing us ;)
Seriousness aside, if the plugin turns out to be the defacto standard, it may find itself in core. There are a few plugins (Asset Timestamping, Calculations, Filtered Logging) that have made this transition. This plugin seems like a big change from the standard Ajax stuff, so I personally don’t see it happening anytime soon.
I’m just not really sold on the whole idea of writing JS from Ruby. I’ll write JS myself, thanks…
Seth – thats fine; UJS doesn’t force you to write JS in Ruby. The RJS-style functionality was just a nice bonus for those small, procedural JS snippets.
Both Dan and I are all for putting complex Javascript where it belongs – in its own, well written JS library, with UJS simply used to hook into it and fire off commands.
But theres a lot to be said for wrapping commonly used JS functionality in Ruby helpers (such as make_draggable, make_sortable etc.), for all of the same benefits of wrapping up commonly used HTML functionality in helpers – to avoid duplication. Why repeat yourself when helpers help you keep your behaviours DRY?
On the point of adding this kind of thing to the core I’d have to say I think it’s better as a plugin. In fact, if I had my way I’d pull out all of the JavaScript related stuff as a (collection of) plugins.
I find JavaScript helpers useful and I do write my own but I’d rather have my choice of library per project so I don’t like being tied to Prototype by the core.
That being said, I realise Prototype’s inclusion as being part of the ‘Full stack’ of the Rails framework and also responsible for a susttantial part of it’s success. The problem for me is that I don’t think Prototype (or any JS lib) has got the client-side licked as well as Rails has the server-side licked so I still want my choice here.
We are using it, on a fairly basic electronic whiteboard system. I love it. We have really high accessibility standards to hit and keeping the HTML and the js away from each other is a big step forward. Obviously we are using all the fall back actions so that the app still works with js turned off. But having the freedom to add some nifty functionality to our screen with turning the HTML into tag soup is just money.
The biggest benifit that I can see is that it’s totally transparent, and fixes all those rails javascript features such as :confirm, and :post => true, that most of us use with out thinking about the consequences. Well now you can because the js is tucked away and your code is all nice and clean again. All your link_to_remote etc are fixed for you too.
UJS for rails uses your existing ID’s if they are already there and insert’s it’s own if not. Go get it today. Oh, you do need a fairly recent version of the prototype library, if you get UJS and install it on a fairly old app (like 9 months old ;-> ) and nothing seems to be working then nip off to the prototype site and treat yourself to the latest and greatest. Great work Dan and Luke.