forme 0.9.2 → 0.10.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.
- checksums.yaml +4 -4
- data/CHANGELOG +56 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +646 -69
- data/Rakefile +5 -4
- data/lib/forme.rb +433 -328
- data/lib/forme/rails.rb +4 -4
- data/lib/forme/version.rb +1 -1
- data/lib/sequel/plugins/forme.rb +43 -94
- data/spec/forme_coverage.rb +13 -0
- data/spec/forme_spec.rb +315 -4
- data/spec/rails_integration_spec.rb +31 -1
- data/spec/sequel_plugin_spec.rb +28 -11
- data/spec/sinatra_integration_spec.rb +1 -1
- data/spec/spec_helper.rb +20 -0
- metadata +3 -2
data/lib/forme/rails.rb
CHANGED
@@ -53,8 +53,8 @@ module Forme
|
|
53
53
|
|
54
54
|
# If a block is not given, emit the inputs into the current output
|
55
55
|
# buffer.
|
56
|
-
def _inputs(
|
57
|
-
if block_given?
|
56
|
+
def _inputs(inputs=[], opts={}) # :nodoc:
|
57
|
+
if block_given? && !opts[:subform]
|
58
58
|
super
|
59
59
|
else
|
60
60
|
emit(super)
|
@@ -83,8 +83,8 @@ module Forme
|
|
83
83
|
template.raw(tag.to_s)
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
87
|
-
def tag_(type, attr={}, children=[])
|
86
|
+
|
87
|
+
def tag_(type, attr={}, children=[]) # :nodoc:
|
88
88
|
tag = _tag(type, attr, children)
|
89
89
|
emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
|
90
90
|
Array(tag.children).each{|c| emit(c)}
|
data/lib/forme/version.rb
CHANGED
data/lib/sequel/plugins/forme.rb
CHANGED
@@ -15,18 +15,6 @@ module Sequel # :nodoc:
|
|
15
15
|
# that use a <tt>Sequel::Model</tt> instance as the form's
|
16
16
|
# +obj+.
|
17
17
|
module SequelForm
|
18
|
-
# Stack of objects used by subform. The current +obj+
|
19
|
-
# is added to the top of the stack on a call to +subform+,
|
20
|
-
# the nested associated object is set as the current +obj+ during the
|
21
|
-
# call to +subform+, and when +subform+ returns, the top of the
|
22
|
-
# stack is set as the current +obj+.
|
23
|
-
attr_accessor :nested_associations
|
24
|
-
|
25
|
-
# The namespaces that should be added to the id and name
|
26
|
-
# attributes for the receiver's inputs. Used as a stack
|
27
|
-
# by +subform+.
|
28
|
-
attr_accessor :namespaces
|
29
|
-
|
30
18
|
# Use the post method by default for Sequel forms, unless
|
31
19
|
# overridden with the :method attribute.
|
32
20
|
def form(attr={}, &block)
|
@@ -53,26 +41,31 @@ module Sequel # :nodoc:
|
|
53
41
|
# :inputs :: Automatically call +inputs+ with the given values. Using
|
54
42
|
# this, it is not required to pass a block to the method,
|
55
43
|
# though it will still work if you do.
|
56
|
-
# :legend ::
|
57
|
-
#
|
44
|
+
# :legend :: Overrides the default :legend used (which is based on the
|
45
|
+
# association name). You can also use a proc as the value,
|
58
46
|
# which will called with each associated object (and the position
|
59
47
|
# in the associated object already for *_to_many associations),
|
60
48
|
# and should return the legend string to use for that object.
|
49
|
+
# :grid :: Sets up a table with one row per associated object, and
|
50
|
+
# one column per field.
|
51
|
+
# :labels :: When using the :grid option, override the labels that would
|
52
|
+
# be created via the :inputs option. If you are not providing
|
53
|
+
# an :inputs option or are using a block with additional inputs,
|
54
|
+
# you should specify this option.
|
61
55
|
def subform(association, opts={}, &block)
|
62
56
|
nested_obj = opts.has_key?(:obj) ? opts[:obj] : obj.send(association)
|
63
57
|
ref = obj.class.association_reflection(association)
|
64
58
|
multiple = ref.returns_array?
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
options = opts.dup
|
59
|
+
grid = opts[:grid]
|
60
|
+
ns = "#{association}_attributes"
|
61
|
+
|
62
|
+
contents = proc do
|
63
|
+
send(multiple ? :each_obj : :with_obj, nested_obj, ns) do |no, i|
|
64
|
+
emit(input(ref.associated_class.primary_key, :type=>:hidden, :label=>nil, :wrapper=>nil)) unless no.new?
|
65
|
+
options = opts.dup
|
66
|
+
if grid
|
67
|
+
options.delete(:legend)
|
68
|
+
else
|
76
69
|
if options.has_key?(:legend)
|
77
70
|
if options[:legend].respond_to?(:call)
|
78
71
|
options[:legend] = multiple ? options[:legend].call(no, i) : options[:legend].call(no)
|
@@ -84,32 +77,21 @@ module Sequel # :nodoc:
|
|
84
77
|
options[:legend] = humanize(association)
|
85
78
|
end
|
86
79
|
end
|
87
|
-
_inputs(ins, options, &block)
|
88
|
-
else
|
89
|
-
yield
|
90
80
|
end
|
91
|
-
|
92
|
-
|
93
|
-
namespaces.pop if multiple
|
94
|
-
namespaces.pop
|
81
|
+
options[:subform] = true
|
82
|
+
_inputs(options[:inputs]||[], options, &block)
|
95
83
|
end
|
96
84
|
end
|
85
|
+
|
86
|
+
if grid
|
87
|
+
labels = opts.fetch(:labels){opts[:inputs].map{|l, *| humanize(l)} if opts[:inputs]}
|
88
|
+
legend = opts.fetch(:legend){humanize(association)}
|
89
|
+
inputs({:inputs_wrapper=>:table, :nested_inputs_wrapper=>:tr, :wrapper=>:td, :labeler=>nil, :labels=>labels, :legend=>legend}, &contents)
|
90
|
+
else
|
91
|
+
contents.call
|
92
|
+
end
|
97
93
|
nil
|
98
94
|
end
|
99
|
-
|
100
|
-
# Return a unique id attribute for the +field+, handling
|
101
|
-
# nested attributes use.
|
102
|
-
def namespaced_id(field)
|
103
|
-
"#{namespaces.join('_')}_#{field}"
|
104
|
-
end
|
105
|
-
|
106
|
-
# Return a unique name attribute for the +field+, handling nested
|
107
|
-
# attribute use. If +multiple+ is true, end the name
|
108
|
-
# with [] so that param parsing will treat the name as part of an array.
|
109
|
-
def namespaced_name(field, multiple=false)
|
110
|
-
root, *nsps = namespaces
|
111
|
-
"#{root}#{nsps.map{|n| "[#{n}]"}.join}[#{field}]#{'[]' if multiple}"
|
112
|
-
end
|
113
95
|
end
|
114
96
|
|
115
97
|
# Helper class for dealing with Forme/Sequel integration.
|
@@ -157,8 +139,7 @@ module Sequel # :nodoc:
|
|
157
139
|
type = opts[:type]
|
158
140
|
if !type && (sch = obj.db_schema[field])
|
159
141
|
meth = :"input_#{sch[:type]}"
|
160
|
-
opts[:
|
161
|
-
opts[:name] = form.namespaced_name(field) unless opts.has_key?(:name)
|
142
|
+
opts[:key] = field unless opts.has_key?(:key)
|
162
143
|
opts[:required] = true if !opts.has_key?(:required) && sch[:allow_null] == false && sch[:type] != :boolean
|
163
144
|
handle_label(field)
|
164
145
|
|
@@ -183,8 +164,7 @@ module Sequel # :nodoc:
|
|
183
164
|
raise(Error, "Unrecognized field used: #{field}") unless rt || type
|
184
165
|
meth = :"input_#{type}"
|
185
166
|
opts[:value] = nil unless rt || opts.has_key?(:value)
|
186
|
-
opts[:
|
187
|
-
opts[:name] = form.namespaced_name(field, opts[:multiple]) unless opts.has_key?(:name)
|
167
|
+
opts[:key] = field unless opts.has_key?(:key)
|
188
168
|
handle_label(field)
|
189
169
|
if respond_to?(meth, true)
|
190
170
|
opts.delete(:type)
|
@@ -217,22 +197,6 @@ module Sequel # :nodoc:
|
|
217
197
|
opts[:label] = [opts[:label], form._tag(:abbr, {:title=>'required'}, '*')] if opts[:required]
|
218
198
|
end
|
219
199
|
|
220
|
-
# Add the label to the start of the array, returning the array.
|
221
|
-
def add_label(label, array)
|
222
|
-
array.unshift(form._tag(:span, {:class=>:label}, label)) if label
|
223
|
-
array
|
224
|
-
end
|
225
|
-
|
226
|
-
# Unset the wrapper and tag_wrapper options and return a
|
227
|
-
# array with the wrapper and tag_wrapper to use. The tag_wrapper
|
228
|
-
# is for wrapping each individual tag.
|
229
|
-
def get_wrappers
|
230
|
-
tag_wrapper = opts.delete(:tag_wrapper) || :default
|
231
|
-
wrapper = form.transformer(:wrapper, opts)
|
232
|
-
opts.delete(:wrapper)
|
233
|
-
[wrapper, tag_wrapper]
|
234
|
-
end
|
235
|
-
|
236
200
|
# Update the attributes and options for any recognized validations
|
237
201
|
def handle_validations(f)
|
238
202
|
m = obj.model
|
@@ -296,19 +260,13 @@ module Sequel # :nodoc:
|
|
296
260
|
def association_many_to_one(ref)
|
297
261
|
key = ref[:key]
|
298
262
|
handle_errors(key)
|
299
|
-
opts[:
|
263
|
+
opts[:key] = key unless opts.has_key?(:key)
|
300
264
|
opts[:value] = obj.send(key) unless opts.has_key?(:value)
|
301
265
|
opts[:options] = association_select_options(ref) unless opts.has_key?(:options)
|
302
266
|
if opts.delete(:as) == :radio
|
303
267
|
handle_label(field)
|
304
|
-
|
305
|
-
val = opts.delete(:value)
|
306
|
-
wrapper, tag_wrapper = get_wrappers
|
307
|
-
radios = opts.delete(:options).map{|l, pk| _input(:radio, opts.merge(:value=>pk, :id=>"#{form.namespaced_id(key)}_#{pk}", :wrapper=>tag_wrapper, :label=>l, :label_attr=>{:class=>:option}, :checked=>(pk == val)))}
|
308
|
-
add_label(label, radios)
|
309
|
-
wrapper ? wrapper.call(radios, _input(:radio, opts)) : radios
|
268
|
+
_input(:radioset, opts)
|
310
269
|
else
|
311
|
-
opts[:id] = form.namespaced_id(key) unless opts.has_key?(:id)
|
312
270
|
opts[:required] = true if !opts.has_key?(:required) && (sch = obj.model.db_schema[key]) && !sch[:allow_null]
|
313
271
|
opts[:add_blank] = true if !opts.has_key?(:add_blank) && !(opts[:required] && opts[:value])
|
314
272
|
handle_label(field)
|
@@ -327,19 +285,16 @@ module Sequel # :nodoc:
|
|
327
285
|
klass = ref.associated_class
|
328
286
|
pk = klass.primary_key
|
329
287
|
field = "#{klass.send(:singularize, ref[:name])}_pks"
|
330
|
-
|
288
|
+
unless opts.has_key?(:key)
|
289
|
+
opts[:array] = true unless opts.has_key?(:array)
|
290
|
+
opts[:key] = field
|
291
|
+
end
|
331
292
|
opts[:value] = obj.send(ref[:name]).map{|x| x.send(pk)} unless opts.has_key?(:value)
|
332
293
|
opts[:options] = association_select_options(ref) unless opts.has_key?(:options)
|
333
294
|
handle_label(field)
|
334
295
|
if opts.delete(:as) == :checkbox
|
335
|
-
|
336
|
-
val = opts.delete(:value)
|
337
|
-
wrapper, tag_wrapper = get_wrappers
|
338
|
-
cbs = opts.delete(:options).map{|l, pk| _input(:checkbox, opts.merge(:value=>pk, :id=>"#{form.namespaced_id(field)}_#{pk}", :wrapper=>tag_wrapper, :label=>l, :label_attr=>{:class=>:option}, :checked=>val.include?(pk), :no_hidden=>true))}
|
339
|
-
add_label(label, cbs)
|
340
|
-
wrapper ? wrapper.call(cbs, _input(:checkbox, opts)) : cbs
|
296
|
+
_input(:checkboxset, opts)
|
341
297
|
else
|
342
|
-
opts[:id] = form.namespaced_id(field) unless opts.has_key?(:id)
|
343
298
|
opts[:multiple] = true unless opts.has_key?(:multiple)
|
344
299
|
_input(:select, opts)
|
345
300
|
end
|
@@ -385,19 +340,14 @@ module Sequel # :nodoc:
|
|
385
340
|
|
386
341
|
case opts[:as]
|
387
342
|
when :radio
|
388
|
-
wrapper, tag_wrapper = get_wrappers
|
389
|
-
true_opts = opts.merge(:value=>opts[:true_value]||'t', :label=>opts[:true_label]||'Yes', :label_attr=>{:class=>:option}, :error=>nil, :wrapper=>tag_wrapper, :wrapper_attr=>{})
|
390
|
-
false_opts = opts.merge(:value=>opts[:false_value]||'f', :label=>opts[:false_label]||'No', :label_attr=>{:class=>:option}, :wrapper=>tag_wrapper, :wrapper_attr=>{})
|
391
|
-
if i = opts[:id]
|
392
|
-
true_opts[:id] = "#{i}_yes"
|
393
|
-
false_opts[:id] = "#{i}_no"
|
394
|
-
end
|
395
343
|
v = opts.has_key?(:value) ? opts[:value] : obj.send(field)
|
344
|
+
true_value = opts[:true_value]||'t'
|
345
|
+
false_value = opts[:false_value]||'f'
|
346
|
+
opts[:options] = [[opts[:true_label]||'Yes', {:value=>true_value, :key_id=>'yes'}], [opts[:false_label]||'No', {:value=>false_value, :key_id=>'no'}]]
|
396
347
|
unless v.nil?
|
397
|
-
|
348
|
+
opts[:value] = v ? true_value : false_value
|
398
349
|
end
|
399
|
-
|
400
|
-
wrapper ? wrapper.call(array, _input(:radio, opts)) : array
|
350
|
+
_input(:radioset, opts)
|
401
351
|
when :select
|
402
352
|
v = opts[:value] || obj.send(field)
|
403
353
|
opts[:value] = (v ? 't' : 'f') unless v.nil?
|
@@ -487,8 +437,7 @@ module Sequel # :nodoc:
|
|
487
437
|
# specific code, such as support for nested attributes.
|
488
438
|
def forme_config(form)
|
489
439
|
form.extend(SequelForm)
|
490
|
-
form.
|
491
|
-
form.namespaces = [model.send(:underscore, model.name)]
|
440
|
+
form.namespaces << model.send(:underscore, model.name)
|
492
441
|
form.extend(SinatraSequelForm) if defined?(::Forme::Sinatra::Form) && form.is_a?(::Forme::Sinatra::Form)
|
493
442
|
end
|
494
443
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'coverage'
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
def SimpleCov.forme_coverage(opts = {})
|
5
|
+
start do
|
6
|
+
add_filter "/spec/"
|
7
|
+
add_group('Missing'){|src| src.covered_percent < 100}
|
8
|
+
add_group('Covered'){|src| src.covered_percent == 100}
|
9
|
+
yield self if block_given?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
ENV.delete('COVERAGE')
|
data/spec/forme_spec.rb
CHANGED
@@ -45,6 +45,136 @@ describe "Forme plain forms" do
|
|
45
45
|
@f.input(:text, :style=>"foo").to_s.should == '<input style="foo" type="text"/>'
|
46
46
|
end
|
47
47
|
|
48
|
+
specify "should use :key option as name and id attributes" do
|
49
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="foo" name="foo" type="text"/>'
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "should use :key_id option as suffix for :key option id attributes" do
|
53
|
+
@f.input(:text, :key=>"foo", :key_id=>'bar').to_s.should == '<input id="foo_bar" name="foo" type="text"/>'
|
54
|
+
end
|
55
|
+
|
56
|
+
specify "should have :key option respect :multiple option" do
|
57
|
+
@f.input(:text, :key=>"foo", :multiple=>true).to_s.should == '<input id="foo" name="foo[]" type="text"/>'
|
58
|
+
end
|
59
|
+
|
60
|
+
specify "should use :key option respect form's current namespace" do
|
61
|
+
@f.with_opts(:namespace=>['bar']) do
|
62
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="bar_foo" name="bar[foo]" type="text"/>'
|
63
|
+
@f.input(:text, :key=>"foo", :multiple=>true).to_s.should == '<input id="bar_foo" name="bar[foo][]" type="text"/>'
|
64
|
+
@f.with_opts(:namespace=>['bar', 'baz']) do
|
65
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="bar_baz_foo" name="bar[baz][foo]" type="text"/>'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
specify "should consider form's :values hash for default values based on the :key option if :value is not present" do
|
71
|
+
@f.opts[:values] = {'foo'=>'baz'}
|
72
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="foo" name="foo" type="text" value="baz"/>'
|
73
|
+
@f.input(:text, :key=>"foo", :value=>'x').to_s.should == '<input id="foo" name="foo" type="text" value="x"/>'
|
74
|
+
|
75
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="foo" name="foo" type="text" value="baz"/>'
|
76
|
+
@f.opts[:values] = {:foo=>'baz'}
|
77
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="foo" name="foo" type="text" value="baz"/>'
|
78
|
+
end
|
79
|
+
|
80
|
+
specify "should consider form's :values hash for default values based on the :key option when using namespaces" do
|
81
|
+
@f.opts[:values] = {'bar'=>{'foo'=>'baz'}}
|
82
|
+
@f.with_opts(:namespace=>['bar']) do
|
83
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="bar_foo" name="bar[foo]" type="text" value="baz"/>'
|
84
|
+
@f.input(:text, :key=>"foo", :value=>'x').to_s.should == '<input id="bar_foo" name="bar[foo]" type="text" value="x"/>'
|
85
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="bar_foo" name="bar[foo]" type="text" value="baz"/>'
|
86
|
+
end
|
87
|
+
|
88
|
+
@f.with_opts(:namespace=>[:bar]) do
|
89
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="bar_foo" name="bar[foo]" type="text" value="baz"/>'
|
90
|
+
|
91
|
+
@f.opts[:values] = {:bar=>{:foo=>'baz'}}
|
92
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="bar_foo" name="bar[foo]" type="text" value="baz"/>'
|
93
|
+
@f.opts[:values] = {:bar=>{}}
|
94
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="bar_foo" name="bar[foo]" type="text"/>'
|
95
|
+
@f.opts[:values] = {}
|
96
|
+
@f.input(:text, :key=>:foo).to_s.should == '<input id="bar_foo" name="bar[foo]" type="text"/>'
|
97
|
+
|
98
|
+
@f.opts[:values] = {'bar'=>{'quux'=>{'foo'=>'baz'}}}
|
99
|
+
@f.with_opts(:namespace=>['bar', 'quux']) do
|
100
|
+
@f.input(:text, :key=>"foo").to_s.should == '<input id="bar_quux_foo" name="bar[quux][foo]" type="text" value="baz"/>'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
specify "should support a with_obj method that changes the object and namespace for the given block" do
|
106
|
+
@f.with_obj([:a, :c], 'bar') do
|
107
|
+
@f.input(:first).to_s.should == '<input id="bar_first" name="bar[first]" type="text" value="a"/>'
|
108
|
+
@f.with_obj([:b], 'baz') do
|
109
|
+
@f.input(:first).to_s.should == '<input id="bar_baz_first" name="bar[baz][first]" type="text" value="b"/>'
|
110
|
+
end
|
111
|
+
@f.with_obj([:b], %w'baz quux') do
|
112
|
+
@f.input(:first).to_s.should == '<input id="bar_baz_quux_first" name="bar[baz][quux][first]" type="text" value="b"/>'
|
113
|
+
end
|
114
|
+
@f.with_obj([:b]) do
|
115
|
+
@f.input(:first).to_s.should == '<input id="bar_first" name="bar[first]" type="text" value="b"/>'
|
116
|
+
end
|
117
|
+
@f.input(:last).to_s.should == '<input id="bar_last" name="bar[last]" type="text" value="c"/>'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
specify "should support a each_obj method that changes the object and namespace for multiple objects for the given block" do
|
122
|
+
@f.tag(:form) do
|
123
|
+
@f.each_obj([[:a, :c], [:b, :d]], 'bar') do
|
124
|
+
@f.input(:first)
|
125
|
+
@f.input(:last)
|
126
|
+
end
|
127
|
+
end.to_s.should == '<form><input id="bar_0_first" name="bar[0][first]" type="text" value="a"/><input id="bar_0_last" name="bar[0][last]" type="text" value="c"/><input id="bar_1_first" name="bar[1][first]" type="text" value="b"/><input id="bar_1_last" name="bar[1][last]" type="text" value="d"/></form>'
|
128
|
+
|
129
|
+
@f.tag(:form) do
|
130
|
+
@f.each_obj([[:a, :c], [:b, :d]], %w'bar baz') do
|
131
|
+
@f.input(:first)
|
132
|
+
@f.input(:last)
|
133
|
+
end
|
134
|
+
end.to_s.should == '<form><input id="bar_baz_0_first" name="bar[baz][0][first]" type="text" value="a"/><input id="bar_baz_0_last" name="bar[baz][0][last]" type="text" value="c"/><input id="bar_baz_1_first" name="bar[baz][1][first]" type="text" value="b"/><input id="bar_baz_1_last" name="bar[baz][1][last]" type="text" value="d"/></form>'
|
135
|
+
|
136
|
+
@f.tag(:form) do
|
137
|
+
@f.each_obj([[:a, :c], [:b, :d]]) do
|
138
|
+
@f.input(:first)
|
139
|
+
@f.input(:last)
|
140
|
+
end
|
141
|
+
end.to_s.should == '<form><input id="0_first" name="0[first]" type="text" value="a"/><input id="0_last" name="0[last]" type="text" value="c"/><input id="1_first" name="1[first]" type="text" value="b"/><input id="1_last" name="1[last]" type="text" value="d"/></form>'
|
142
|
+
end
|
143
|
+
|
144
|
+
specify "should allow overriding form inputs on a per-block basis" do
|
145
|
+
@f.input(:text).to_s.should == '<input type="text"/>'
|
146
|
+
@f.with_opts(:wrapper=>:div){@f.input(:text).to_s}.should == '<div><input type="text"/></div>'
|
147
|
+
@f.with_opts(:wrapper=>:div){@f.input(:text).to_s.should == '<div><input type="text"/></div>'}
|
148
|
+
@f.with_opts(:wrapper=>:div) do
|
149
|
+
@f.input(:text).to_s.should == '<div><input type="text"/></div>'
|
150
|
+
@f.with_opts(:wrapper=>:li){@f.input(:text).to_s.should == '<li><input type="text"/></li>'}
|
151
|
+
@f.input(:text).to_s.should == '<div><input type="text"/></div>'
|
152
|
+
end
|
153
|
+
@f.input(:text).to_s.should == '<input type="text"/>'
|
154
|
+
end
|
155
|
+
|
156
|
+
specify "should handle delayed formatting when overriding form inputs on a per-block basis" do
|
157
|
+
@f.form do
|
158
|
+
@f.input(:text)
|
159
|
+
@f.with_opts(:wrapper=>:div) do
|
160
|
+
@f.input(:text)
|
161
|
+
@f.with_opts(:wrapper=>:li){@f.input(:text)}
|
162
|
+
@f.input(:text)
|
163
|
+
end
|
164
|
+
@f.input(:text)
|
165
|
+
end.to_s.should == '<form><input type="text"/><div><input type="text"/></div><li><input type="text"/></li><div><input type="text"/></div><input type="text"/></form>'
|
166
|
+
end
|
167
|
+
|
168
|
+
specify "should support :obj method to with_opts for changing the obj inside the block" do
|
169
|
+
@f.form do
|
170
|
+
@f.with_opts(:obj=>[:a, :c]) do
|
171
|
+
@f.input(:first)
|
172
|
+
@f.with_opts(:obj=>[:b]){@f.input(:first)}
|
173
|
+
@f.input(:last)
|
174
|
+
end
|
175
|
+
end.to_s.should == '<form><input id="first" name="first" type="text" value="a"/><input id="first" name="first" type="text" value="b"/><input id="last" name="last" type="text" value="c"/></form>'
|
176
|
+
end
|
177
|
+
|
48
178
|
specify "should allow arbitrary attributes using the :attr option" do
|
49
179
|
@f.input(:text, :attr=>{:bar=>"foo"}).to_s.should == '<input bar="foo" type="text"/>'
|
50
180
|
end
|
@@ -157,10 +287,95 @@ describe "Forme plain forms" do
|
|
157
287
|
@f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.should == '<select><option value=""></option><option selected="selected" value="2">b</option><option value="3">c</option></select>'
|
158
288
|
end
|
159
289
|
|
290
|
+
specify "should use Forme.default_add_blank_prompt value if :add_blank option is true" do
|
291
|
+
begin
|
292
|
+
Forme.default_add_blank_prompt = 'foo'
|
293
|
+
@f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.should == '<select><option value="">foo</option><option selected="selected" value="2">b</option><option value="3">c</option></select>'
|
294
|
+
ensure
|
295
|
+
Forme.default_add_blank_prompt = nil
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
160
299
|
specify "should use :add_blank option value as prompt if it is a String" do
|
161
300
|
@f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.should == '<select><option value="">Prompt Here</option><option selected="selected" value="2">b</option><option value="3">c</option></select>'
|
162
301
|
end
|
163
302
|
|
303
|
+
specify "should create set of radio buttons" do
|
304
|
+
@f.input(:radioset, :options=>[1, 2, 3], :selected=>2).to_s.should == '<label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input type="radio" value="3"/> 3</label>'
|
305
|
+
@f.input(:radioset, :options=>[1, 2, 3], :value=>2).to_s.should == '<label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input type="radio" value="3"/> 3</label>'
|
306
|
+
end
|
307
|
+
|
308
|
+
specify "should create set of radio buttons with options and values" do
|
309
|
+
@f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :selected=>2).to_s.should == '<label class="option"><input type="radio" value="1"/> a</label><label class="option"><input checked="checked" type="radio" value="2"/> b</label><label class="option"><input type="radio" value="3"/> c</label>'
|
310
|
+
end
|
311
|
+
|
312
|
+
specify "should create set of radio buttons with options and values with hashes" do
|
313
|
+
@f.input(:radioset, :options=>[[:a, {:attr=>{:foo=>1}}], [:b, {:class=>'foo', :value=>2}], [:c, {:id=>:baz}]], :selected=>2).to_s.should == '<label class="option"><input foo="1" type="radio" value="a"/> a</label><label class="option"><input checked="checked" class="foo" type="radio" value="2"/> b</label><label class="option"><input id="baz" type="radio" value="c"/> c</label>'
|
314
|
+
end
|
315
|
+
|
316
|
+
specify "should create set of radio buttons with options and values using given method" do
|
317
|
+
@f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :selected=>2).to_s.should == '<label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input type="radio" value="3"/> 3</label>'
|
318
|
+
@f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :value_method=>:first, :selected=>:b).to_s.should == '<label class="option"><input type="radio" value="a"/> 1</label><label class="option"><input checked="checked" type="radio" value="b"/> 2</label><label class="option"><input type="radio" value="c"/> 3</label>'
|
319
|
+
end
|
320
|
+
|
321
|
+
specify "should support :add_blank option for radioset inputs" do
|
322
|
+
@f.input(:radioset, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.should == '<label class="option"><input type="radio" value=""/> </label><label class="option"><input checked="checked" type="radio" value="2"/> b</label><label class="option"><input type="radio" value="3"/> c</label>'
|
323
|
+
end
|
324
|
+
|
325
|
+
specify "should use :add_blank option value as prompt if it is a String" do
|
326
|
+
@f.input(:radioset, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.should == '<label class="option"><input type="radio" value=""/> Prompt Here</label><label class="option"><input checked="checked" type="radio" value="2"/> b</label><label class="option"><input type="radio" value="3"/> c</label>'
|
327
|
+
end
|
328
|
+
|
329
|
+
specify "should respect the :key option for radio sets" do
|
330
|
+
@f.input(:radioset, :options=>[1, 2, 3], :key=>:foo, :value=>2).to_s.should == '<label class="option"><input id="foo_1" name="foo" type="radio" value="1"/> 1</label><label class="option"><input checked="checked" id="foo_2" name="foo" type="radio" value="2"/> 2</label><label class="option"><input id="foo_3" name="foo" type="radio" value="3"/> 3</label>'
|
331
|
+
end
|
332
|
+
|
333
|
+
specify "should create set of checkbox buttons" do
|
334
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :selected=>2).to_s.should == '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input type="checkbox" value="3"/> 3</label>'
|
335
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :value=>2).to_s.should == '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input type="checkbox" value="3"/> 3</label>'
|
336
|
+
end
|
337
|
+
|
338
|
+
specify "should create set of checkbox buttons with options and values" do
|
339
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :selected=>2).to_s.should == '<label class="option"><input type="checkbox" value="1"/> a</label><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label>'
|
340
|
+
end
|
341
|
+
|
342
|
+
specify "should create set of checkbox buttons with options and values with hashes" do
|
343
|
+
@f.input(:checkboxset, :options=>[[:a, {:attr=>{:foo=>1}}], [:b, {:class=>'foo', :value=>2}], [:c, {:id=>:baz}]], :selected=>2).to_s.should == '<label class="option"><input foo="1" type="checkbox" value="a"/> a</label><label class="option"><input checked="checked" class="foo" type="checkbox" value="2"/> b</label><label class="option"><input id="baz" type="checkbox" value="c"/> c</label>'
|
344
|
+
end
|
345
|
+
|
346
|
+
specify "should create set of checkbox buttons with options and values using given method" do
|
347
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :selected=>2).to_s.should == '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input type="checkbox" value="3"/> 3</label>'
|
348
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :value_method=>:first, :selected=>:b).to_s.should == '<label class="option"><input type="checkbox" value="a"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="b"/> 2</label><label class="option"><input type="checkbox" value="c"/> 3</label>'
|
349
|
+
end
|
350
|
+
|
351
|
+
specify "should support :add_blank option for checkboxset inputs" do
|
352
|
+
@f.input(:checkboxset, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.should == '<label class="option"><input type="checkbox" value=""/> </label><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label>'
|
353
|
+
end
|
354
|
+
|
355
|
+
specify "should use :add_blank option value as prompt if it is a String" do
|
356
|
+
@f.input(:checkboxset, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.should == '<label class="option"><input type="checkbox" value=""/> Prompt Here</label><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label>'
|
357
|
+
end
|
358
|
+
|
359
|
+
specify "should respect the :key option for checkbox sets" do
|
360
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :value=>2).to_s.should == '<label class="option"><input id="foo_1" name="foo[]" type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" id="foo_2" name="foo[]" type="checkbox" value="2"/> 2</label><label class="option"><input id="foo_3" name="foo[]" type="checkbox" value="3"/> 3</label>'
|
361
|
+
end
|
362
|
+
|
363
|
+
specify "should prefer the :name option to :key option for checkbox sets" do
|
364
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :name=>'bar[]', :value=>2).to_s.should == '<label class="option"><input id="foo_1" name="bar[]" type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" id="foo_2" name="bar[]" type="checkbox" value="2"/> 2</label><label class="option"><input id="foo_3" name="bar[]" type="checkbox" value="3"/> 3</label>'
|
365
|
+
end
|
366
|
+
|
367
|
+
specify "should prefer the :name and :id option to :key option for checkbox sets" do
|
368
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :name=>'bar[]', :id=>:baz, :value=>2).to_s.should == '<label class="option"><input id="baz_1" name="bar[]" type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" id="baz_2" name="bar[]" type="checkbox" value="2"/> 2</label><label class="option"><input id="baz_3" name="bar[]" type="checkbox" value="3"/> 3</label>'
|
369
|
+
end
|
370
|
+
|
371
|
+
specify "should respect the :error option for checkbox sets" do
|
372
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :error=>'foo', :value=>2).to_s.should == '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input class="error" type="checkbox" value="3"/> 3</label><span class="error_message">foo</span>'
|
373
|
+
end
|
374
|
+
|
375
|
+
specify "should raise an Error for empty checkbox sets" do
|
376
|
+
@f.input(:checkboxset, :options=>[], :error=>'foo', :value=>2).to_s.should == '<span class="error_message">foo</span>'
|
377
|
+
end
|
378
|
+
|
164
379
|
specify "radio and checkbox inputs should handle :checked option" do
|
165
380
|
@f.input(:radio, :checked=>true).to_s.should == '<input checked="checked" type="radio"/>'
|
166
381
|
@f.input(:radio, :checked=>false).to_s.should == '<input type="radio"/>'
|
@@ -168,6 +383,11 @@ describe "Forme plain forms" do
|
|
168
383
|
@f.input(:checkbox, :checked=>false).to_s.should == '<input type="checkbox"/>'
|
169
384
|
end
|
170
385
|
|
386
|
+
specify "inputs should handle :autofocus option" do
|
387
|
+
@f.input(:text, :autofocus=>true).to_s.should == '<input autofocus="autofocus" type="text"/>'
|
388
|
+
@f.input(:text, :autofocus=>false).to_s.should == '<input type="text"/>'
|
389
|
+
end
|
390
|
+
|
171
391
|
specify "inputs should handle :required option" do
|
172
392
|
@f.input(:text, :required=>true).to_s.should == '<input required="required" type="text"/>'
|
173
393
|
@f.input(:text, :required=>false).to_s.should == '<input type="text"/>'
|
@@ -283,6 +503,14 @@ describe "Forme plain forms" do
|
|
283
503
|
@f.inputs([[:textarea, {:name=>'foo'}], [:text, {:id=>'bar'}]]).to_s.should == '<fieldset class="inputs"><textarea name="foo"></textarea><input id="bar" type="text"/></fieldset>'
|
284
504
|
end
|
285
505
|
|
506
|
+
specify "should have #inputs accept transformer options to modify the options inside the inputs" do
|
507
|
+
@f.inputs([:textarea, :text], :wrapper=>:div).to_s.should == '<fieldset class="inputs"><div><textarea></textarea></div><div><input type="text"/></div></fieldset>'
|
508
|
+
end
|
509
|
+
|
510
|
+
specify "should have #inputs accept :nested_inputs_wrapper options to modify the :input_wrapper option inside the inputs" do
|
511
|
+
@f.inputs(:nested_inputs_wrapper=>:div){@f.inputs([:textarea, :text])}.to_s.should == '<fieldset class="inputs"><div><textarea></textarea><input type="text"/></div></fieldset>'
|
512
|
+
end
|
513
|
+
|
286
514
|
specify "should escape tag content" do
|
287
515
|
@f.tag(:div, {}, ['<p></p>']).to_s.should == '<div><p></p></div>'
|
288
516
|
end
|
@@ -376,8 +604,14 @@ describe "Forme plain forms" do
|
|
376
604
|
f.input(:textarea, :name=>"foo").to_s.should == '<textarea cols="80" name="foo" rows="6"></textarea>'
|
377
605
|
end
|
378
606
|
|
607
|
+
specify "should work with input_defaults with symbol keys using using inputs with symbol keys" do
|
608
|
+
f = Forme::Form.new(:input_defaults=>{:text=>{:size=>20}, 'text'=>{:size=>30}})
|
609
|
+
f.input(:text, :name=>"foo").to_s.should == '<input name="foo" size="20" type="text"/>'
|
610
|
+
f.input('text', :name=>"foo").to_s.should == '<input name="foo" size="30" type="text"/>'
|
611
|
+
end
|
612
|
+
|
379
613
|
specify "invalid custom transformers should raise an Error" do
|
380
|
-
proc{Forme::Form.new(:wrapper=>Object.new)}.should raise_error(Forme::Error)
|
614
|
+
proc{Forme::Form.new(:wrapper=>Object.new).input(:text).to_s}.should raise_error(Forme::Error)
|
381
615
|
proc{@f.input(:textarea, :wrapper=>Object.new).to_s}.should raise_error(Forme::Error)
|
382
616
|
proc{@f.input(:textarea, :formatter=>nil).to_s}.should raise_error(Forme::Error)
|
383
617
|
end
|
@@ -415,11 +649,11 @@ end
|
|
415
649
|
|
416
650
|
describe "Forme custom" do
|
417
651
|
specify "formatters can be specified as a proc" do
|
418
|
-
Forme::Form.new(:formatter=>proc{|i| i.form._tag(:textarea, i.opts
|
652
|
+
Forme::Form.new(:formatter=>proc{|i| i.form._tag(:textarea, i.opts[:name]=>:name)}).input(:text, :name=>'foo').to_s.should == '<textarea foo="name"></textarea>'
|
419
653
|
end
|
420
654
|
|
421
655
|
specify "serializers can be specified as a proc" do
|
422
|
-
Forme::Form.new(:serializer=>proc{|t| "#{t.type} = #{t.opts
|
656
|
+
Forme::Form.new(:serializer=>proc{|t| "#{t.type} = #{t.opts[:name]}"}).input(:textarea, :name=>'foo').to_s.should == 'textarea = foo'
|
423
657
|
end
|
424
658
|
|
425
659
|
specify "labelers can be specified as a proc" do
|
@@ -441,7 +675,7 @@ end
|
|
441
675
|
|
442
676
|
describe "Forme built-in custom" do
|
443
677
|
specify "transformers should raise if the there is no matching transformer" do
|
444
|
-
proc{Forme::Form.new(:formatter=>:foo)}.should raise_error(Forme::Error)
|
678
|
+
proc{Forme::Form.new(:formatter=>:foo).input(:text).to_s}.should raise_error(Forme::Error)
|
445
679
|
end
|
446
680
|
|
447
681
|
specify "formatter: disabled disables all inputs unless :disabled=>false option" do
|
@@ -463,28 +697,42 @@ describe "Forme built-in custom" do
|
|
463
697
|
Forme::Form.new(:labeler=>:explicit).input(:textarea, :id=>'foo', :label=>'bar').to_s.should == '<label for="foo">bar</label><textarea id="foo"></textarea>'
|
464
698
|
end
|
465
699
|
|
700
|
+
specify "labeler: explicit handles the key option correctly" do
|
701
|
+
Forme::Form.new(:labeler=>:explicit, :namespace=>:baz).input(:textarea, :key=>'foo', :label=>'bar').to_s.should == '<label for="baz_foo">bar</label><textarea id="baz_foo" name="baz[foo]"></textarea>'
|
702
|
+
end
|
703
|
+
|
466
704
|
specify "labeler: explicit should handle tags with errors" do
|
467
705
|
Forme::Form.new(:labeler=>:explicit).input(:text, :error=>'Bad Stuff!', :value=>'f', :id=>'foo', :label=>'bar').to_s.should == '<label for="foo">bar</label><input class="error" id="foo" type="text" value="f"/><span class="error_message">Bad Stuff!</span>'
|
468
706
|
end
|
469
707
|
|
470
708
|
specify "wrapper: li wraps tag in an li" do
|
471
709
|
Forme::Form.new(:wrapper=>:li).input(:textarea, :id=>'foo').to_s.should == '<li><textarea id="foo"></textarea></li>'
|
710
|
+
Forme::Form.new(:wrapper=>:li).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<li id="bar"><textarea id="foo"></textarea></li>'
|
472
711
|
end
|
473
712
|
|
474
713
|
specify "wrapper: p wraps tag in an p" do
|
475
714
|
Forme::Form.new(:wrapper=>:p).input(:textarea, :id=>'foo').to_s.should == '<p><textarea id="foo"></textarea></p>'
|
715
|
+
Forme::Form.new(:wrapper=>:p).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<p id="bar"><textarea id="foo"></textarea></p>'
|
476
716
|
end
|
477
717
|
|
478
718
|
specify "wrapper: div wraps tag in an div" do
|
479
719
|
Forme::Form.new(:wrapper=>:div).input(:textarea, :id=>'foo').to_s.should == '<div><textarea id="foo"></textarea></div>'
|
720
|
+
Forme::Form.new(:wrapper=>:div).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<div id="bar"><textarea id="foo"></textarea></div>'
|
480
721
|
end
|
481
722
|
|
482
723
|
specify "wrapper: span wraps tag in an span" do
|
483
724
|
Forme::Form.new(:wrapper=>:span).input(:textarea, :id=>'foo').to_s.should == '<span><textarea id="foo"></textarea></span>'
|
725
|
+
Forme::Form.new(:wrapper=>:span).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<span id="bar"><textarea id="foo"></textarea></span>'
|
726
|
+
end
|
727
|
+
|
728
|
+
specify "wrapper: td wraps tag in an td" do
|
729
|
+
Forme::Form.new(:wrapper=>:td).input(:textarea, :id=>'foo').to_s.should == '<td><textarea id="foo"></textarea></td>'
|
730
|
+
Forme::Form.new(:wrapper=>:td).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<td id="bar"><textarea id="foo"></textarea></td>'
|
484
731
|
end
|
485
732
|
|
486
733
|
specify "wrapper: trtd wraps tag in an tr/td" do
|
487
734
|
Forme::Form.new(:wrapper=>:trtd).input(:textarea, :id=>'foo').to_s.should == '<tr><td><textarea id="foo"></textarea></td><td></td></tr>'
|
735
|
+
Forme::Form.new(:wrapper=>:trtd).input(:textarea, :id=>'foo', :wrapper_attr=>{:id=>'bar'}).to_s.should == '<tr id="bar"><td><textarea id="foo"></textarea></td><td></td></tr>'
|
488
736
|
end
|
489
737
|
|
490
738
|
specify "wrapper: trtd supports multiple tags in separate tds" do
|
@@ -499,12 +747,44 @@ describe "Forme built-in custom" do
|
|
499
747
|
Forme::Form.new(:wrapper=>:trtd, :labeler=>:explicit).input(:checkbox, :id=>'foo', :name=>'foo', :label=>'Foo').to_s.should == '<tr><td><label for="foo">Foo</label></td><td><input id="foo_hidden" name="foo" type="hidden" value="0"/><input id="foo" name="foo" type="checkbox"/></td></tr>'
|
500
748
|
end
|
501
749
|
|
750
|
+
specify "wrapper: tr should use a td wrapper and tr inputs_wrapper" do
|
751
|
+
Forme::Form.new(:wrapper=>:tr).inputs([:textarea]).to_s.should == '<tr><td><textarea></textarea></td></tr>'
|
752
|
+
f = Forme::Form.new
|
753
|
+
f.with_opts(:wrapper=>:tr){f.inputs([:textarea])}.to_s.should == '<tr><td><textarea></textarea></td></tr>'
|
754
|
+
end
|
755
|
+
|
756
|
+
specify "wrapper: table should use a trtd wrapper and table inputs_wrapper" do
|
757
|
+
Forme::Form.new(:wrapper=>:table).inputs([:textarea]).to_s.should == '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
|
758
|
+
f = Forme::Form.new
|
759
|
+
f.with_opts(:wrapper=>:table){f.inputs([:textarea])}.to_s.should == '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
|
760
|
+
end
|
761
|
+
|
762
|
+
specify "wrapper: ol should use an li wrapper and ol inputs_wrapper" do
|
763
|
+
Forme::Form.new(:wrapper=>:ol).inputs([:textarea]).to_s.should == '<ol><li><textarea></textarea></li></ol>'
|
764
|
+
f = Forme::Form.new
|
765
|
+
f.with_opts(:wrapper=>:ol){f.inputs([:textarea])}.to_s.should == '<ol><li><textarea></textarea></li></ol>'
|
766
|
+
end
|
767
|
+
|
768
|
+
specify "wrapper: fieldset_ol should use an li wrapper and fieldset_ol inputs_wrapper" do
|
769
|
+
Forme::Form.new(:wrapper=>:fieldset_ol).inputs([:textarea]).to_s.should == '<fieldset class="inputs"><ol><li><textarea></textarea></li></ol></fieldset>'
|
770
|
+
f = Forme::Form.new
|
771
|
+
f.with_opts(:wrapper=>:fieldset_ol){f.inputs([:textarea])}.to_s.should == '<fieldset class="inputs"><ol><li><textarea></textarea></li></ol></fieldset>'
|
772
|
+
end
|
773
|
+
|
774
|
+
specify "wrapper should not override inputs_wrapper if both given" do
|
775
|
+
Forme::Form.new(:wrapper=>:tr, :inputs_wrapper=>:div).inputs([:textarea]).to_s.should == '<div><td><textarea></textarea></td></div>'
|
776
|
+
f = Forme::Form.new
|
777
|
+
f.with_opts(:wrapper=>:tr, :inputs_wrapper=>:div){f.inputs([:textarea])}.to_s.should == '<div><td><textarea></textarea></td></div>'
|
778
|
+
end
|
779
|
+
|
502
780
|
specify "inputs_wrapper: ol wraps tags in an ol" do
|
503
781
|
Forme::Form.new(:inputs_wrapper=>:ol, :wrapper=>:li).inputs([:textarea]).to_s.should == '<ol><li><textarea></textarea></li></ol>'
|
782
|
+
Forme::Form.new(:inputs_wrapper=>:ol, :wrapper=>:li).inputs([:textarea], :attr=>{:foo=>1}).to_s.should == '<ol foo="1"><li><textarea></textarea></li></ol>'
|
504
783
|
end
|
505
784
|
|
506
785
|
specify "inputs_wrapper: fieldset_ol wraps tags in a fieldset and an ol" do
|
507
786
|
Forme::Form.new(:inputs_wrapper=>:fieldset_ol, :wrapper=>:li).inputs([:textarea]).to_s.should == '<fieldset class="inputs"><ol><li><textarea></textarea></li></ol></fieldset>'
|
787
|
+
Forme::Form.new(:inputs_wrapper=>:fieldset_ol, :wrapper=>:li).inputs([:textarea], :attr=>{:foo=>1}).to_s.should == '<fieldset class="inputs" foo="1"><ol><li><textarea></textarea></li></ol></fieldset>'
|
508
788
|
end
|
509
789
|
|
510
790
|
specify "inputs_wrapper: fieldset_ol supports a :legend option" do
|
@@ -513,10 +793,33 @@ describe "Forme built-in custom" do
|
|
513
793
|
|
514
794
|
specify "inputs_wrapper: div wraps tags in a div" do
|
515
795
|
Forme::Form.new(:inputs_wrapper=>:div, :wrapper=>:span).inputs([:textarea]).to_s.should == '<div><span><textarea></textarea></span></div>'
|
796
|
+
Forme::Form.new(:inputs_wrapper=>:div, :wrapper=>:span).inputs([:textarea], :attr=>{:foo=>1}).to_s.should == '<div foo="1"><span><textarea></textarea></span></div>'
|
797
|
+
end
|
798
|
+
|
799
|
+
specify "inputs_wrapper: tr wraps tags in an tr" do
|
800
|
+
Forme::Form.new(:inputs_wrapper=>:tr, :wrapper=>:td).inputs([:textarea]).to_s.should == '<tr><td><textarea></textarea></td></tr>'
|
801
|
+
Forme::Form.new(:inputs_wrapper=>:tr, :wrapper=>:td).inputs([:textarea], :attr=>{:foo=>1}).to_s.should == '<tr foo="1"><td><textarea></textarea></td></tr>'
|
516
802
|
end
|
517
803
|
|
518
804
|
specify "inputs_wrapper: table wraps tags in an table" do
|
519
805
|
Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea]).to_s.should == '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
|
806
|
+
Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :attr=>{:foo=>1}).to_s.should == '<table foo="1"><tr><td><textarea></textarea></td><td></td></tr></table>'
|
807
|
+
end
|
808
|
+
|
809
|
+
specify "inputs_wrapper: table accepts a :legend option" do
|
810
|
+
Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs').to_s.should == '<table><caption>Inputs</caption><tr><td><textarea></textarea></td><td></td></tr></table>'
|
811
|
+
end
|
812
|
+
|
813
|
+
specify "inputs_wrapper: table accepts a :legend_attr option" do
|
814
|
+
Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs', :legend_attr=>{:class=>'foo'}).to_s.should == '<table><caption class="foo">Inputs</caption><tr><td><textarea></textarea></td><td></td></tr></table>'
|
815
|
+
end
|
816
|
+
|
817
|
+
specify "inputs_wrapper: table accepts a :labels option" do
|
818
|
+
Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>%w'A B C').to_s.should == '<table><tr><th>A</th><th>B</th><th>C</th></tr></table>'
|
819
|
+
end
|
820
|
+
|
821
|
+
specify "inputs_wrapper: table doesn't add empty header row for :labels=>[]" do
|
822
|
+
Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>[]).to_s.should == '<table></table>'
|
520
823
|
end
|
521
824
|
|
522
825
|
specify "serializer: html_usa formats dates and datetimes in American format without timezones" do
|
@@ -630,6 +933,14 @@ describe "Forme object forms" do
|
|
630
933
|
Forme::Form.new([:foo]).input(:first, :attr=>{:x=>'bar'}).to_s.should == '<input id="first" name="first" type="text" value="foo" x="bar"/>'
|
631
934
|
end
|
632
935
|
|
936
|
+
specify "should respect current namespace" do
|
937
|
+
Forme::Form.new([:foo], :namespace=>'a').input(:first).to_s.should == '<input id="a_first" name="a[first]" type="text" value="foo"/>'
|
938
|
+
end
|
939
|
+
|
940
|
+
specify "should get values for hashes using #[]" do
|
941
|
+
Forme::Form.new(:obj=>{:bar=>:foo}, :namespace=>'a').input(:bar).to_s.should == '<input id="a_bar" name="a[bar]" type="text" value="foo"/>'
|
942
|
+
end
|
943
|
+
|
633
944
|
specify "should handle obj passed in via :obj hash key" do
|
634
945
|
Forme::Form.new(:obj=>[:foo]).input(:first).to_s.should == '<input id="first" name="first" type="text" value="foo"/>'
|
635
946
|
end
|