occasionally useful ruby, ubuntu, etc

24Mar/082

Simple Easy AJAX Form Validation in Rails

I'm using Ruby 1.8 and Rails 2 for this.

Thanks to BigSmoke for both the ActiveResource::Errors hint as well as inspiring me to look for another way.

What this method does is create and populate an error div with the specific error messages that occurred, and then destroy the div when the user submits a valid entry.

You'll need three files: a controller, an rjs, and a partial.

Controller:

The way I have it set up, the controller invokes the same rjs file regardless of success or failure. This minimizes the number of files needed and
isn't too inconvenient. I simply added a @error = true to the branch of the failure, like so.

 

def create
  @myobject = Myobject.new(params[:myobject])
  @myobject.metagame_id = @id
  respond_to do |format|
    if @myobject.save
      flash[:notice] = 'Myobject was successfully created.'
      format.html { redirect_to myobject_url(@myobject) }
      format.xml  { head :created, :location => myobject_url(@myobject) }
      format.js { render :action=> 'create' }
    else
      @error = true
      format.html { render :action => "new" }
      format.xml  { render :xml => @myobject.errors.to_xml }
      format.js { render :action => 'create' }
    end
  end
end

RJS:

This one happens to be named 'create'. I have different behaviors set up for whether error is set or not. A flash variable is used to track the error state. A partial is loaded in each case. Also, I should mention that the id of the remote_form_for this is going in is ajax_create. Pastebin version.

if @error.nil?
 page.insert_html :bottom, 'myobject_container',{:partial=>'myobject_row', :object=>@myobject}
 page.visual_effect :highlight, "myobject_container", :duration=>2
 if flash[:create_form_error]
 	# Cleanup
 	page.remove 'form_error'
 end
else
 # Was there already an error?
 if flash[:create_form_error]
 	# Update old error message
 	page.replace 'form_error', :partial=>'form_error', :object=>@myobject
 else
 	# Create error dialog
 	page.insert_html :top, 'ajax_create', {:partial=>'form_error', :object=>@myobject}
 end	flash[:create_form_error] = true
 page.visual_effect :highlight, 'form_error', :duration=>2
end

Partial:

This partial's filename is _form_error.html.erb. I think its contents are fairly self-explanatory. Pastebin link.

<p id="form_error">There were one or more errors.</p>
 
<ul>
<% form_error.errors.each_full do |msg| %>
	<li><%=msg%></li>
<% end %></ul>

Bonus: CSS

In case you're curious, the CSS I used was this:

#form_error {
  background:pink;
  border:4px solid red;
  padding:4px;
  margin:2px;
}

Hope this helps. If you found it useful, noticed something I left out, or would like to comment for any reason, please do! At least to inspire me to do future tutorials.

Comments (2) Trackbacks (0)
  1. This was very helpful. It’s the cleanest way I’ve seen to do error validation on custom remote forms. For some reason, the error messages are being added on the page if I post multiple errors, but I’m going over the code to see if I messed something up.

  2. Make sure you got that “flash[:create_form_error] = true” line. For some reason that’s not on its own line.


Leave a comment


No trackbacks yet.