Advanced Rails Studio: Custom Form Builder 7

Posted by Daniel Wanja Fri, 13 Jun 2008 21:42:00 GMT

Custom Form Builder

Use a custom form builder to clean up your html.erb files.

lib/label_form_builder.rb
class LabelFormBuilder < ActionView::Helpers::FormBuilder
  helpers = field_helpers +
            %w{date_select datetime_select time_select} +
            %w{collection_select select country_select time_zone_select} -
            %w{hidden_field label fields_for} # Don't decorate these

  helpers.each do |name|
    define_method(name) do |field, *args|
      options = args.last.is_a?(Hash) ? args.pop : {}
      label = label(field, options[:label], :class => options[:label_clas])
      @template.content_tag(:p, label +'<br/>' + super)  #wrap with a paragraph 
    end
  end
end

Then you can remove all the <p> and label tags from you form.

app/views/users/edit.html.erb
<h1>Editing user</h1>

<% form_for(@user, :builder => LabelFormBuilder) do |f| %>
  <%= f.error_messages %>
    <%= f.text_field :name %>
    <%= f.text_field :address %>
    <%= f.text_area :comment %>
    <%= f.check_box :check %>
    <%= f.submit "Update" %>
<% end %>

<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>

Add this to your application initializer to have all form use this form builder

ActionView::Base.default_form_builder = LabelFormBuilder
Then you can replace
<% form_for(@user, :builder => LabelFormBuilder) do |f| %>
with
<% form_for(@user) do |f| %>

Now the same form with no custom builder was looking like this before.

<h1>Editing user</h1>

<% form_for(@user) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :address %><br />
    <%= f.text_field :address %>
  </p>
  <p>
    <%= f.label :comment %><br />
    <%= f.text_area :comment %>
  </p>
  <p>
    <%= f.label :check %><br />
    <%= f.check_box :check %>
  </p>
  <p>
    <%= f.submit "Update" %>
  </p>
<% end %>

<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>
Comments

Leave a response

  1. k Sat, 14 Jun 2008 00:37:38 GMT

    Thanks!! :)

    I was just gonna implement this tomorrow morning, and now it's just a copy and paste job. ;-)

    Thanks a lot for sharing!

  2. Georg Ledermann Sat, 14 Jun 2008 09:33:52 GMT

    To avoid HTML validation errors you should write in the LabelFormBuilder class:

    label = label(field, options.delete(:label), :class => options.delete(:label_class))

    Beware of the “options.delete”. Otherwise the inputs will have non-valid attributes “label” and “label_class”.

    Now you can write:

    <%= f.text_field :name, :label => 'Surname' %>
  3. Michael Tue, 17 Jun 2008 02:55:08 GMT

    Where is the best place to put the customer form builder class?

  4. Michael Tue, 17 Jun 2008 02:55:14 GMT

    Where is the best place to put the customer form builder class?

  5. Carlo Thu, 19 Jun 2008 13:31:28 GMT

    simply put following line into your environment.rb file:

    config.load_paths += %W( #{RAILS_ROOT}/app/builders )

    and your builder under app/builders

  6. Daniel Cadenas Sun, 06 Jul 2008 19:28:02 GMT

    I think a better place to put it is the helpers directory and you won’t need to load the path.

  7. RaW Mon, 25 Aug 2008 11:57:09 GMT

    You can replace

    options = args.last.is_a?(Hash) ? args.pop : {}

    with predefined Rails method

    options = args.extract_options!

Comments