Timothy Payton

Timothy Payton on 27.10.2009 at 16:55h CET

There are many html forms on XING – when you sign up, when you write a message, or when you discuss in a group. We do most of our form validations on the server side. This allows us to apply complex validations, prevents code duplication, and apply security checks.

This works well – you define the requirements for the specific field (such as <input>) and Rails returns the page with an error message, also highlighting the corresponding field in red. Sounds good, but that’s actually where the problem is. Rails surrounds the field with a <div> that is styled via CSS.

This additional <div> may lead to CSS problems especially in pixel-precise layouts such as the XING html forms, it may break the HTML structure – and it will add completely unneeded DOM complexity.

Changing how Rails handles fields with errors

The technical details of how we solved it follow. We were not the first ones to encounter this problem, inquirylabs also talked about (and solved) it in their blog post Highlight background of fields with errors. The basic idea is rather simple: We rewrote the method Rails uses to handle form field errors to create cleaner html. The best solution we can think of is to add a class directly to the error elements, and that class has styling to border the error fields in red. No added DOM elements, no more broken structure, just clean code.

Here is the default rails html output

<div class="fieldWithErrors">
<input />Test</div>

Here is what our changes output

<input class="input-error" />Test

Luckily, Rails already provides a simple entry point for cleaning things up. In active_record_helper.rb in the actionpack gem, there is a class variable defined @@field_error_proc, which can be redefined to apply custom error handling on the html input fields. We’ve uploaded the code to github: http://github.com/xing/classy_field_errors.

It’s a plugin, so just:

  • script/plugin install git://github.com/xing/classy_field_errors.git
  • Put the css contained in field_error_proc.css in your base css file

The method we call inside the block, does exactly what we want. You pass it an element and a css class. It then applies that css class to input, textarea, or select elements, either adding the class to the existing classes or adding a class attribute to the element.

The method itself just calls the HtmlElement class method add_css_class which does what you’d think it does: It instantiates an HtmlElement object, adds the class passed into the elements and returns the changed html_element (which is really a string).

So, with the added class, we can do the same error highlighting, but without any added DOM complexity and with the intended semantic separation of HTML for content and CSS for styling.

Our solution produces the same basic results as inquirylabs, but also took care of 2 edge cases:

  • it only adds the CSS class if the element doesn’t have it already, so in the rare case that an input field has two errors, the code remains clean
  • the code also works with self-closing <input/> tags

Thanks to Ladislav Martincik, Sebastian Roebke, Mark Schuette and Hendrik Mans who all contributed to making this code highly efficient and clean.


4
Comments
Leave a comment
Tim Connor on 28.10.2009 at 19:13h CET

cleanly. clean is an adjective

Tim Connor on 28.10.2009 at 19:16h CET

Also, I’m pretty sure this was in there because of lack of browser support for styling inputs. It might be removable now with older IE’s getting less common, but you will want to check this against the full range of browsers you care about, for all types of form fields (select and checkbox/radio-button tend to be the problematic ones)

Timothy Payton on 29.10.2009 at 10:37h CET

@Tim: Thanks for the feedback and input. I hope you enjoyed the post. Good point about checking it in different browsers. For us, it was more important to not get the added DOM elements. If you have any improvements, we would be happy to add them to the plugin, just fork us on github :)

Timothy Patrick Connor on 29.10.2009 at 17:26h CET

Of course I enjoyed it, I commented on it didn’t I? ;)

I totally understand. Just explaining the reasons I can remember for the crappy seeming mark-up addition (though they really could have made it an inline element, like a span, by default :( ). The real issue with the styling of some elements being problematic is that means browsers that don’t support it then can get absolutely *no* feedback around the field, which is a pretty bad user experience, comparatively, and I can understand why they wouldn’t want that to be the default behavior.

If for your user base screwing a set of users in exchange for academic superiority is a good trade off…. I’m kidding, I’m kidding! I honestly don’t remember which browsers were problematic, so if it’s even a real issue anymore. I suppose if one really wanted the least messed up html and the best user experience there could be a damn browser detect and output an wrapper when needed, but that’s just more css maintenance then, so it’s a bit of a trade-off.

I’ve always tweaked the output to not put a damn wrapper around the hidden input and done he rest in css, and that’s proven sufficient, but your solution, of course, handles that automatically.

RSS-Feeds RSS feed for comments on this post.

Leave a comment

If you have a Word Press Account, please sign in