Skip to content

Instantly share code, notes, and snippets.

@seyhunak
Created January 23, 2012 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seyhunak/1662697 to your computer and use it in GitHub Desktop.
Save seyhunak/1662697 to your computer and use it in GitHub Desktop.
Another approach to FormBuilder
# app/helpers/main_form.rb
class MainForm < ActionView::Helpers::FormBuilder # NestedForm::Builder
CSS = {
:label => 'label-control',
:hint => 'hint',
:hint_ptr => 'hint-pointer',
:error => 'help-inline',
:field_error => 'error',
:main_class => 'clearfix'
}
FIELDS = %w(radio_button check_box text_field text_area password_field select file_field collection_select email_field date_select)
def main_class(error=nil)
return CSS[:main_class] unless error
[CSS[:main_class], CSS[:field_error]].join(' ')
end
def required(name)
object.class.validators_on(name).map(&:class).include?(ActiveModel::Validations::PresenceValidator) rescue nil
end
def cancel(options={})
link = options.fetch(:return, "/")
@template.content_tag(:a, "Cancel", :href => link, :class => "btn_form button np_cancel_btn #{options[:class]}")
end
def submit(value="Save", options={})
options[:class] = "send_form_btn #{options[:class]}"
super
end
def label_class
{:class => CSS[:label]}
end
def label_tag(attribute, arg)
# Incase its a mandatory field, the '*' is added to the field.
txt = arg[:label] && arg[:label].to_s || attribute.to_s.titleize
txt<< '*' if(arg[:required] || required(attribute)) && arg[:required] != false
label(attribute, txt, label_class)
end
def error_tag(method_name, attribute)
errs = field_error(method_name, attribute)
@template.content_tag(:span, errs.first, :class => CSS[:error]) if errs.present?
end
def field_error(method_name, attribute)
return if @object && @object.errors.blank?
return @object.errors[attribute] if method_name != 'file_field'
@object.errors["#{attribute.to_s}_file_name"] | @object.errors["#{attribute.to_s}_file_size"] | @object.errors["#{attribute.to_s}_content_type"]
end
def hint_tag(txt)
hintPtr = @template.content_tag(:span, '', :class => CSS[:hint_ptr])
hintT = @template.content_tag(:span, txt + hintPtr, {:class => CSS[:hint]}, false)
end
def spinner_tag
@template.image_tag('spinner.gif', :class => :spinner,:id => :spinner)
end
end
cat app/helpers/zero_form.rb
class ZeroForm < MainForm
# Overridden label_class here as we dont need class to be applied
def label_class
{}
end
def self.create_tagged_field(method_name)
define_method(method_name) do |attribute, *args|
arg = args.last && args.last.is_a?(Hash) && args.last || {}
# Bypass form-builder and do your own custom stuff!
return super(attribute, *args) if arg[:skip] && args.last.delete(:skip)
errT = error_tag(method_name, attribute)
labelT = label_tag(attribute, arg)
mainT = super(attribute, *args)
baseT = @template.content_tag(:div, mainT + errT)
hintT = hint_tag(arg[:hint]) if arg[:hint]
spinnerT = spinner_tag if arg[:spinner]
allT = labelT + baseT + spinnerT + hintT
@template.content_tag(:div, allT, :class => main_class(errT))
end
end
FIELDS.each do |name|
create_tagged_field(name)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment