formula 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.rdoc +22 -10
  2. data/lib/formula.rb +168 -31
  3. metadata +2 -2
@@ -8,19 +8,31 @@ Formula is a Rails form generator that generates simple clean markup. The projec
8
8
 
9
9
  == Examples
10
10
 
11
- <%= f.input :email %>
12
- <%= f.input :password %>
11
+ <% formula_form_for @user do |f| %>
12
+ <%= f.input :email %>
13
+ <%= f.input :password %>
14
+ <% end %>
13
15
 
14
- <%= f.input :email, :label => "Email:", :hint => "We promise never to bother you." %>
15
- <%= f.input :password, :label => "Password:", :hint => "Must be at least six characters." %>
16
+ <% formula_form_for @user do |f| %>
17
+ <%= f.input :email, :label => "Email:", :hint => "We promise never to bother you." %>
18
+ <%= f.input :password, :label => "Password:", :hint => "Must be at least six characters." %>
19
+ <% end %>
16
20
 
17
- <%= f.input :url, :class => 'grid-04' %>
18
- <%= f.input :phone, :class => 'grid-04' %>
19
- <%= f.input :email, :class => 'grid-04' %>
21
+ <% formula_form_for @company do |f|
22
+ <%= f.input :url, :class => 'grid-04' %>
23
+ <%= f.input :phone, :class => 'grid-04' %>
24
+ <%= f.input :email, :class => 'grid-04' %>
25
+ <% end %>
20
26
 
21
- <%= f.input :credit_card_number, :label => 'Number:', :class => 'grid-08' %>
22
- <%= f.input :credit_card_verification, :label => 'CVV:', :class => 'grid-02' %>
23
- <%= f.input :credit_card_expiration, :label => 'Expiration:', :class => 'grid-02' %>
27
+ <% formula_form_for @user do |f| %>
28
+ <%= f.input :email, :label => "Email:", :class => 'grid-06 %>
29
+ <%= f.input :password, :label => "Password:", :class => 'grid-06' %>
30
+ <% formula_fields_for @user.payment do |payment_f| %>
31
+ <%= f.input :credit_card_number, :label => 'Number:', :class => 'grid-08' %>
32
+ <%= f.input :credit_card_verification, :label => 'CVV:', :class => 'grid-02' %>
33
+ <%= f.input :credit_card_expiration, :label => 'Expiration:', :class => 'grid-02' %>
34
+ <% end %>
35
+ <% end %>
24
36
 
25
37
  == Copyright
26
38
 
@@ -6,6 +6,10 @@ module Formula
6
6
  mattr_accessor :input_class
7
7
  @@input_class = 'input'
8
8
 
9
+ # Default class assigned to input (<div class="association">...</div>).
10
+ mattr_accessor :association_class
11
+ @@association_class = 'association'
12
+
9
13
  # Default class assigned to error (<div class="error">...</div>).
10
14
  mattr_accessor :error_class
11
15
  @@error_class = 'error'
@@ -18,6 +22,10 @@ module Formula
18
22
  mattr_accessor :input_tag
19
23
  @@input_tag = :div
20
24
 
25
+ # Default tag assigned to input (<div class="association">...</div>).
26
+ mattr_accessor :association_tag
27
+ @@association_tag = :div
28
+
21
29
  # Default tag assigned to error (<div class="error">...</div>).
22
30
  mattr_accessor :error_tag
23
31
  @@error_tag = :div
@@ -41,42 +49,112 @@ module Formula
41
49
  class FormulaFormBuilder < ActionView::Helpers::FormBuilder
42
50
 
43
51
 
44
- # Generate a suitable form input for a given method by performing introspection on the type.
52
+ # Basic container generator for use with blocks.
45
53
  #
46
54
  # Options:
47
55
  #
48
- # * :as - override the default type used (:url, :email, :phone, :password, :number, :text)
49
- # * :label - override the default label used ('Name:', 'URL:', etc.)
50
- # * :error - override the default error used ('invalid', 'incorrect', etc.)
51
- # * :class - add custom classes to the container ('grid-04', 'grid-08', etc.)
56
+ # * :hint - specify a hint to be displayed ('We promise not to spam you.', etc.)
57
+ # * :label - override the default label used ('Name:', 'URL:', etc.)
58
+ # * :error - override the default error used ('invalid', 'incorrect', etc.)
59
+ #
60
+ # Usage:
61
+ #
62
+ # f.block(:name, :label => "Name:", :hint => "Please use your full name.", :container => { :class => 'fill' }) do
63
+ # ...
64
+ # end
65
+ #
66
+ # Equivalent:
67
+ #
68
+ # <div class='fill'>
69
+ # <%= f.label(:name, "Name:") %>
70
+ # ...
71
+ # <div class="hint">Please use your full name.</div>
72
+ # <div class="error"></div>
73
+ # </div>
52
74
 
