Agile Web Development

Build it. Launch it. Love it.

KRJS

RJS is a great Ruby DSL to write javascript. However, its so tempting to write RJS directly in the views, and soon the views would contain substantial controller knowledge (e.g. link_to_remote, link_to, etc)

KRJS attempts to solve that problem by allowing dynamic inclusion of AJAX calls on HTML elements. When a controller defines a method (based on naming convention) that handles a client-side event, the rendering engine will do the wiring automatically - when the event happens, an AJAX call will be made to the controller’s method which would ideally reply with RJS and update portions of the document.

KRJS could potentially use behavior/selector style javascript instead of modifying elements itself - See http://www.lukeredpath.co.uk/index.php/2006/06/06/introducing-unobtrusive-javascript-for-rails and http://www.vivabit.com/bollocks/2006/02/09/rails-is-the-devil-in-your-client-side-shoulder.

Examples

To see it in action, create a blank controller and a index.rhtml file: ./script/generate controller Sample index

In your view (app/views/sample/index.rhtml) write:

  <%= form_tag({:action => 'submit'}, {:id => 'form'}) %>
    <%= text_field 'account', 'login', :id => 'account-new-login' %>
    <%= submit_tag 'Login' %>
  <%= end_form_tag %>

In your controller (app/controllers/sample_controller.rb), write: class SampleController < ApplicationController

  def on_form_submit
    render :update do |page|
      page.insert_html :after, params[:dom_id], CGI.escapeHTML(params.inspect)
    end
  end

end

Go to your browser, load the page and click on the submit button. The form should be submitted via ajax (not a fullpage refresh) and rjs code should update the page, right after the form (submit button)

You can also try adding this method to the controller:

  def on_account_login_blur
    render :update do |page|
      page.insert_html :after, params[:dom_id], CGI.escapeHTML(params.inspect)
    end
  end

View the page again, type in something in the textfield, press the TAB key (to lose focus on the input field). An AJAX call should be made to your controller, and the respective RJS will update the page.

Explanation

Controller#on_XX_YY means the controller receives ajax requests when event "onYY" of element XX occurs. e.g. if YY is "focus", then the ajax request is sent during "onfocus" even of XX field. Controller#on_XX_YY_ZZ means the controller receives ajax requests when field XX is modified - changes are polled every ZZ seconds instead of waiting for event to occur. Note: if YY is ‘form’ or ‘submit’, XX is considered as a DOM ID for a form instead of a field. This impacts the :with parameter. i.e. for a field, the value is submitted; for a form, the whole form is submitted

Installation

Go to your RAILS_ROOT directory and execute: ./script/plugin install http://choonkeat.svnrepository.com/svn/rails-plugins/krjs

Testing

To test, go to your RAILS_ROOT directory and execute (1 line): PLUGIN=krjs; rake test:plugins

License

KRJS is released under the MIT license.

Author

Chew Choon Keat http://blog.yanime.org/

12 June 2006

Vitals

Home http://blog.yanime.org/articles/2006/06/12/krjs-rjs-without-messing-the-views
Repository http://choonkeat.svnrepository.com/svn/rails-plugins/krjs/
License Rails' (MIT)
Tags Tag_red ajax fgh hjk jj rjs
Rating (18 votes)
Owner Chew Choon Keat
Created 14 June 2006

Comments

  • Avatar
    Downtown1
    20 December 2006

    There's a problem with the "tag" method on this KRJS. It seems to override the "tag" method that is uses in an ActiveRecord helper. So when you try to use make something like a text_field, usually AR automatically wraps that with a <div class="fieldwithErrors"> if there are errors on that field.

    But I noticed after installing KRJS that didn't happen anymore. But when I commented out your new tag implementation, it worked fine.

    I looked around, but unfortunately I didn't understand your new tag method too well to try to fix it on my own. Please fix this for the next version! Thanks

  • Avatar
    19 April 2007

    That has been fixed, thanks to Paolo DonĂ 

    see http://blog.seesaw.it/articles/2007/03/02/fixing-krjs

  • Aaron
    12 September 2007

    I just traced a bug in my application to KRJS. Firebug showed that, without the plugin, the app was posting: https://localhost/clients/editassociated/17502?method=get&association=meeting_registrations

    With the plugin, the request was: https://localhost/clients/editassociated/17502?method=get&amp;association=meeting_registrations

    In other words, the ampersand was incorrectly escaped. Modifying the override of tagoptions to use escapeonce instead of htmlescape fixed the problem (the original Rails 1.2.3 implementation used escapeonce).

  • Aaron
    12 September 2007

    My comment below makes no sense due to the way it was rendered. Second attempt:

    I just traced a bug in my application to KRJS. Firebug showed me that, without the plugin, the app was posting: <pre>https://localhost/clients/editassociated/17502?method=get&association=meeting_registrations</pre>

    With the plugin, the request was: <pre>https://localhost/clients/editassociated/17502?method=get&amp;amp;association=meeting_registrations</pre>

    In other words, the ampersand was incorrectly escaped. Modifying the override of <code>tagoptions</code> to use <code>escapeonce</code> instead of <code>htmlescape</code> fixed the problem (the original Rails 1.2.3 implementation used <code>escapeonce</code>).

  • Avatar
    wilson
    12 March 2008

    Doesn't work with rails 2.0!

  • Avatar
    John Del
    4 June 2008

    broken again with rails 2.1

  • Wes Hays
    18 July 2008

    In order to get it to work for Rails 2.1 I commented out "protectfromforgery" in application.rb and commented out lines 123 to 130 in krjs.rb. Everything still seems to work for me.

Add a comment