Class: Formula::FormBuilder

Inherits:
ActionView::Helpers::FormBuilder
  • Object
show all
Defined in:
lib/formula/form_builder.rb

Instance Method Summary collapse

Instance Method Details

#association(method, collection, value, text, options = {}) ⇒ Object

Generate a suitable form association for a given method by performing introspection on the type.

Options:

  • :label - override the default label used (‘Name:’, ‘URL:’, etc.)

  • :error - override the default error used (‘invalid’, ‘incorrect’, etc.)

  • :association - add custom options to the input ({ class: ‘goregous’ }, etc.)

  • :container - add custom options to the container ({ class: ‘gorgeous’ }, etc.)

Usage:

f.association(:category, Category.all, :id, :name, hint: "What do you do?")
f.association(:category, Category.all, :id, :name, association: { prompt: "Category?" })
f.association(:category, Category.all, :id, :name, association: { html: { class: "category" } })

Equivalent:

<div>
  <div class="association category">
    <%= f.label(:category)
    <div class="association">
      <%= f.collection_select(:category, Category.all, :id, :name) %>
    </div>
    <div class="hint">What do you do?</div>
    <div class="error">...</div>
  </div>
</div>
<div>
  <div class="association category">
    <%= f.label(:category)
    <div class="association">
      <%= f.collection_select(:category, Category.all, :id, :name, { prompt: "Category") } %>
    </div>
    <div class="error">...</div>
  </div>
</div>
<div>
  <div class="association category">
    <%= f.label(:category)
    <div class="association">
      <%= f.collection_select(:category, Category.all, :id, :name, {}, { class: "category" } %>
    </div>
    <div class="error">...</div>
  </div>
</div>


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/formula/form_builder.rb', line 206

def association(method, collection, value, text, options = {})
  options[:as] ||= :select
  options[:association] ||= {}

  klass = [config.association_class, options[:as]]
  klass << config.association_error_class if config.association_error_class.present? and error?(method)

  block(method, options) do
    @template.(config.association_tag, class: klass) do
      case options[:as]
      when :select then collection_select :"#{method}_id", collection, value, text,
                                          options[:association], options[:association].delete(:html) || {}
      end
    end
  end
end

#block(method = nil, options = {}) ⇒ Object

Basic container generator for use with blocks.

Options:

  • :hint - specify a hint to be displayed (‘We promise not to spam you.’, etc.)

  • :label - override the default label used (‘Name:’, ‘URL:’, etc.)

  • :error - override the default error used (‘invalid’, ‘incorrect’, etc.)

Usage:

f.block(:name, label: "Name:", hint: "Please use your full name.", container: { class: 'fill' }) do
  ...
end

Equivalent:

<div class='block fill'>
  <%= f.label(:name, "Name:") %>
  ...
  <div class="hint">Please use your full name.</div>
  <div class="error">...</div>
</div>


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/formula/form_builder.rb', line 54

def block(method = nil, options = {}, &)
  options[:error] ||= error(method) if method

  components = ''.html_safe

  components << label(method, options[:label], config.label_options) if method

  components << @template.capture(&)

  options[:container] ||= {}
  options[:container][:class] = arrayorize(options[:container][:class]) << config.block_class << method
  options[:container][:class] << config.block_error_class if config.block_error_class.present? and error?(method)

  if options[:hint]
    components << @template.(config.hint_tag, options[:hint],
                                        class: config.hint_class)
  end
  if options[:error]
    components << @template.(config.error_tag, options[:error],
                                        class: config.error_class)
  end

  @template.(config.block_tag, options[:container]) do
    components
  end
end

#button(value = nil, options = {}) ⇒ Object

Generate a form button.

Options:

  • :container - add custom options to the container

  • :button - add custom options to the button

Usage:

f.button(:name)

Equivalent:

<div class="block">
  <%= f.submit("Save")
</div>


21
22
23
24
25
26
27
28
29
30
# File 'lib/formula/form_builder.rb', line 21

def button(value = nil, options = {})
  options[:button] ||= {}

  options[:container] ||= {}
  options[:container][:class] = arrayorize(options[:container][:class]) << config.block_class

  @template.(config.block_tag, options[:container]) do
    submit value, options[:button]
  end
end

#formula_fields_for(record_or_name_or_array, *args) ⇒ Object Also known as: fieldsula_for

Generates a wrapper around fields_form with :builder set to FormBuilder.

Supports:

  • f.formula_fields_for(@user.company)

  • f.fieldsula_for(@user.company)

Equivalent:

  • f.fields_for(@user.company, builder: Formula::FormBuilder))

