RJS is great and awesome. I use it quite regularly now. With RJS, I don't have to deal with which parts of the page to update in the rhtml files - I get to decide whilst in my controller using the nice and elegant render :update. Sweet.
But part of me wished I didn't have to even decide which page elements are to be ajaxified. I'd wish I could more easily enable a link, form or button to make ajax calls without going back and touching my html...
Oh well.
Introducing the KRJS plugin, with less than 60 lines of patch to Rails' ActionPack itself (which probably means bugs are aplenty, would slow production sites to a crawl, and that its fresh from the oven too)
To see KRJS in action (so what does it do?), generate a blank controller and index action:
./script/generate controller Sample index
Give it a decent layout (include javascripts) by creating the file app/views/layouts/sample.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<%= @content_for_layout %>
</body>
</html>
Create a sample form:
<%= form_tag({:action => 'submit'}, {:id => 'form'}) %>
<%= text_field 'account', 'login', :id => 'account-new-login' %><br />
<%= submit_tag 'Login' %>
<%= end_form_tag %> This will be the last time we're touch the Views. If you visit the page now, you should see a simple form. This is the most basic Rails app. It will be our mickey mouse app for this session:
Clicking on Login leads you to an even simpler error page:
This is because we didn't have any code to handle the form submit. Don't let that stop us web2.0-ers, let's ajaxify it anyways! First, install the KRJS plugin
./script/plugin install http://choonkeat.svnrepository.com/svn/rails-plugins/krjs/
and restart your server.
Now, try to view the page, and click on the Login button.... same error page. Good! That means KRJS didn't mess up the original app. Now let's add a new method into the controller, app/controllers/sample_controller.rb
def on_form_submit
render :update do |page|
page.insert_html :after, 'form', CGI.escapeHTML(params.inspect)
end
end
Refresh the page, and click on Login
As you can see, the form has become ajaxified - to update the page instead of sending the browser to a new location - by merely adding a new corresponding method in the controller! How about adding this to the controller:
def on_account_login_blur
render :update do |page|
page.insert_html :after, 'form', CGI.escapeHTML(params.inspect)
end
end
Refresh the page, type something into the textfield and TAB away from the field:
Yea, KRJS registers onBlur events as well. In fact, it'll register onClick, onSubmit, onWatever, onYouwant because it doesn't really care. All that matters is your HTML element's ID attribute. KRJS currently identifies xhr actions by naming conventions, hence it will probably be most convenient to be used with dashed_dom_id plugin.
Go ahead, give it a spin. I'm going to sleep.. hope I don't wake into a world of horror...
[Updated plugin links]




If the "on_xx_blur" didn't work in the example above, please use revision 3 of the plugin.
I must've broken it whilst adding observer support in r4. Will fix later.
Posted by: choonkeat | June 12, 2006 at 06:55 PM
fixed in revision 5
Posted by: choonkeat | June 13, 2006 at 08:43 AM
That's really awesome! I'll give it a try asap! great work :)
Posted by: Federico | June 13, 2006 at 06:28 PM
tickets and updates, pls refer to
http://choonkeat.svnrepository.com/rails-plugins/trac.cgi/wiki
Posted by: choonkeat | June 14, 2006 at 02:40 AM
Interesting idea! Is there a way to abstract this into, say, the controller's helper so view code doesn't muddle the controller?
Posted by: Grant | June 15, 2006 at 09:36 PM
If I'm not mistaken, helper methods are not part of the controller themselves, hence you can't.
You can probably mixin a module or have your controller inherit the on_xxx methods from somewhere else instead.
Posted by: choonkeat | June 16, 2006 at 08:55 AM
Very nice. Will give it a try over the weekend.
Posted by: Hendrik | June 16, 2006 at 08:25 PM