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.
January 21st, 2009 - 15:36
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.
January 22nd, 2009 - 18:48
Make sure you got that “flash[:create_form_error] = true” line. For some reason that’s not on its own line.