Usage:

<% f.formula_fields_for(@user.company) do |company_f| %>
  <%= company_f.input :url %>
  <%= company_f.input :phone %>
<% end %>


343
344
345
346
347
# File 'lib/formula/form_builder.rb', line 343

def formula_fields_for(record_or_name_or_array, *args, &)
  options = args.extract_options!
  options[:builder] ||= self.class
  fields_for(record_or_name_or_array, *(args << options), &)
end

#input(method, options = {}) ⇒ Object

Generate a suitable form input for a given method by performing introspection on the type.

Options:

  • :as - override the default type used (:url, :email, :phone, :password, :number, :text)

  • :label - override the default label used (‘Name:’, ‘URL:’, etc.)

  • :error - override the default error used (‘invalid’, ‘incorrect’, etc.)

  • :input - add custom options to the input ({ class: ‘goregous’ }, etc.)

  • :container - add custom options to the container ({ class: ‘gorgeous’ }, etc.)

Usage:

f.input(:name)
f.input(:email)
f.input(:password_a, label: "Password", hint: "It's a secret!", container: { class: "half" })
f.input(:password_b, label: "Password", hint: "It's a secret!", container: { class: "half" })

Equivalent:

<div class="block name">
  <%= f.label(:name)
  <div class="input string"><%= f.text_field(:name)</div>
   <div class="error">...</div>
</div>
<div class="block email">
  <%= f.label(:email)
  <div class="input string"><%= f.email_field(:email)</div>
   <div class="error">...</div>
</div>
<div class="block half password_a">
  <div class="input">
    <%= f.label(:password_a, "Password")
    <%= f.password_field(:password_a)
    <div class="hint">It's a secret!</div>
    <div class="error">...</div>
  </div>
</div>
<div class="block half password_b">
  <div class="input">
    <%= f.label(:password_b, "Password")
    <%= f.password_field(:password_b)
    <div class="hint">It's a secret!</div>
    <div class="error">...</div>
  </div>
</div>


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/formula/form_builder.rb', line 126

def input(method, options = {})
  options[:as] ||= as(method)
  options[:input] ||= {}

  return hidden_field method, options[:input] if options[:as] == :hidden

  klass = [config.input_class, options[:as]]
  klass << config.input_error_class if config.input_error_class.present? and error?(method)

  block(method, options) do
    @template.(config.input_tag, class: klass) do
      case options[:as]
      when :text     then text_area       method, config.area_options.merge(options[:input] || {})
      when :file     then file_field      method, config.file_options.merge(options[:input] || {})
      when :string   then text_field      method, config.field_options.merge(options[:input] || {})
      when :password then password_field  method, config.field_options.merge(options[:input] || {})
      when :url      then url_field       method, config.field_options.merge(options[:input] || {})
      when :email    then email_field     method, config.field_options.merge(options[:input] || {})
      when :phone    then phone_field     method, config.field_options.merge(options[:input] || {})
      when :number   then number_field    method, config.field_options.merge(options[:input] || {})
      when :boolean  then check_box       method, config.box_options.merge(options[:input] || {})
      when :country  then country_select  method, config.select_options.merge(options[:input] || {})
      when :date     then date_select     method, config.select_options.merge(options[:input] || {}),
                                          options[:input].delete(:html) || {}
      when :time     then time_select     method, config.select_options.merge(options[:input] || {}),
                                          options[:input].delete(:html) || {}
      when :datetime then datetime_select method, config.select_options.merge(options[:input] || {}),
                                          options[:input].delete(:html) || {}
      when :select   then select          method, options[:choices],
                                          config.select_options.merge(options[:input] || {}), options[:input].delete(:html) || {}
      end
    end
  end
end