Getting my feet wet with Unobtrusive Javascript for Ruby on Rails

Got a link from fellow Filipino Ruby on Rails programmer Mark about a plugin that allows your Ajax-powered application to degrade gracefully when JavaScript is turned off. This is important because every user can choose to turn off JavaScript in their browser. If you rely solely on JavaScript, then your application will not behave properly in this situation.

The UJS (Unobtrusive JavaScript) Rails Plugin has a very professional looking website and I didn’t doubt for a second their claims. So I gave it a try.

When installing the plugin in Windows, you may encounter the “Exec format error – rake update_scripts (Errno::ENOEXEC)” error. Don’t worry, just execute the command below afterwards and you will be fine:

rake unobtrusive_javascript:install

Below is the sample RJS code I wanted to change:

<%= link_to_function(image_tag('new_album.jpg'), update_page { |page
 page.visual_effect :blind_down, 'folder_new', :duration => 0.5
 # some code removed
}) %>

This link, when clicked, will display a form where the user can input some data (just like the typical new.rhtml)

Here are the steps I did to transform the above UJS.

1. Create a new link to your desired action. In my case, a ‘new’.

<%= link_to(image_tag('new_album.jpg'), {:controller => 'albums',
:action => 'new'},  'id' => 'new_album') %>

Before, the link has no ID. Since UJS uses CSS selectors, the new link must have an ID or class. In my case, I used an ID since I want this to be uniquely identifiable in my page.

2. Now, let’s use UJS

<% apply_behavior 'a#new_album:click' do |page, element, event
  page.visual_effect :blind_down, 'folder_new', :duration => 0.5
end %>

Note that there are 3 parameters to the code block. Even though I did not use ‘element’, I need to include it so that ‘even’t will have the correct object. (Is there an alternative here?)

I called ‘event.stop’ to prevent the original link from executing.

Some gotchas I encountered.

1. Not specifying the action attribute in the CSS selector.

Initially, I had this code. Note there is no ‘:click’

<% apply_behavior 'a#new_album' do |page, element, event| do %>

When a I did a page refresh, the UJS code was executed right away.

2. Specifying too many javascript_include_tag.

This one took almost 80% of my time to figure out. 🙂 Since this is anew JavaScript, you need to include it in the before you can use it. Following the tutorial, I pasted the code in my layout/application.rhtml

<%= javascript_include_tag 'prototype', :unobtrusive %>

Even though I followed everything, the behavior was still not being applied to my “a#new_album” link. The problem is caused by these two lines in my layout/application.rhtml

<%= javascript_include_tag 'prototype', :unobtrusive %>

This two lines will include “prototype.js” twice. Viewing the generated HTML source code, I thought this was harmless. I merged the above two lines into a single call

<%= javascript_include_tag :defaults, :unobtrusive %>

Now, the UJS works. Actually, I have no idea what had just happened. It seems including “prototype.js” twice affects the behavior of UJS


I love it!!! The Rails code is simpler and more importantly, I can turn off JavaScript and everything can still work. My only problem right now is recovering the old RHTML codes I removed after I transitioned to RJS 🙂


One thought on “Getting my feet wet with Unobtrusive Javascript for Ruby on Rails

  1. Great article! I’ve known about UJS for awhile now but I’ve yet to use it in any of my projects. The UJS site by the way uses a variation of the Sydney mephisto theme used in Luke Redpath’s blog, which I agree is a very slick, classy looking theme. In fact, I’m thinking of using a similar black background/white text look for one of my upcoming projects, subject to approval of my clients. I already use a modified sydney theme for a gaming community portal i’m developing.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s