I’m finally digging into the jQuery setup with Rails 3.1. As you are all likely aware, jQuery is the new default javascript language in Rails 3.1. This is great, in my opinion. I really like jQuery - so much that I leaned away from Rails 2.x for awhile because of its tight integration with Prototype.

jQuery and Rails are paired by default, but I am also digging into jquery-ujs - an ubobtrusive scripting adapter for jQuery.

Specifically, this means:

  • The ability to use “:remote => true” with Rails form_for and link_to helpers.
  • AJAX updates!
  • The prevention of double form submits.
  • The ability to make POST, PUT, and DELETE requests from hyperlinks.

Sweet! Especially with regard to AJAX updates, and that’s what I’ve been working with recently.

jQuery and Rails 3 AJAX Form Submission and Flash Update

Here’s an example of an AJAX form submission and a response to update the page flash. It requires several components:

  • The form view
  • The controller action
  • The javascript response

The AJAX Form Submission: “:remote => true”

All that’s required for a form to use AJAX is the :remote argument set to true. Here’s an example of a Rails 3 form that is set to submit via AJAX:

    = form_for(Comment.new, :remote => true) do |f|
      = f.hidden_field :commentable_id, :value => resource.id
      = f.hidden_field :commentable_type, :value => resource.class
      = f.label :comment
      %br/
      = f.text_area :comment, :rows => 2
      %br/
      = f.submit "Post Comment"

Using The Rails 3 Controller “respond_to” Method

First I placed this line at the top of my CommentsController:

respond_to :js, :html

Then the create action:

  def create
    params[:comment][:user_id] = current_user || -1
    @comment = Comment.new(params[:comment])
    flash[:notice] = "Comment created. It will need to be approved by a moderator." if @comment.save
    respond_with( @comment, :layout => !request.xhr? )
  end

The ERB Powered Javascript Response

Now comes the jQuery part! I created a create.js.erb file, like this:

<% if @comment.errors.any? %>
<% else %>
  $("#flash_messages").append('<%= escape_javascript(render(:partial => 'flash', :locals => {:flash => flash, :flush_flash => true})) %>');
<% end %>