In a previous post, Rails 3, jQuery & UJS, I talked about how easy Rails has made it to do remote forms or even linking to remote actions. It covered how to set up the basics of a remote form to gather the information and let the user know something is being processed. The only question I didn’t cover is, what happens when a form returns a validation error? It’s as easy as making a generic js.erb file.
Assuming that you already have your UJS working to save the data when everything validates, let’s setup a way to handle when the data does not validate. I will just be covering the example of creation, but this can easily be applied to the update action as well.
Since rails form helpers handle creation of forms the same way no matter what the object is, to reduce code duplication, using the same error handling file goes a long way.
The following is what I typically put into my form error handling js.erb file:
Since Rails holds the messages and object ID’s in separate methods on the object it returns, it is easiest to store these in two separate arrays to call together later using their index.
The next part is crucial to finding and storing the DOM elements on the page that have validation errors. Using the way Rails form helpers place ID’s on the fields (type_object), you can store the exact DOM object into the array. This is of course if you haven’t broken Rails convention in naming your objects.
Next you want to loop through all the error messages and store them in the array.
Now to handle these freshly created arrays and display the errors:
This is a quick example of how to handle the form errors by giving the DOM element a title and adding a class to signify that it’s an error field. I like to use a jQuery plugin called QTip which you can place on the form fields. When the field is then selected, a tooltip pops up with the error message.
Other than that, styling up the form errors is all you have to do. Of course, there are many ways to validate a form before it is even sent to the server, but this is a great fall back method until you have that in place.