KRJS: RJS without messing the Views

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:

KRJS walkthru: Default form

Clicking on Login leads you to an even simpler error page:

KRJS walkthru: Default page after submitting form

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

KRJS walkthru: Result page after installing KRJS and clicking form

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:

KRJS walkthru: Result page after losing focus on text 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]