Advanced Rails Studio: Custom Form Builder

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 theseclass 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 %>

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


Comments

  1. k about 3 hours later:

    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 about 12 hours later:

    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 3 days later:

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

  4. Michael 3 days later:

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

  5. Carlo 6 days later:

    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 23 days later:

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

  7. RaW 2 months later:

    You can replace

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

    with predefined Rails method

    @options = args.extract_options! @

  8. feh 6 months later:

    I’m getting “stack level too deep” errors. Is anyone else seeing this, and have a solution to it?

  9. Douglas 6 months later:

    Works for me in edge rails (2.3.0). I followed @Carlo and made a builder folder and added to environment.rb.

  10. Lewis Hoffman 7 months later:

    Thanks, Daniel. hit the spot! :)

  11. KnickLack 7 months later:

    gerfried, the link you posted doesn’t work, but i installed the gem and the official link is:
    http://intra.wortundform.de/aurita-gui
    according to the readme included.
    And yes, it’s awesome! :)
    Different way of handling forms and HTML GUI in ruby, but the best way from a GUI perspective. Why not handling forms as objects in an OO language?!

  12. Andrea 10 months later:

    With this form builder i have problems with internet explorer. The from builder work fine, but if i have select tags, when i load or refresh the pages the label get “hidden” or not displayed.
    Someone know a workaround?

  13. Seth Thomas Rasmussen 12 months later:

    Hey, nice job!

    I have a similar plugin with what I think are some improvements to the API. It still has room for improvement, though, so I’d love any feedback anyone has.

    http://github.com/greatseth/labeling-form-helper