class Padrino::Helpers::FormBuilder::AbstractFormBuilder

Base class for Padrino Form Builder

Attributes

attributes_name[R]
is_nested[R]
model_name[R]
multipart[RW]
namespace[R]
nested_index[R]
object[RW]
parent_form[R]
template[RW]

Public Class Methods

new(template, object, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 13
def initialize(template, object, options={})
  @template = template
  fail "FormBuilder template must be initialized" unless template
  @object = object.kind_of?(Symbol) ? build_object(object) : object
  fail "FormBuilder object must be present. If there's no object, use a symbol instead (i.e. :user)" unless object
  @options = options
  @namespace = options[:namespace]
  @model_name = options[:as] || @object.class.to_s.underscore.gsub(/\//, '_')
  nested = options[:nested]
  if @is_nested = nested && (nested_parent = nested[:parent]) && nested_parent.respond_to?(:object)
    @parent_form = nested_parent
    @nested_index = nested[:index]
    @attributes_name = "#{nested[:association]}_attributes"
  end
end

Protected Class Methods

field_types() click to toggle source

Returns the known field types for a Formbuilder.

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 149
def self.field_types
  [:hidden_field, :text_field, :text_area, :password_field, :file_field, :radio_button, :check_box, :select]
end

Public Instance Methods

check_box(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 96
def check_box(field, options={})
  options = default_options(field, options, :value => '1')
  options[:checked] = true if is_checked?(field, options)
  name = field_name(field)
  html = @template.hidden_field_tag(name, :value => options.delete(:uncheck_value) || '0')
  html << @template.check_box_tag(name, options)
end
check_box_group(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 84
def check_box_group(field, options={})
  labeled_group(field, options) do |attributes|
    @template.check_box_tag(field_name(field)+'[]', attributes)
  end
end
csrf_token_field() click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 142
def csrf_token_field
  @template.csrf_token_field
end
email_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 60
def email_field(field, options={})
  @template.email_field_tag field_name(field), default_options(field, options)
end
error_message_on(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 33
def error_message_on(field, options={})
  @template.error_message_on object, field, options
end
error_messages(*params) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 29
def error_messages(*params)
  @template.error_messages_for object, *params
end
fields_for(child_association, collection=nil, options={}, &block) click to toggle source

Supports nested fields for a child model within a form. f.fields_for :addresses f.fields_for :addresses, address f.fields_for :addresses, @addresses f.fields_for :addresses, address, index: i

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 130
def fields_for(child_association, collection=nil, options={}, &block)
  default_collection = self.object.send(child_association)
  collection ||= default_collection
  include_index = default_collection.respond_to?(:each)

  nested_options = { :parent => self, :association => child_association }
  Array(collection).each_with_index.inject(ActiveSupport::SafeBuffer.new) do |all,(child_instance,index)|
    nested_options[:index] = options[:index] || (include_index ? index : nil)
    all << @template.fields_for(child_instance,  { :nested => nested_options, :builder => self.class }, &block) << "\n"
  end
end
file_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 111
def file_field(field, options={})
  self.multipart = true
  @template.file_field_tag field_name(field), default_options(field, options).except(:value)
end
hidden_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 43
def hidden_field(field, options={})
  @template.hidden_field_tag field_name(field), default_options(field, options)
end
image_submit(source, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 120
def image_submit(source, options={})
  @template.image_submit_tag source, options
end
label(field, options={}, &block) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 37
def label(field, options={}, &block)
  options[:id] ||= nil
  options[:caption] ||= I18n.t("#{model_name}.attributes.#{field}", :count => 1, :default => field.to_s.humanize, :scope => :models) + ': '
  @template.label_tag(field_id(field), default_options(field, options), &block)
end
number_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 51
def number_field(field, options={})
  @template.number_field_tag field_name(field), default_options(field, options)
end
password_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 76
def password_field(field, options={})
  @template.password_field_tag field_name(field), default_options(field, options)
end
phone_field(field, options={})
Alias for: telephone_field
radio_button(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 104
def radio_button(field, options={})
  options = default_options(field, options)
  options[:checked] = true if is_checked?(field, options)
  options[:id] = field_id(field, options[:value])
  @template.radio_button_tag field_name(field), options
end
radio_button_group(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 90
def radio_button_group(field, options={})
  labeled_group(field, options) do |attributes|
    @template.radio_button_tag(field_name(field), attributes)
  end
end
search_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 64
def search_field(field, options={})
  @template.search_field_tag field_name(field), default_options(field, options)
end
select(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 80
def select(field, options={})
  @template.select_tag field_name(field), default_options(field, options)
end
submit(*args) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 116
def submit(*args)
  @template.submit_tag *args
end
telephone_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 55
def telephone_field(field, options={})
  @template.telephone_field_tag field_name(field), default_options(field, options)
end
Also aliased as: phone_field
text_area(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 72
def text_area(field, options={})
  @template.text_area_tag field_name(field), default_options(field, options)
end
text_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 47
def text_field(field, options={})
  @template.text_field_tag field_name(field), default_options(field, options)
end
url_field(field, options={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 68
def url_field(field, options={})
  @template.url_field_tag field_name(field), default_options(field, options)
end

Protected Instance Methods

build_object(symbol) click to toggle source

Returns a record from template instance or create a record of specified class.

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 195
def build_object(symbol)
  @template.instance_variable_get("@#{symbol}") || symbol.to_s.camelize.constantize.new
end
field_id(field=nil, value=nil) click to toggle source

Returns the id for the given field. field_id(:username) => “user_username” field_id(:gender, :male) => “user_gender_male” field_name(:number) => “user_telephone_attributes_number” field_name(:street) => “user_addresses_attributes_0_street”

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 170
def field_id(field=nil, value=nil)
  result = (namespace && !is_nested) ? "#{namespace}_" : ''
  result << field_id_fragment
  result << "_#{field}" unless field.blank?
  result << "_#{value}" unless value.blank?
  result
end
field_name(field=nil) click to toggle source

Returns the name for the given field. field_name(:username) => “userfield_name(:number) => “user[number]” field_name(:street) => “user[0]

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 158
def field_name(field=nil)
  result = field_name_fragment
  result << "[#{field}]" unless field.blank?
  result
end
field_value(field) click to toggle source

Returns the value for the object’s field.

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 188
def field_value(field)
  @object.respond_to?(field) ? @object.send(field) : ''
end
labeled_group(field, options={}) { |attributes| ... } click to toggle source

Builds a group of labels for radios or checkboxes.

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 202
def labeled_group(field, options={})
  options = { :id => field_id(field), :selected => field_value(field) }.update(options)
  options.update(error_class(field)){ |_,*values| values.compact.join(' ') }
  selected_values = resolve_checked_values(field, options)
  variants_for_group(options).inject(ActiveSupport::SafeBuffer.new) do |html, (caption,value)|
    variant_id = "#{options[:id]}_#{value}"
    attributes = { :value => value, :id => variant_id, :checked => selected_values.include?(value) }
    caption = yield(attributes) << ' ' << caption
    html << @template.label_tag("#{field_name(field)}[]", :for => variant_id, :caption => caption)
  end
end
nested_object_id() click to toggle source

Returns the child object if it exists.

# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 181
def nested_object_id
  is_nested && object.respond_to?(:new_record?) && !object.new_record? && object.id
end

Private Instance Methods

default_options(field, options, defaults={}) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 275
def default_options(field, options, defaults={})
  { :value => field_value(field),
    :id => field_id(field)
  }.update(defaults).update(options).update(error_class(field)){ |_,*values| values.compact.join(' ') }
end
error_class(field) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 270
def error_class(field)
  error = @object.errors[field] if @object.respond_to?(:errors)
  error.blank? ? {} : { :class => 'invalid' }
end
field_id_fragment() click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 260
def field_id_fragment
  if is_nested
    fragment = parent_form.field_id.dup << "_#{attributes_name}"
    fragment << "_#{nested_index}" if nested_index
    fragment
  else
    "#{model_name}"
  end
end
field_methods(options) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 242
def field_methods(options)
  options[:fields] || [:name, :id]
end
field_name_fragment() click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 250
def field_name_fragment
  if is_nested
    fragment = parent_form.field_name.dup << "[#{attributes_name}"
    fragment << "][#{nested_index}" if nested_index
    fragment << "]"
  else
    "#{model_name}"
  end
end
field_values(object, options) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 246
def field_values(object, options)
  field_methods(options).map{ |field| object.send(field).to_s }
end
is_checked?(field, options) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 216
def is_checked?(field, options)
  !options.has_key?(:checked) && [options[:value].to_s, 'true'].include?(field_value(field).to_s)
end
resolve_checked_values(field, options) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 230
def resolve_checked_values(field, options)
  selected_values = Array(options[:selected] || field_value(field))
  if options[:collection]
    _, id_method = *field_methods(options)
    selected_values.map do |value|
      (value.respond_to?(id_method) ? value.send(id_method) : value).to_s
    end
  else
    selected_values
  end
end
variants_for_group(options) click to toggle source
# File lib/padrino-helpers/form_builder/abstract_form_builder.rb, line 220
def variants_for_group(options)
  if variants = options[:options]
    variants.map{ |caption, value| [caption.to_s, (value||caption).to_s] }
  elsif collection = options[:collection]
    collection.map{ |variant| field_values(variant, options) }
  else
    []
  end
end