Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sebthemonster/3917030 to your computer and use it in GitHub Desktop.
Save sebthemonster/3917030 to your computer and use it in GitHub Desktop.
Twitter Bootstrap FormBuilder
# FormBuilder for Ruby on Rails which produces HTML code compatible with Twitter Bootstrap
# horizontal forms styles (see here: http://twitter.github.com/bootstrap/base-css.html#forms)
#
# Features:
# * displays validation errors in-line
# * has custom option - label-text - to override default label text for an input
#
# Requirements:
# By default, Rails will wrap a field with validation error in an ugly div tag that breaks
# the layout. To override this behaviour, add
# config.action_view.field_error_proc = Proc.new do |html_tag, instance|
# "#{html_tag}".html_safe
# end
# to config/application.rb
#
# Sample usage:
# <%= form_for @pet, builder: BootstrapFormBuilder, html: { class: "well form-horizontal" } do |f| %>
# <%= f.text_field :name %>
# <%= f.number_field :age, in: 0..50 %>
# <%= f.collection_select :kind, Pet::KINDS, :to_s, :to_s,
# include_blank: true, label_text: "My pet is a" %>
# <%= f.check_box :bites %>
# <%= f.date_select :birthday, label_text: "Date of birth" %>
# <%= f.file_field :image %>
# <div class="form-actions">
# <%= f.submit "Add pet", class: "btn btn-primary" %>
# </div>
# <% end %>
class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
delegate :content_tag, to: :@template
%w[text_field number_field collection_select check_box date_select file_field].each do |method_name|
define_method(method_name) do |name, *args|
content_tag :div, class: "control-group #{"error" if object.errors[name].any?}" do
label_field(name, *args) + field_div(method_name, name, *args)
end
end
end
private
def errors_span(name)
content_tag :span, class: "help-inline" do
object.errors[name].first if object.errors[name].any?
end
end
def field_div(field, name, *args)
content_tag :div, class: "controls" do
self.class.superclass.instance_method(field).bind(self).call(name, *args) + errors_span(name)
end
end
def label_field(name, *args)
options = args.extract_options!
label(name, options[:label_text], class: "control-label")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment