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.
- data/README.rdoc +22 -10
- data/lib/formula.rb +168 -31
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -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
|
-
|
12
|
-
|
11
|
+
<% formula_form_for @user do |f| %>
|
12
|
+
<%= f.input :email %>
|
13
|
+
<%= f.input :password %>
|
14
|
+
<% end %>
|
13
15
|
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
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
|
|
data/lib/formula.rb
CHANGED
@@ -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
|
-
#
|
52
|
+
# Basic container generator for use with blocks.
|
45
53
|
#
|
46
54
|
# Options:
|
47
55
|
#
|
48
|
-
# * :
|
49
|
-
# * :label
|
50
|
-
# * :error
|
51
|
-
#
|
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
|
54
|
-
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
|
-
|
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,
|
78
|
-
|
79
|
-
|
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
|
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
|
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
|
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 :
|
190
|
-
|
326
|
+
alias :fieldsula_for :formula_fields_for
|
327
|
+
|
191
328
|
end
|
192
329
|
|
193
330
|
end
|