The Rails wiki has some examples of custom highlighting methods, one of which involves using regular expressions to add a style to error fields, like this:
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
msg = instance.error_message
error_style = "background-color: #f2afaf"
if html_tag =~ /<(input|textarea|select)[^>]+style=/
style_attribute = html_tag =~ /style=['"]/
html_tag.insert(style_attribute + 7, "#{error_style}; ")
elsif html_tag =~ /<(input|textarea|select)/
first_whitespace = html_tag =~ /\s/
html_tag[first_whitespace] = " style='#{error_style}' "
end
html_tag
end
There are a few problems with this approach:
- It doesn’t apply the style to label elements but does to hidden input fields.
- It can lead to the error style being added twice (for example if you use the datetime select helpers)
For a project I’m working on I wanted to add a CSS class of error to my form fields (including labels) and wanted to do it in a nicer way. Here’s what I came up with:
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
if html_tag =~ /<(input|label|textarea|select)/
error_class = 'error'
nodes = Hpricot(html_tag)
nodes.each_child { |node| node[:class] = node.classes.push(error_class).join(' ') unless !node.elem? || node[:type] == 'hidden' || node.classes.include?(error_class) }
nodes.to_html
else
html_tag
end
end
And here’s an example of the output:
<div>
<label class="error" for="user_email">Email</label>
<input name="user[email]" size="30" class="error" type="text" id="user_email" value="" />
</div>
To add the class I’ve used why’s super-speedy Hpricot HTML parser and, to me at least, this looks far nicer than regular expressions and string inserts (although one regular expression remains to skip the tag if it doesn’t need any further processing). It even checks to make sure the error class isn’t added twice.
Using an HTML parser may seem like overkill but a quick benchmark shows it takes less than 0.01 of a second to do its thing: for me the cleaner looking code and the ability to easily manipulate the HTML element using Hpricot makes this a worthwhile approach.


2 comments
Comment on Error fields with a Hpricot twist by Kent Fenwick
November 10th, 2008 @ 07:30 – permalink
Comment on Error fields with a Hpricot twist by James Bebbington
October 14th, 2009 @ 23:21 – permalink
Leave a reply
You can use Markdown in your comment as well as plain HTML. You can use
<filter:jscode lang="ruby">and</filter:jscode>tags to surround code blocks (supported languages are css, html, javascript and ruby). Your email address will not be published.If your comment doesn’t appear immediately after posting it could have been marked as spam. Don’t worry: we regularly check for and approve incorrectly filtered comments so you shouldn’t have to wait too long for it to be shown.