You should look at creating your own form builder to customize the behavior of form_for . You can do something that defines a class for the name of the validations defined in the attribute, and jQuery binds itself to the corresponding class names. Let's start with how the form creator might look.
class ValidationFormBuilder < ActionView::Helpers::FormBuilder def text_field(object_name, method, options = {}) options[:class] = object_name.class.validators_on(method).map do |k| # Eg: ActiveModel::Validations::PresenceValidator -> presence k.to_s.slice(/[^:]+Validator$/).chomp('Validator').downcase end.join(' ') super(object_name, method, options) end end
You need to configure form_for to use ValidationFormBuilder.
<%= form_for @foo, :builder => ValidationFormBuilder do |f| %> <%= f.text_field :bar %> <% end %> ... becomes something like <form action="/foo" method="post"> <input type="text" class="presence" name="foo[bar]" id="foo_bar"> </form>
If you need more flexibility over class names, you can create a hash that displays the desired string.
class ValidationFormBuilder < ActionView::Helpers::FormBuilder MAPPINGS = { ActiveModel::Validations::PresenceValidator => 'text' } def text_field(object_name, method, options = {}) options[:class] = object_name.class.validators_on(method).map do |k| MAPPINGS[k] end.join(' ') super(object_name, method, options) end end
You can see the full list of checks included in Rails by looking at the activemodel/lib/active_model/validations of the Rails source code. I hope this is enough to get you started.
source share