Better error_messages_for (I)
Posted by Jorge Bernal November 27, 2006
What is error_messages_for?
Rails validation system is definitely a time saver. For those of you who don’t know it, let’s say you define validations in a model like this
class User < ActiveRecord::Base
validates_presence_of :name, :email, :password,
n => :create
validates_uniqueness_of :email, :name
# ... rest of model code here ...
end
and if you fail to enter data correctly this is what you get

error_messages_for is the helper used in the views to show the warning box.
The enhancement
I thought it would be nice to have the first field with an error not only shown in red but focused so you can fix the error right away.
To make this happen you can add the following code to config/environment.rb
module ActionView
module Helpers
module ActiveRecordHelper
alias_method :error_messages_for_original, :error_messages_for
def error_messages_for(*params)
options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
error_text = error_messages_for_original(params)
if error_text.empty?
error_text
else
# Add JS tag to focus on first error
first_attr = nil
objects.first.errors.each {|attr,msg| first_attr ||= attr}
error_text + javascript_tag("window.onload = function () {$('#{params.first}_#{first_attr}').focus();}")
end
end
end
end
end
Caveats
This is far from being perfect (that’s why you should expect a second part article on this one). The caveat is using the window.onload attribute. It’s needed because you can’t modify a DOM object before it exists.
The next approach will be modifying directly the form helpers, so the JS code to focus the first field with an error will go just after the INPUT tag.
