formeze 1.0.0 → 1.1.0
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.md +44 -34
- data/formeze.gemspec +2 -2
- data/lib/formeze.rb +25 -3
- data/spec/formeze_spec.rb +43 -4
- metadata +2 -2
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
Formeze: A little library for
|
2
|
-
|
1
|
+
Formeze: A little library for handling form data/input
|
2
|
+
======================================================
|
3
3
|
|
4
4
|
|
5
5
|
Motivation
|
@@ -22,21 +22,23 @@ some class methods and instance methods, but will otherwise leave the object
|
|
22
22
|
untouched (i.e. you can define your own initialization). Here is a minimal
|
23
23
|
example, which defines a form with a single "title" field:
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
field :title
|
29
|
-
end
|
25
|
+
```ruby
|
26
|
+
class ExampleForm
|
27
|
+
Formeze.setup(self)
|
30
28
|
|
29
|
+
field :title
|
30
|
+
end
|
31
|
+
```
|
31
32
|
|
32
33
|
This form can then be used to parse and validate form/input data as follows:
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
form.parse('title=Title')
|
35
|
+
```ruby
|
36
|
+
form = ExampleForm.new
|
37
37
|
|
38
|
-
|
38
|
+
form.parse('title=Title')
|
39
39
|
|
40
|
+
form.title # => "Title"
|
41
|
+
```
|
40
42
|
|
41
43
|
Detecting errors
|
42
44
|
----------------
|
@@ -65,50 +67,57 @@ Defining a field without any options works well for a simple text input.
|
|
65
67
|
If the default character limit is too big or too small you can override
|
66
68
|
it by setting the `char_limit` option. For example:
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
+
```ruby
|
71
|
+
field :title, char_limit: 200
|
72
|
+
```
|
70
73
|
|
71
74
|
If you are dealing with textareas (i.e. multiple lines of text) then you can
|
72
75
|
set the `multiline` option to allow newlines. For example:
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
```ruby
|
78
|
+
field :description, char_limit: 500, multiline: true
|
79
|
+
```
|
76
80
|
|
77
81
|
Error messages will include the field label, which by default is set to the
|
78
82
|
field name, capitalized, and with underscores replace by spaces. If you want
|
79
83
|
to override this, set the `label` option. For example:
|
80
84
|
|
81
|
-
|
82
|
-
|
85
|
+
```ruby
|
86
|
+
field :twitter, label: 'Twitter Username'
|
87
|
+
```
|
83
88
|
|
84
89
|
If you want to validate that the field value matches a specific pattern you
|
85
90
|
can specify the `pattern` option. This is useful for validating things with
|
86
91
|
well defined formats, like numbers. For example:
|
87
92
|
|
88
|
-
|
89
|
-
|
90
|
-
field :card_security_code, char_limit: 5, value: /\A\d+\z/
|
93
|
+
```ruby
|
94
|
+
field :number, pattern: /\A[1-9]\d*\z/
|
91
95
|
|
96
|
+
field :card_security_code, char_limit: 5, value: /\A\d+\z/
|
97
|
+
```
|
92
98
|
|
93
99
|
If you want to validate that the field value belongs to a set of predefined
|
94
100
|
values then you can specify the `values` option. This is useful for dealing
|
95
101
|
with input from select boxes, where the values are known upfront. For example:
|
96
102
|
|
97
|
-
|
98
|
-
|
103
|
+
```ruby
|
104
|
+
field :card_expiry_month, values: (1..12).map(&:to_s)
|
105
|
+
```
|
99
106
|
|
100
107
|
The `values` option is also useful for checkboxes. Specify the `key_required`
|
101
108
|
option to handle the case where the checkbox is unchecked. For example:
|
102
109
|
|
103
|
-
|
104
|
-
|
110
|
+
```ruby
|
111
|
+
field :accept_terms, values: %w(true), key_required: false
|
112
|
+
```
|
105
113
|
|
106
114
|
Sometimes you'll have a field with multiple values. A multiple select input,
|
107
115
|
a set of checkboxes. For this case you can specify the `multiple` option to
|
108
116
|
allow multiple values. For example:
|
109
117
|
|
110
|
-
|
111
|
-
|
118
|
+
```ruby
|
119
|
+
field :colour, multiple: true, values: Colour.keys
|
120
|
+
```
|
112
121
|
|
113
122
|
Unlike all the other examples so far, reading the attribute that corresponds
|
114
123
|
to this field will return an array of strings instead of a single string.
|
@@ -119,15 +128,16 @@ Rails usage
|
|
119
128
|
|
120
129
|
This is the basic pattern for using a formeze form in a rails controller:
|
121
130
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
if form.valid?
|
126
|
-
# do something with form data
|
127
|
-
else
|
128
|
-
# display form.errors to user
|
129
|
-
end
|
131
|
+
```ruby
|
132
|
+
form = SomeForm.new
|
133
|
+
form.parse(request.raw_post)
|
130
134
|
|
135
|
+
if form.valid?
|
136
|
+
# do something with form data
|
137
|
+
else
|
138
|
+
# display form.errors to user
|
139
|
+
end
|
140
|
+
```
|
131
141
|
|
132
142
|
Formeze will automatically define optional "utf8" and "authenticity_token"
|
133
143
|
fields on every form so that you don't have to specify those manually.
|
data/formeze.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'formeze'
|
3
|
-
s.version = '1.
|
3
|
+
s.version = '1.1.0'
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.authors = ['Tim Craft']
|
6
6
|
s.email = ['mail@timcraft.com']
|
7
7
|
s.homepage = 'http://github.com/timcraft/formeze'
|
8
|
-
s.description = 'A little library for
|
8
|
+
s.description = 'A little library for handling form data/input'
|
9
9
|
s.summary = 'See description'
|
10
10
|
s.files = Dir.glob('{lib,spec}/**/*') + %w(README.md Rakefile.rb formeze.gemspec)
|
11
11
|
s.require_path = 'lib'
|
data/lib/formeze.rb
CHANGED
@@ -85,6 +85,22 @@ module Formeze
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
class GuardCondition
|
89
|
+
attr_reader :block
|
90
|
+
|
91
|
+
def initialize(block)
|
92
|
+
@block = block
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class HaltingCondition
|
97
|
+
attr_reader :block
|
98
|
+
|
99
|
+
def initialize(block)
|
100
|
+
@block = block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
88
104
|
module ArrayAttrAccessor
|
89
105
|
def array_attr_reader(name)
|
90
106
|
define_method(name) do
|
@@ -142,7 +158,11 @@ module Formeze
|
|
142
158
|
end
|
143
159
|
|
144
160
|
def guard(&block)
|
145
|
-
fields << block
|
161
|
+
fields << GuardCondition.new(block)
|
162
|
+
end
|
163
|
+
|
164
|
+
def halts(&block)
|
165
|
+
fields << HaltingCondition.new(block)
|
146
166
|
end
|
147
167
|
|
148
168
|
def checks
|
@@ -173,8 +193,10 @@ module Formeze
|
|
173
193
|
form_data = CGI.parse(encoded_form_data)
|
174
194
|
|
175
195
|
self.class.fields.each do |field|
|
176
|
-
|
177
|
-
instance_eval(&field) ?
|
196
|
+
if field.is_a?(GuardCondition)
|
197
|
+
instance_eval(&field.block) ? next : return
|
198
|
+
elsif field.is_a?(HaltingCondition)
|
199
|
+
instance_eval(&field.block) ? return : next
|
178
200
|
end
|
179
201
|
|
180
202
|
unless form_data.has_key?(field.key)
|
data/spec/formeze_spec.rb
CHANGED
@@ -301,14 +301,53 @@ describe 'FormWithFieldThatCanOnlyHaveSpecifiedValues after parsing input with a
|
|
301
301
|
end
|
302
302
|
end
|
303
303
|
|
304
|
-
class
|
304
|
+
class FormWithGuardCondition
|
305
|
+
Formeze.setup(self)
|
306
|
+
|
307
|
+
field :account_name
|
308
|
+
|
309
|
+
guard { @business_account }
|
310
|
+
|
311
|
+
field :account_vat_number
|
312
|
+
|
313
|
+
def initialize(business_account)
|
314
|
+
@business_account = business_account
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
describe 'FormWithGuardCondition with business_account set to true' do
|
319
|
+
before do
|
320
|
+
@form = FormWithGuardCondition.new(true)
|
321
|
+
end
|
322
|
+
|
323
|
+
describe 'parse method' do
|
324
|
+
it 'should raise an exception when the account_vat_number key is missing' do
|
325
|
+
proc { @form.parse('account_name=Something') }.must_raise(Formeze::KeyError)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe 'FormWithGuardCondition with business_account set to false after parsing valid input' do
|
331
|
+
before do
|
332
|
+
@form = FormWithGuardCondition.new(false)
|
333
|
+
@form.parse('account_name=Something')
|
334
|
+
end
|
335
|
+
|
336
|
+
describe 'valid query method' do
|
337
|
+
it 'should return true' do
|
338
|
+
@form.valid?.must_equal(true)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
class FormWithHaltingCondition
|
305
344
|
Formeze.setup(self)
|
306
345
|
|
307
346
|
field :delivery_address
|
308
347
|
|
309
348
|
field :same_address, values: %w(yes no)
|
310
349
|
|
311
|
-
|
350
|
+
halts { same_address? }
|
312
351
|
|
313
352
|
field :billing_address
|
314
353
|
|
@@ -317,9 +356,9 @@ class FormWithGuard
|
|
317
356
|
end
|
318
357
|
end
|
319
358
|
|
320
|
-
describe '
|
359
|
+
describe 'FormWithHaltingCondition after parsing input with same_address set and no billing address' do
|
321
360
|
before do
|
322
|
-
@form =
|
361
|
+
@form = FormWithHaltingCondition.new
|
323
362
|
@form.parse('delivery_address=123+Main+St&same_address=yes')
|
324
363
|
end
|
325
364
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formeze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-04-09 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
|
-
description: A little library for
|
14
|
+
description: A little library for handling form data/input
|
15
15
|
email:
|
16
16
|
- mail@timcraft.com
|
17
17
|
executables: []
|