forme 0.9.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|