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 %>
