forme 1.11.0 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG +54 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +235 -209
- data/Rakefile +1 -7
- data/lib/forme/bs3.rb +18 -4
- data/lib/forme/erb.rb +13 -25
- data/lib/forme/form.rb +144 -149
- data/lib/forme/input.rb +1 -1
- data/lib/forme/rails.rb +39 -83
- data/lib/forme/raw.rb +2 -2
- data/lib/forme/tag.rb +3 -12
- data/lib/forme/template.rb +110 -0
- data/lib/forme/transformers/formatter.rb +4 -1
- data/lib/forme/transformers/helper.rb +0 -1
- data/lib/forme/transformers/inputs_wrapper.rb +4 -4
- data/lib/forme/version.rb +2 -2
- data/lib/forme.rb +15 -2
- data/lib/roda/plugins/forme.rb +1 -1
- data/lib/roda/plugins/forme_erubi_capture.rb +57 -0
- data/lib/roda/plugins/forme_route_csrf.rb +16 -34
- data/lib/roda/plugins/forme_set.rb +39 -76
- data/lib/sequel/plugins/forme.rb +40 -50
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/lib/sequel/plugins/forme_set.rb +3 -1
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +18 -18
- data/spec/bs3_sequel_plugin_spec.rb +17 -17
- data/spec/bs3_spec.rb +23 -11
- data/spec/erb_helper.rb +69 -58
- data/spec/erubi_capture_helper.rb +198 -0
- data/spec/forme_spec.rb +21 -32
- data/spec/rails_integration_spec.rb +39 -25
- data/spec/roda_integration_spec.rb +118 -70
- data/spec/sequel_helper.rb +0 -1
- data/spec/sequel_i18n_helper.rb +1 -1
- data/spec/sequel_i18n_plugin_spec.rb +3 -2
- data/spec/sequel_plugin_spec.rb +29 -12
- data/spec/sequel_set_plugin_spec.rb +9 -2
- data/spec/shared_erb_specs.rb +71 -0
- data/spec/sinatra_integration_spec.rb +5 -6
- data/spec/spec_helper.rb +21 -8
- metadata +9 -7
- data/lib/forme/erb_form.rb +0 -74
- data/lib/forme/sinatra.rb +0 -17
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
require 'rack/utils'
|
4
|
-
|
4
|
+
require_relative '../../forme/template'
|
5
5
|
|
6
6
|
class Roda
|
7
7
|
module RodaPlugins
|
@@ -34,74 +34,6 @@ class Roda
|
|
34
34
|
:missing_namespace=>"no content in expected namespace"
|
35
35
|
}.freeze
|
36
36
|
|
37
|
-
# Forme::Form subclass that adds hidden fields with metadata that can be used
|
38
|
-
# to automatically process form submissions.
|
39
|
-
class Form < ::Forme::ERB::Form
|
40
|
-
def initialize(obj, opts=nil)
|
41
|
-
super
|
42
|
-
@forme_namespaces = @opts[:namespace]
|
43
|
-
end
|
44
|
-
|
45
|
-
# Try adding hidden fields to all forms
|
46
|
-
def form(*)
|
47
|
-
if block_given?
|
48
|
-
super do |f|
|
49
|
-
yield f
|
50
|
-
hmac_hidden_fields
|
51
|
-
end
|
52
|
-
else
|
53
|
-
t = super
|
54
|
-
if tags = hmac_hidden_fields
|
55
|
-
tags.each{|tag| t << tag}
|
56
|
-
end
|
57
|
-
t
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
# Add hidden fields with metadata, if the form has an object associated that
|
64
|
-
# supports the forme_inputs method, and it includes inputs.
|
65
|
-
def hmac_hidden_fields
|
66
|
-
if (obj = @opts[:obj]) && obj.respond_to?(:forme_inputs) && (forme_inputs = obj.forme_inputs)
|
67
|
-
columns = []
|
68
|
-
valid_values = {}
|
69
|
-
|
70
|
-
forme_inputs.each do |field, input|
|
71
|
-
next unless col = obj.send(:forme_column_for_input, input)
|
72
|
-
col = col.to_s
|
73
|
-
columns << col
|
74
|
-
|
75
|
-
next unless validation = obj.send(:forme_validation_for_input, field, input)
|
76
|
-
validation[0] = validation[0].to_s
|
77
|
-
has_nil = false
|
78
|
-
validation[1] = validation[1].map do |v|
|
79
|
-
has_nil ||= v.nil?
|
80
|
-
v.to_s
|
81
|
-
end
|
82
|
-
validation[1] << nil if has_nil
|
83
|
-
valid_values[col] = validation
|
84
|
-
end
|
85
|
-
|
86
|
-
return if columns.empty?
|
87
|
-
|
88
|
-
data = {}
|
89
|
-
data['columns'] = columns
|
90
|
-
data['namespaces'] = @forme_namespaces
|
91
|
-
data['csrf'] = @opts[:csrf]
|
92
|
-
data['valid_values'] = valid_values unless valid_values.empty?
|
93
|
-
data['form_version'] = @opts[:form_version] if @opts[:form_version]
|
94
|
-
|
95
|
-
data = data.to_json
|
96
|
-
tags = []
|
97
|
-
tags << tag(:input, :type=>:hidden, :name=>:_forme_set_data, :value=>data)
|
98
|
-
tags << tag(:input, :type=>:hidden, :name=>:_forme_set_data_hmac, :value=>OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA512.new, @opts[:roda].class.opts[:forme_set_hmac_secret], data))
|
99
|
-
tags.each{|tag| emit(tag)}
|
100
|
-
tags
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
37
|
module InstanceMethods
|
106
38
|
# Return hash based on submitted parameters, with :values key
|
107
39
|
# being submitted values for the object, and :validations key
|
@@ -151,15 +83,46 @@ class Roda
|
|
151
83
|
raise Error, ERROR_MESSAGES[type]
|
152
84
|
end
|
153
85
|
|
154
|
-
# Use form class that adds hidden fields for metadata.
|
155
|
-
def _forme_form_class
|
156
|
-
Form
|
157
|
-
end
|
158
|
-
|
159
86
|
# Include a reference to the current scope to the form. This reference is needed
|
160
87
|
# to correctly construct the HMAC.
|
161
|
-
def _forme_form_options(
|
162
|
-
|
88
|
+
def _forme_form_options(obj, attr, opts)
|
89
|
+
super
|
90
|
+
|
91
|
+
opts[:_after] = lambda do |form|
|
92
|
+
if (obj = form.opts[:obj]) && obj.respond_to?(:forme_inputs) && (forme_inputs = obj.forme_inputs)
|
93
|
+
columns = []
|
94
|
+
valid_values = {}
|
95
|
+
|
96
|
+
forme_inputs.each do |field, input|
|
97
|
+
next unless col = obj.send(:forme_column_for_input, input)
|
98
|
+
col = col.to_s
|
99
|
+
columns << col
|
100
|
+
|
101
|
+
next unless validation = obj.send(:forme_validation_for_input, field, input)
|
102
|
+
validation[0] = validation[0].to_s
|
103
|
+
has_nil = false
|
104
|
+
validation[1] = validation[1].map do |v|
|
105
|
+
has_nil ||= v.nil?
|
106
|
+
v.to_s
|
107
|
+
end
|
108
|
+
validation[1] << nil if has_nil
|
109
|
+
valid_values[col] = validation
|
110
|
+
end
|
111
|
+
|
112
|
+
return if columns.empty?
|
113
|
+
|
114
|
+
data = {}
|
115
|
+
data['columns'] = columns
|
116
|
+
data['namespaces'] = form.opts[:namespace]
|
117
|
+
data['csrf'] = form.opts[:csrf]
|
118
|
+
data['valid_values'] = valid_values unless valid_values.empty?
|
119
|
+
data['form_version'] = form.opts[:form_version] if form.opts[:form_version]
|
120
|
+
|
121
|
+
data = data.to_json
|
122
|
+
form.tag(:input, :type=>:hidden, :name=>:_forme_set_data, :value=>data)
|
123
|
+
form.tag(:input, :type=>:hidden, :name=>:_forme_set_data_hmac, :value=>OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA512.new, self.class.opts[:forme_set_hmac_secret], data))
|
124
|
+
end
|
125
|
+
end
|
163
126
|
end
|
164
127
|
|
165
128
|
# Internals of forme_parse_hmac and forme_set_hmac.
|
data/lib/sequel/plugins/forme.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'thread'
|
3
|
+
require_relative '../../forme'
|
5
4
|
|
6
5
|
module Sequel # :nodoc:
|
7
6
|
module Plugins # :nodoc:
|
@@ -37,7 +36,8 @@ module Sequel # :nodoc:
|
|
37
36
|
# of the association for the form's +obj+. Inside the block, calls to
|
38
37
|
# the +input+ and +inputs+ methods for the receiver treat the associated
|
39
38
|
# object as the recevier's +obj+, using name and id attributes that work
|
40
|
-
# with the Sequel +nested_attributes+ plugin.
|
39
|
+
# with the Sequel +nested_attributes+ plugin. Returns the HTML generated by
|
40
|
+
# the subform.
|
41
41
|
#
|
42
42
|
# The following options are currently supported:
|
43
43
|
# :inputs :: Automatically call +inputs+ with the given values. Using
|
@@ -59,45 +59,50 @@ module Sequel # :nodoc:
|
|
59
59
|
# :skip_primary_key :: Skip adding a hidden primary key field for existing
|
60
60
|
# objects.
|
61
61
|
def subform(association, opts={}, &block)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
content_added do
|
63
|
+
nested_obj = opts.has_key?(:obj) ? opts[:obj] : obj.send(association)
|
64
|
+
ref = obj.class.association_reflection(association)
|
65
|
+
multiple = ref.returns_array?
|
66
|
+
grid = opts[:grid]
|
67
|
+
ns = "#{association}_attributes"
|
67
68
|
|
68
|
-
contents = proc do
|
69
69
|
send(multiple ? :each_obj : :with_obj, nested_obj, ns) do |no, i|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
70
|
+
input(ref.associated_class.primary_key, :type=>:hidden, :label=>nil, :wrapper=>nil) unless no.new? || opts[:skip_primary_key]
|
71
|
+
end
|
72
|
+
|
73
|
+
contents = proc do
|
74
|
+
send(multiple ? :each_obj : :with_obj, nested_obj, ns) do |no, i|
|
75
|
+
options = opts.dup
|
76
|
+
if grid
|
77
|
+
options.delete(:legend)
|
79
78
|
else
|
80
|
-
if
|
81
|
-
options[:legend]
|
79
|
+
if options.has_key?(:legend)
|
80
|
+
if options[:legend].respond_to?(:call)
|
81
|
+
options[:legend] = multiple ? options[:legend].call(no, i) : options[:legend].call(no)
|
82
|
+
end
|
82
83
|
else
|
83
|
-
|
84
|
+
if multiple
|
85
|
+
options[:legend] = humanize("#{obj.model.send(:singularize, association)} ##{i+1}")
|
86
|
+
else
|
87
|
+
options[:legend] = humanize(association)
|
88
|
+
end
|
84
89
|
end
|
85
90
|
end
|
91
|
+
options[:subform] = true
|
92
|
+
|
93
|
+
inputs(options[:inputs]||[], options, &block)
|
86
94
|
end
|
87
|
-
|
88
|
-
|
95
|
+
end
|
96
|
+
|
97
|
+
if grid
|
98
|
+
labels = opts.fetch(:labels){opts[:inputs].map{|l, *| humanize(l)} if opts[:inputs]}
|
99
|
+
legend = opts.fetch(:legend){humanize(association)}
|
100
|
+
inputs_opts = opts[:inputs_opts] || {}
|
101
|
+
inputs(inputs_opts.merge(:inputs_wrapper=>:table, :nested_inputs_wrapper=>:tr, :wrapper=>:td, :labeler=>nil, :labels=>labels, :legend=>legend), &contents)
|
102
|
+
else
|
103
|
+
contents.call
|
89
104
|
end
|
90
105
|
end
|
91
|
-
|
92
|
-
if grid
|
93
|
-
labels = opts.fetch(:labels){opts[:inputs].map{|l, *| humanize(l)} if opts[:inputs]}
|
94
|
-
legend = opts.fetch(:legend){humanize(association)}
|
95
|
-
inputs_opts = opts[:inputs_opts] || {}
|
96
|
-
inputs(inputs_opts.merge(:inputs_wrapper=>:table, :nested_inputs_wrapper=>:tr, :wrapper=>:td, :labeler=>nil, :labels=>labels, :legend=>legend), &contents)
|
97
|
-
else
|
98
|
-
contents.call
|
99
|
-
end
|
100
|
-
nil
|
101
106
|
end
|
102
107
|
end
|
103
108
|
|
@@ -192,6 +197,7 @@ module Sequel # :nodoc:
|
|
192
197
|
|
193
198
|
# Set the error option correctly if the field contains errors
|
194
199
|
def handle_errors(f)
|
200
|
+
return if opts.has_key?(:error)
|
195
201
|
if e = obj.errors.on(f)
|
196
202
|
opts[:error] = e.join(', ')
|
197
203
|
end
|
@@ -346,7 +352,7 @@ module Sequel # :nodoc:
|
|
346
352
|
|
347
353
|
# Delegate to the +form+.
|
348
354
|
def humanize(s)
|
349
|
-
form.humanize(s)
|
355
|
+
form.respond_to?(:humanize) ? form.humanize(s) : s.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
350
356
|
end
|
351
357
|
|
352
358
|
# If the column allows +NULL+ values, use a three-valued select
|
@@ -451,21 +457,6 @@ module Sequel # :nodoc:
|
|
451
457
|
end
|
452
458
|
end
|
453
459
|
|
454
|
-
# Helper module used for Sequel forms using ERB template integration. Necessary for
|
455
|
-
# proper subform handling when using such forms with partials.
|
456
|
-
module ERBSequelForm
|
457
|
-
# Capture the inside of the inputs, injecting it into the template
|
458
|
-
# if a block is given, or returning it as a string if not.
|
459
|
-
def subform(*, &block)
|
460
|
-
if block
|
461
|
-
capture(block){super}
|
462
|
-
else
|
463
|
-
capture{super}
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
SinatraSequelForm = ERBSequelForm
|
468
|
-
|
469
460
|
class Form < ::Forme::Form
|
470
461
|
include SequelForm
|
471
462
|
end
|
@@ -485,7 +476,6 @@ module Sequel # :nodoc:
|
|
485
476
|
unless klass = MUTEX.synchronize{FORM_CLASSES[base]}
|
486
477
|
klass = Class.new(base)
|
487
478
|
klass.send(:include, SequelForm)
|
488
|
-
klass.send(:include, ERBSequelForm) if defined?(::Forme::ERB::Form) && base == ::Forme::ERB::Form
|
489
479
|
MUTEX.synchronize{FORM_CLASSES[base] = klass}
|
490
480
|
end
|
491
481
|
klass
|
@@ -18,6 +18,7 @@ module Sequel # :nodoc:
|
|
18
18
|
module InstanceMethods
|
19
19
|
# Hash with column name symbol keys and Forme::SequelInput values
|
20
20
|
def forme_inputs
|
21
|
+
return (@forme_inputs || {}) if frozen?
|
21
22
|
@forme_inputs ||= {}
|
22
23
|
end
|
23
24
|
|
@@ -25,12 +26,13 @@ module Sequel # :nodoc:
|
|
25
26
|
# is a boolean flag, if true, the uploaded values should be a subset of the allowed values,
|
26
27
|
# otherwise, there should be a single uploaded value that is a member of the allowed values.
|
27
28
|
def forme_validations
|
29
|
+
return (@forme_validations || {}) if frozen?
|
28
30
|
@forme_validations ||= {}
|
29
31
|
end
|
30
32
|
|
31
33
|
# Keep track of the inputs used.
|
32
34
|
def forme_input(_form, field, _opts)
|
33
|
-
forme_inputs[field] = super
|
35
|
+
frozen? ? super : (forme_inputs[field] = super)
|
34
36
|
end
|
35
37
|
|
36
38
|
# Given the hash of submitted parameters, return a hash containing information on how to
|
data/spec/all.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
$: << 'lib'
|
2
|
-
Dir
|
2
|
+
Dir.new(File.dirname(__FILE__)).each{|f| require_relative f if f.end_with?('_spec.rb')}
|
data/spec/bs3_reference_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
|
+
require_relative '../lib/forme/bs3'
|
4
4
|
|
5
5
|
describe "Forme Bootstrap3 (BS3) forms" do
|
6
6
|
def sel(opts, s)
|
@@ -33,7 +33,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should create an input[:text] tag with a label when ':id => bar' with an error" do
|
36
|
-
@f.input(:text, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-text-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="text"/><span class="help-block with-errors">input-text-error</span></div>'
|
36
|
+
@f.input(:text, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-text-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input aria-describedby="bar_error_message" aria-invalid="true" class="form-control foo" id="bar" type="text"/><span class="help-block with-errors">input-text-error</span></div>'
|
37
37
|
end
|
38
38
|
|
39
39
|
describe 'from a Sequel model' do
|
@@ -43,7 +43,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
43
43
|
|
44
44
|
it "should correctly handle an input[:text] tag from Sequel model with error" do
|
45
45
|
@ac.errors.add(:name, 'name not valid')
|
46
|
-
@c.input(:name).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <input class="form-control" id="album_name" maxlength="255" name="album[name]" type="text" value="c"/><span class="help-block with-errors">name not valid</span></div>'
|
46
|
+
@c.input(:name).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <input aria-describedby="album_name_error_message" aria-invalid="true" class="form-control" id="album_name" maxlength="255" name="album[name]" type="text" value="c"/><span class="help-block with-errors">name not valid</span></div>'
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -66,7 +66,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should create an input[:password] tag with a label when ':id => bar' with an error" do
|
69
|
-
@f.input(:password, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-password-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="password"/><span class="help-block with-errors">input-password-error</span></div>'
|
69
|
+
@f.input(:password, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-password-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input aria-describedby="bar_error_message" aria-invalid="true" class="form-control foo" id="bar" type="password"/><span class="help-block with-errors">input-password-error</span></div>'
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -88,7 +88,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should create an input[:email] tag with a label when ':id => bar' with an error" do
|
91
|
-
@f.input(:email, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-email-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="email"/><span class="help-block with-errors">input-email-error</span></div>'
|
91
|
+
@f.input(:email, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-email-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input aria-describedby="bar_error_message" aria-invalid="true" class="form-control foo" id="bar" type="email"/><span class="help-block with-errors">input-email-error</span></div>'
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -110,7 +110,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should create an input[:file] tag with a label when ':id => bar' with an error" do
|
113
|
-
@f.input(:file, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-file-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="foo" id="bar" type="file"/><span class="help-block with-errors">input-file-error</span></div>'
|
113
|
+
@f.input(:file, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-file-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input aria-describedby="bar_error_message" aria-invalid="true" class="foo" id="bar" type="file"/><span class="help-block with-errors">input-file-error</span></div>'
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -132,7 +132,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
it "should create an input[:submit] tag without error message " do
|
135
|
-
@f.input(:submit, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input class="btn btn-default" id="foo" type="submit" value="Save"/>'
|
135
|
+
@f.input(:submit, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input aria-describedby="foo_error_message" aria-invalid="true" class="btn btn-default" id="foo" type="submit" value="Save"/>'
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
@@ -154,7 +154,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
154
154
|
end
|
155
155
|
|
156
156
|
it "should create an input[:reset] tag without error message " do
|
157
|
-
@f.input(:reset, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input class="btn btn-default" id="foo" type="reset" value="Save"/>'
|
157
|
+
@f.input(:reset, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input aria-describedby="foo_error_message" aria-invalid="true" class="btn btn-default" id="foo" type="reset" value="Save"/>'
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
@@ -180,7 +180,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
180
180
|
end
|
181
181
|
|
182
182
|
it "should create a textarea tag with .has-error and error message when ':error => is-a-string'" do
|
183
|
-
@f.input(:textarea, :error=>'input-textarea-error').to_s.must_equal '<div class="form-group has-error"><textarea class="form-control"></textarea><span class="help-block with-errors">input-textarea-error</span></div>'
|
183
|
+
@f.input(:textarea, :error=>'input-textarea-error').to_s.must_equal '<div class="form-group has-error"><textarea aria-invalid="true" class="form-control"></textarea><span class="help-block with-errors">input-textarea-error</span></div>'
|
184
184
|
end
|
185
185
|
|
186
186
|
describe 'from a Sequel model' do
|
@@ -190,7 +190,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
190
190
|
|
191
191
|
it "should correctly handle an input[:text] tag from Sequel model with error" do
|
192
192
|
@ac.errors.add(:name, 'name not valid')
|
193
|
-
@c.input(:name, :as=>:textarea).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <textarea class="form-control" id="album_name" maxlength="255" name="album[name]">c</textarea><span class="help-block with-errors">name not valid</span></div>'
|
193
|
+
@c.input(:name, :as=>:textarea).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <textarea aria-describedby="album_name_error_message" aria-invalid="true" class="form-control" id="album_name" maxlength="255" name="album[name]">c</textarea><span class="help-block with-errors">name not valid</span></div>'
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
@@ -225,7 +225,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
225
225
|
end
|
226
226
|
|
227
227
|
it "should create a select tag with .has-error and error message when ':error => is-a-string'" do
|
228
|
-
@f.input(:select, :error=>'input-select-error').to_s.must_equal '<div class="form-group has-error"><select class="form-control"></select><span class="help-block with-errors">input-select-error</span></div>'
|
228
|
+
@f.input(:select, :error=>'input-select-error').to_s.must_equal '<div class="form-group has-error"><select aria-invalid="true" class="form-control"></select><span class="help-block with-errors">input-select-error</span></div>'
|
229
229
|
end
|
230
230
|
|
231
231
|
it "should correctly handle a Sequel model output :as => :select" do
|
@@ -234,7 +234,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
234
234
|
|
235
235
|
it "should correctly handle a Sequel model output :as => :select with error" do
|
236
236
|
@ac.errors.add(:artist, 'error message')
|
237
|
-
@c.input(:artist, :as=>:select).to_s.must_equal '<div class="form-group has-error many_to_one"><label for="album_artist_id">Artist</label> <select class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select><span class="help-block with-errors">error message</span></div>'
|
237
|
+
@c.input(:artist, :as=>:select).to_s.must_equal '<div class="form-group has-error many_to_one"><label for="album_artist_id">Artist</label> <select aria-describedby="album_artist_id_error_message" aria-invalid="true" class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select><span class="help-block with-errors">error message</span></div>'
|
238
238
|
end
|
239
239
|
|
240
240
|
describe 'from a Sequel model' do
|
@@ -244,7 +244,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
244
244
|
|
245
245
|
it "should correctly handle a boolean attribute from a Sequel model with an error" do
|
246
246
|
@ac.errors.add(:gold, 'error message')
|
247
|
-
@c.input(:gold).to_s.must_equal '<div class="boolean form-group has-error"><label for="album_gold">Gold</label> <select class="form-control" id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select><span class="help-block with-errors">error message</span></div>'
|
247
|
+
@c.input(:gold).to_s.must_equal '<div class="boolean form-group has-error"><label for="album_gold">Gold</label> <select aria-describedby="album_gold_error_message" aria-invalid="true" class="form-control" id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select><span class="help-block with-errors">error message</span></div>'
|
248
248
|
end
|
249
249
|
end
|
250
250
|
end
|
@@ -267,7 +267,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
267
267
|
end
|
268
268
|
|
269
269
|
it "should create an input[:checkbox] tag with a label when ':id => bar' with an error" do
|
270
|
-
@f.input(:checkbox, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-checkbox-error').to_s.must_equal '<div class="has-error"><div class="checkbox"><label for="bar"><input class="foo" id="bar" type="checkbox"/> Gold</label></div><span class="help-block with-errors">input-checkbox-error</span></div>'
|
270
|
+
@f.input(:checkbox, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-checkbox-error').to_s.must_equal '<div class="has-error"><div class="checkbox"><label for="bar"><input aria-describedby="bar_error_message" aria-invalid="true" class="foo" id="bar" type="checkbox"/> Gold</label></div><span class="help-block with-errors">input-checkbox-error</span></div>'
|
271
271
|
end
|
272
272
|
|
273
273
|
describe 'from a Sequel model' do
|
@@ -277,7 +277,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
277
277
|
|
278
278
|
it "should correctly handle a boolean attribute ':as=>:checkbox' with an error" do
|
279
279
|
@ac.errors.add(:gold, 'error message')
|
280
|
-
@c.input(:gold, :as=>:checkbox).to_s.must_equal '<div class="boolean has-error"><div class="checkbox"><label for="album_gold"><input id="album_gold_hidden" name="album[gold]" type="hidden" value="f"/><input checked="checked" id="album_gold" name="album[gold]" type="checkbox" value="t"/> Gold</label></div><span class="help-block with-errors">error message</span></div>'
|
280
|
+
@c.input(:gold, :as=>:checkbox).to_s.must_equal '<div class="boolean has-error"><div class="checkbox"><label for="album_gold"><input id="album_gold_hidden" name="album[gold]" type="hidden" value="f"/><input aria-describedby="album_gold_error_message" aria-invalid="true" checked="checked" id="album_gold" name="album[gold]" type="checkbox" value="t"/> Gold</label></div><span class="help-block with-errors">error message</span></div>'
|
281
281
|
end
|
282
282
|
end
|
283
283
|
end
|
@@ -301,7 +301,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
301
301
|
end
|
302
302
|
|
303
303
|
it "should create an input[:radio] tag with a label when ':id => bar' with an error" do
|
304
|
-
@f.input(:radio, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-radio-error').to_s.must_equal '<div class="has-error"><div class="radio"><label for="bar"><input class="foo" id="bar" type="radio"/> Gold</label></div><span class="help-block with-errors">input-radio-error</span></div>'
|
304
|
+
@f.input(:radio, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-radio-error').to_s.must_equal '<div class="has-error"><div class="radio"><label for="bar"><input aria-describedby="bar_error_message" aria-invalid="true" class="foo" id="bar" type="radio"/> Gold</label></div><span class="help-block with-errors">input-radio-error</span></div>'
|
305
305
|
end
|
306
306
|
|
307
307
|
describe 'from a Sequel model' do
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
|
+
require_relative '../lib/forme/bs3'
|
4
4
|
|
5
5
|
describe "Forme Sequel::Model BS3 forms" do
|
6
6
|
before do
|
@@ -263,7 +263,7 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
263
263
|
|
264
264
|
it "should handle an error message on the underlying column for pg_array_to_many associations" do
|
265
265
|
@ab.errors.add(:atag_ids, 'tis not valid')
|
266
|
-
@b.input(:atags).to_s.must_equal '<div class="form-group has-error pg_array_to_many"><label for="album_atag_ids">Atags</label> <select class="form-control" id="album_atag_ids" multiple="multiple" name="album[atag_ids][]"><option selected="selected" value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select><span class="help-block with-errors">tis not valid</span></div>'
|
266
|
+
@b.input(:atags).to_s.must_equal '<div class="form-group has-error pg_array_to_many"><label for="album_atag_ids">Atags</label> <select aria-describedby="album_atag_ids_error_message" aria-invalid="true" class="form-control" id="album_atag_ids" multiple="multiple" name="album[atag_ids][]"><option selected="selected" value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select><span class="help-block with-errors">tis not valid</span></div>'
|
267
267
|
@b.input(:atags, :as=>:checkbox).to_s.must_equal '<div class="pg_array_to_many checkboxset has-error"><label>Atags</label><div class="checkbox"><label class="option" for="album_atag_ids_1"><input checked="checked" id="album_atag_ids_1" name="album[atag_ids][]" type="checkbox" value="1"/> s</label></div><div class="checkbox"><label class="option" for="album_atag_ids_2"><input checked="checked" id="album_atag_ids_2" name="album[atag_ids][]" type="checkbox" value="2"/> t</label></div><div class="checkbox"><label class="option" for="album_atag_ids_3"><input id="album_atag_ids_3" name="album[atag_ids][]" type="checkbox" value="3"/> u</label></div><span class="help-block with-errors">tis not valid</span></div>'
|
268
268
|
@b.input(:atags, :as=>:checkbox,:wrapper=>:li).to_s.must_equal '<li class="pg_array_to_many checkboxset has-error"><label>Atags</label><div class="checkbox"><label class="option" for="album_atag_ids_1"><input checked="checked" id="album_atag_ids_1" name="album[atag_ids][]" type="checkbox" value="1"/> s</label></div><div class="checkbox"><label class="option" for="album_atag_ids_2"><input checked="checked" id="album_atag_ids_2" name="album[atag_ids][]" type="checkbox" value="2"/> t</label></div><div class="checkbox"><label class="option" for="album_atag_ids_3"><input id="album_atag_ids_3" name="album[atag_ids][]" type="checkbox" value="3"/> u</label></div><span class="help-block with-errors">tis not valid</span></li>'
|
269
269
|
end
|
@@ -308,7 +308,7 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
308
308
|
|
309
309
|
it "should handle errors on methods not backed by columns" do
|
310
310
|
@ab.errors.add(:artist_name, 'foo')
|
311
|
-
@b.input(:artist_name).to_s.must_equal '<div class="form-group has-error"><label for="album_artist_name">Artist name</label> <input class="form-control" id="album_artist_name" name="album[artist_name]" type="text" value="a"/><span class="help-block with-errors">foo</span></div>'
|
311
|
+
@b.input(:artist_name).to_s.must_equal '<div class="form-group has-error"><label for="album_artist_name">Artist name</label> <input aria-describedby="album_artist_name_error_message" aria-invalid="true" class="form-control" id="album_artist_name" name="album[artist_name]" type="text" value="a"/><span class="help-block with-errors">foo</span></div>'
|
312
312
|
end
|
313
313
|
|
314
314
|
it "should respect a :type option with a schema type as the input type for methods not backed by columns" do
|
@@ -323,12 +323,12 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
323
323
|
|
324
324
|
it "should correctly show an error message if there is one" do
|
325
325
|
@ab.errors.add(:name, 'tis not valid')
|
326
|
-
@b.input(:name).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <input class="form-control" id="album_name" maxlength="255" name="album[name]" type="text" value="b"/><span class="help-block with-errors">tis not valid</span></div>'
|
326
|
+
@b.input(:name).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <input aria-describedby="album_name_error_message" aria-invalid="true" class="form-control" id="album_name" maxlength="255" name="album[name]" type="text" value="b"/><span class="help-block with-errors">tis not valid</span></div>'
|
327
327
|
end
|
328
328
|
|
329
329
|
it "should correctly show an error message for many_to_one associations if there is one" do
|
330
330
|
@ab.errors.add(:artist_id, 'tis not valid')
|
331
|
-
@b.input(:artist).to_s.must_equal '<div class="form-group has-error many_to_one"><label for="album_artist_id">Artist</label> <select class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select><span class="help-block with-errors">tis not valid</span></div>'
|
331
|
+
@b.input(:artist).to_s.must_equal '<div class="form-group has-error many_to_one"><label for="album_artist_id">Artist</label> <select aria-describedby="album_artist_id_error_message" aria-invalid="true" class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select><span class="help-block with-errors">tis not valid</span></div>'
|
332
332
|
end
|
333
333
|
|
334
334
|
it "should raise an error for unhandled associations" do
|
@@ -390,19 +390,19 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
390
390
|
end
|
391
391
|
|
392
392
|
it "should use allow nested forms with one_to_many associations" do
|
393
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><
|
393
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><fieldset class="inputs"><legend>Track #2</legend><div class="form-group string"><label for="album_tracks_attributes_1_name">Name</label> <input class="form-control" id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></div></fieldset></form>'
|
394
394
|
end
|
395
395
|
|
396
396
|
it "should support :obj option for *_to_many associations" do
|
397
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :obj=>[Track.new(:name=>'x'), Track.load(:id=>5, :name=>'y')]){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="x"/></div></fieldset><
|
397
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :obj=>[Track.new(:name=>'x'), Track.load(:id=>5, :name=>'y')]){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="5"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="x"/></div></fieldset><fieldset class="inputs"><legend>Track #2</legend><div class="form-group string"><label for="album_tracks_attributes_1_name">Name</label> <input class="form-control" id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="y"/></div></fieldset></form>'
|
398
398
|
end
|
399
399
|
|
400
400
|
it "should auto number legends when using subform with inputs for *_to_many associations" do
|
401
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :inputs=>[:name])}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><
|
401
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :inputs=>[:name])}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><fieldset class="inputs"><legend>Track #2</legend><div class="form-group string"><label for="album_tracks_attributes_1_name">Name</label> <input class="form-control" id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></div></fieldset></form>'
|
402
402
|
end
|
403
403
|
|
404
404
|
it "should support callable :legend option when using subform with inputs for *_to_many associations" do
|
405
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :inputs=>[:name], :legend=>proc{|o, i| "Track #{i} (#{o.name})"})}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Track 0 (m)</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><
|
405
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tracks, :inputs=>[:name], :legend=>proc{|o, i| "Track #{i} (#{o.name})"})}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track 0 (m)</legend><div class="form-group string"><label for="album_tracks_attributes_0_name">Name</label> <input class="form-control" id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><fieldset class="inputs"><legend>Track 1 (n)</legend><div class="form-group string"><label for="album_tracks_attributes_1_name">Name</label> <input class="form-control" id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></div></fieldset></form>'
|
406
406
|
end
|
407
407
|
|
408
408
|
it "should not add hidden primary key field for nested forms with one_to_many associations with new objects" do
|
@@ -411,7 +411,7 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
411
411
|
end
|
412
412
|
|
413
413
|
it "should use allow nested forms with many_to_many associations" do
|
414
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tags){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tags_attributes_0_id" name="album[tags_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Tag #1</legend><div class="form-group string"><label for="album_tags_attributes_0_name">Name</label> <input class="form-control" id="album_tags_attributes_0_name" maxlength="255" name="album[tags_attributes][0][name]" type="text" value="s"/></div></fieldset><
|
414
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:tags){f.input(:name)}}.to_s.must_equal '<form class="forme album" method="post"><input id="album_tags_attributes_0_id" name="album[tags_attributes][0][id]" type="hidden" value="1"/><input id="album_tags_attributes_1_id" name="album[tags_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Tag #1</legend><div class="form-group string"><label for="album_tags_attributes_0_name">Name</label> <input class="form-control" id="album_tags_attributes_0_name" maxlength="255" name="album[tags_attributes][0][name]" type="text" value="s"/></div></fieldset><fieldset class="inputs"><legend>Tag #2</legend><div class="form-group string"><label for="album_tags_attributes_1_name">Name</label> <input class="form-control" id="album_tags_attributes_1_name" maxlength="255" name="album[tags_attributes][1][name]" type="text" value="t"/></div></fieldset></form>'
|
415
415
|
end
|
416
416
|
|
417
417
|
it "should not add hidden primary key field for nested forms with many_to_many associations with new objects" do
|
@@ -420,23 +420,23 @@ describe "Forme Sequel::Model BS3 forms" do
|
|
420
420
|
end
|
421
421
|
|
422
422
|
it "should handle multiple nested levels" do
|
423
|
-
Forme.form(Artist[1], {},{:config=>:bs3}){|f| f.subform(:albums){f.input(:name); f.subform(:tracks){f.input(:name)}}}.to_s.to_s.must_equal '<form class="forme artist" method="post"><input id="artist_albums_attributes_0_id" name="artist[albums_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Album #1</legend><div class="form-group string"><label for="artist_albums_attributes_0_name">Name</label> <input class="form-control" id="artist_albums_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][name]" type="text" value="b"/></div><input id="artist_albums_attributes_0_tracks_attributes_0_id" name="artist[albums_attributes][0][tracks_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="artist_albums_attributes_0_tracks_attributes_0_name">Name</label> <input class="form-control" id="artist_albums_attributes_0_tracks_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><
|
423
|
+
Forme.form(Artist[1], {},{:config=>:bs3}){|f| f.subform(:albums){f.input(:name); f.subform(:tracks){f.input(:name)}}}.to_s.to_s.must_equal '<form class="forme artist" method="post"><input id="artist_albums_attributes_0_id" name="artist[albums_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Album #1</legend><div class="form-group string"><label for="artist_albums_attributes_0_name">Name</label> <input class="form-control" id="artist_albums_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][name]" type="text" value="b"/></div><input id="artist_albums_attributes_0_tracks_attributes_0_id" name="artist[albums_attributes][0][tracks_attributes][0][id]" type="hidden" value="1"/><input id="artist_albums_attributes_0_tracks_attributes_1_id" name="artist[albums_attributes][0][tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><div class="form-group string"><label for="artist_albums_attributes_0_tracks_attributes_0_name">Name</label> <input class="form-control" id="artist_albums_attributes_0_tracks_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][tracks_attributes][0][name]" type="text" value="m"/></div></fieldset><fieldset class="inputs"><legend>Track #2</legend><div class="form-group string"><label for="artist_albums_attributes_0_tracks_attributes_1_name">Name</label> <input class="form-control" id="artist_albums_attributes_0_tracks_attributes_1_name" maxlength="255" name="artist[albums_attributes][0][tracks_attributes][1][name]" type="text" value="n"/></div></fieldset></fieldset></form>'
|
424
424
|
end
|
425
425
|
|
426
426
|
it "should have #subform :grid option create a grid" do
|
427
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><
|
427
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
|
428
428
|
end
|
429
429
|
|
430
430
|
it "should have #subform :grid option respect :inputs_opts option to pass options to inputs" do
|
431
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><
|
431
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table class="foo"><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
|
432
432
|
end
|
433
433
|
|
434
434
|
it "should have #subform :grid option handle :legend and :labels options" do
|
435
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><
|
435
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><caption>Foo</caption><thead><tr><th>Bar</th></tr></thead><tbody><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
|
436
436
|
end
|
437
437
|
|
438
438
|
it "should have #subform :grid option handle :legend and :labels nil values" do
|
439
|
-
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><
|
439
|
+
Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><tbody><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
|
440
440
|
end
|
441
441
|
|
442
442
|
it "should have #subform :grid option handle :skip_primary_key option" do
|