Rails 3 UJS dry client + server validation form

Validating a form with jQuery is as simple as adding a class name to a field. Checking the shape with rails is as simple as setting the conditions for your controller (and / or model).

I believe there should be a way to write checks once and apply them both on the client side and on the server side. I have always been a fan of writing my own javascript, but with the inconvenience of rails3 UJS could be useful here if it can do it.

Thanks!!

+2
source share
4 answers
0
source

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.

+2
source

You can use server side validation using RJS (and it does not depend on the use of UJS or not):

 # create.js.haml = render :partial => "shared/flash_messages", :locals => { :flash => flash } - if @message.errors.any? $('#reply_message').html('#{escape_javascript(render(:partial => "message_form"))}'); - else $('ul.data_grid .list').append('#{escape_javascript(render "message", :message => @message)}'); $('#reply_message textarea').val(''); 
0
source

All Articles