53
- def input(method, options = {})
54
- options[:as] ||= as(method, options)
55
- options[:error] ||= error(method, options)
75
+ def block(method, options = {}, &block)
76
+ options[:error] ||= error(method)
56
77
 
57
78
  components = []
58
79
 
59
80
  components << self.label(method, options[:label])
60
81
 
61
- case options[:as]
62
- when :text then components << self.text_area(method)
63
- when :string then components << self.text_field(method)
64
- when :password then components << self.password_field(method)
65
- when :url then components << self.url_field(method)
66
- when :email then components << self.email_field(method)
67
- when :phone then components << self.phone_field(method)
68
- when :number then components << self.number_field(method)
69
- when :date then components << self.date_select(method)
70
- when :time then components << self.time_select(method)
71
- when :datetime then components << self.datetime_select(method)
72
- end
82
+ components << @template.capture(&block)
73
83
 
74
84
  components << @template.content_tag(::Formula.hint_tag, options[:hint], :class => ::Formula.hint_class) if options[:hint]
75
85
  components << @template.content_tag(::Formula.error_tag, options[:error], :class => ::Formula.error_class) if options[:error]
76
86
 
77
- @template.content_tag(:div, :class => options[:class]) do
78
- @template.content_tag(::Formula.input_tag, :class => ::Formula.input_class) do
79
- components.join
87
+ @template.content_tag(:div, options[:container]) do
88
+ components.join
89
+ end
90
+ end
91
+
92
+
93
+ # Generate a suitable form input for a given method by performing introspection on the type.
94
+ #
95
+ # Options:
96
+ #
97
+ # * :as - override the default type used (:url, :email, :phone, :password, :number, :text)
98
+ # * :label - override the default label used ('Name:', 'URL:', etc.)
99
+ # * :error - override the default error used ('invalid', 'incorrect', etc.)
100
+ # * :input - add custom options to the input ({ :class => 'goregous' }, etc.)
101
+ # * :container - add custom options to the container ({ :class => 'gorgeous' }, etc.)
102
+ # * :collection -
103
+ #
104
+ # Usage:
105
+ #
106
+ # f.input(:name)
107
+ # f.input(:email)
108
+ # f.input(:password_a, :label => "Password", :hint => "It's a secret!", :container => { :class => "half" })
109
+ # f.input(:password_b, :label => "Password", :hint => "It's a secret!", :container => { :class => "half" })
110
+ #
111
+ # Equivalent:
112
+ #
113
+ # <div>
114
+ # <div class="input">
115
+ # <%= f.label(:name)
116
+ # <%= f.text_field(:name)
117
+ # </div>
118
+ # </div>
119
+ # <div>
120
+ # <div class="input">
121
+ # <%= f.label(:email)
122
+ # <%= f.email_field(:email)
123
+ # </div>
124
+ # </div>
125
+ # <div class="half">
126
+ # <div class="input">
127
+ # <%= f.label(:password_a, "Password")
128
+ # <%= f.password_field(:password_a)
129
+ # <div class="hint">It's a secret!</div>
130
+ # </div>
131
+ # </div>
132
+ # <div class="half">
133
+ # <div class="input">
134
+ # <%= f.label(:password_b, "Password")
135
+ # <%= f.password_field(:password_b)
136
+ # <div class="hint">It's a secret!</div>
137
+ # </div>
138
+ # </div>
139
+
140
+ def input(method, options = {})
141
+ options[:as] ||= as(method)
142
+
143
+ self.block(method, options) do
144
+ case options[:as]
145
+ when :text then text_area(method)
146
+
147
+ when :string then text_field(method)
148
+ when :password then password_field(method)
149
+
150
+ when :url then url_field(method)
151
+ when :email then email_field(method)
152
+ when :phone then phone_field(method)
153
+ when :number then number_field(method)
154
+
155
+ when :date then date_select(method)
156
+ when :time then time_select(method)
157
+ when :datetime then datetime_select(method)
80
158
  end
81
159
  end
82
160
  end
@@ -92,11 +170,28 @@ module Formula
92
170
  # * :class - add custom classes to the container ('grid-04', 'grid-08', etc.)
93
171
 
94
172
  def association(method, options = {}, &block)
173
+ self.block(method, options) do
174
+ end
95
175
  end
96
176
 
97
177
 
98
178
  private
99
-
179
+
180
+
181
+ # Introspection on the column to determine how to render a method. The method is used to
182
+ # identify a method type (if the method corresponds to a column)
183
+ #
184
+ # Returns:
185
+ #
186
+ # * :text - for columns of type 'text'
187
+ # * :string - for columns of type 'string'
188
+ # * :integer - for columns of type 'integer'
189
+ # * :float - for columns of type 'float'
190
+ # * :decimal - for columns of type 'decimal'
191
+ # * :datetime - for columns of type 'datetime'
192
+ # * :date - for columns of type 'date'
193
+ # * :time - for columns of type 'time'
194
+ # * nil - for unkown columns
100
195
 
101
196
  def type(method)
102
197
  column = @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute)
@@ -113,11 +208,14 @@ module Formula
113
208
  # * :email - for columns containing 'email'
114
209
  # * :phone - for columns containing 'phone'
115
210
  # * :password - for columns containing 'password'
116
- # * :number - for integer, float, or decimal columns
117
-
211
+ # * :number - for integer, float or decimal columns
212
+ # * :datetime - for datetime or timestamp columns
213
+ # * :date - for date column
214
+ # * :time - for time column
215
+ # * :text - for time column
118
216
  # * :string - for all other cases
119
217
 
120
- def as(method, options = {})
218
+ def as(method)
121
219
  type = type(method)
122
220
 
123
221
  if type == :string or type == nil
@@ -157,7 +255,7 @@ module Formula
157
255
  # * :number - for integer, float, or decimal columns
158
256
  # * :text - for all other cases
159
257
 
160
- def error(method, options = {})
258
+ def error(method)
161
259
  @object.errors[method].to_sentence
162
260
  end
163
261
 
@@ -174,20 +272,59 @@ module Formula
174
272
  module FormulaFormHelper
175
273
  @@builder = ::Formula::FormulaFormBuilder
176
274
 
275
+
276
+ # Generates a wrapper around form_for with :builder set to FormulaFormBuilder.
277
+ #
278
+ # Supports:
279
+ #
280
+ # * formula_form_for(@user)
281
+ #
282
+ # Equivalent:
283
+ #
284
+ # * form_for(@user, :builder => Formula::FormulaFormBuilder))
285
+ #
286
+ # Usage:
287
+ #
288
+ # <% formula_form_for(@user) do |f| %>
289
+ # <%= f.input :email %>
290
+ # <%= f.input :password %>
291
+ # <% end %>
292
+
177
293
  def formula_form_for(record_or_name_or_array, *args, &proc)
178
294
  options = args.extract_options!
179
295
  options[:builder] ||= @@builder
180
296
  form_for(record_or_name_or_array, *(args << options), &proc)
181
297
  end
182
-
298
+
299
+ alias :formula_for :formula_form_for
300
+
301
+
302
+ # Generates a wrapper around fields_form with :builder set to FormulaFormBuilder.
303
+ #
304
+ # Supports:
305
+ #
306
+ # * f.formula_fields_for(@user.company)
307
+ # * f.fieldsula_for(@user.company)
308
+ #
309
+ # Equivalent:
310
+ #
311
+ # * f.fields_for(@user.company, :builder => Formula::FormulaFormBuilder))
312
+ #
313
+ # Usage:
314
+ #
315
+ # <% f.formula_form_for(@user.company) do |company_f| %>
316
+ # <%= company_f.input :url %>
317
+ # <%= company_f.input :phone %>
318
+ # <% end %>
319
+
183
320
  def formula_fields_for(record_or_name_or_array, *args, &block)
184
321
  options = args.extract_options!
185
322
  options[:builder] ||= @@builder
186
323
  fields_for(record_or_name_or_array, *(args << options), &block)
187
324
  end
188
325
 
189
- alias :formula_for :formula_form_for
190
- alias :fieldula_for :formula_fields_for
326
+ alias :fieldsula_for :formula_fields_for
327
+
191
328
  end
192
329
 
193
330
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 5
9
- version: 0.0.5
8
+ - 6
9
+ version: 0.0.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kevin Sylvestre