forme 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +10 -0
- data/README.rdoc +3 -3
- data/lib/forme/bs3.rb +7 -7
- data/lib/forme/form.rb +2 -0
- data/lib/forme/transformers/error_handler.rb +10 -10
- data/lib/forme/transformers/formatter.rb +32 -34
- data/lib/forme/version.rb +1 -1
- data/lib/sequel/plugins/forme.rb +8 -6
- data/lib/sequel/plugins/forme_set.rb +2 -4
- data/spec/bs3_reference_spec.rb +288 -311
- data/spec/bs3_sequel_plugin_spec.rb +152 -152
- data/spec/bs3_spec.rb +234 -205
- data/spec/forme_coverage.rb +1 -0
- data/spec/forme_spec.rb +429 -353
- data/spec/rails_integration_spec.rb +13 -1
- data/spec/roda_integration_spec.rb +20 -2
- data/spec/sequel_helper.rb +3 -1
- data/spec/sequel_i18n_plugin_spec.rb +4 -4
- data/spec/sequel_plugin_spec.rb +252 -149
- data/spec/sequel_set_plugin_spec.rb +6 -0
- data/spec/shared_erb_specs.rb +1 -1
- data/spec/sinatra_integration_spec.rb +26 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81ec9ce1b755276902340c709aa7addbd73b6b80252fcf0cbaac236098c62ac1
|
4
|
+
data.tar.gz: 35e17dd67304585e027dca62d6181eff1d30a0fcc7aa128879c9d8d54fd78f55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16f13f8ba1ba9fdae6b26b80f0b2e1fa2ce9ef520a3a29936597771f9f5424d2b49afc6debdb173e2aee6d672a471bb1aa8cee8e73d82ce7f5d30a1fc8ced578
|
7
|
+
data.tar.gz: 89d6f1ef00b4a9b28b55d9a6f42fb5250d10eaec78a7921d6220451f2fe7ea5c4ecea7907bcef5567e5e1dbcb60ccf2ec52195a6a4bfaacf2c4c353c785e9049
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 2.2.0 (2022-06-28)
|
2
|
+
|
3
|
+
* Use inputmode and pattern attributes instead of type=number for integer fields in the Sequel forme plugin (jeremyevans)
|
4
|
+
|
5
|
+
* Respect explicit nil/false :value option for boolean inputs in the Sequel forme plugin (jeremyevans)
|
6
|
+
|
7
|
+
* In bs3 support, make sure error spans have id referenced by aria-describedby (jeremyevans)
|
8
|
+
|
9
|
+
* Set aria-describedby attribute automatically even if :error_id is given manually (jeremyevans)
|
10
|
+
|
1
11
|
=== 2.1.0 (2022-05-25)
|
2
12
|
|
3
13
|
* Avoid hidden inputs inside tbody tags in subform in the Sequel::Model support, since that results in invalid HTML (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -49,7 +49,7 @@ This results in the following HTML:
|
|
49
49
|
<input id="album_name" name="album[name]" type="text" value="Rising Force"/>
|
50
50
|
</label>
|
51
51
|
<label>Copies Sold:
|
52
|
-
<input id="album_copies_sold" name="album[copies_sold]" type="
|
52
|
+
<input id="album_copies_sold" inputmode="numeric" name="album[copies_sold]" pattern="-?[0-9]*" type="text" value="100000"/>
|
53
53
|
</label>
|
54
54
|
</form>
|
55
55
|
|
@@ -443,12 +443,12 @@ form similar to:
|
|
443
443
|
|
444
444
|
<input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/>
|
445
445
|
<fieldset class="inputs"><legend>Track #1</legend>
|
446
|
-
<label>Number: <input id="album_tracks_attributes_0_number" name="album[tracks_attributes][0][number]" type="
|
446
|
+
<label>Number: <input id="album_tracks_attributes_0_number" inputmode="numeric" name="album[tracks_attributes][0][number]" pattern="-?[0-9]*" type="text" value="1"/></label>
|
447
447
|
<label>Name: <input id="album_tracks_attributes_0_name" name="album[tracks_attributes][0][name]" type="text" value="Blue Hawaii"/></label>
|
448
448
|
</fieldset>
|
449
449
|
<input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/>
|
450
450
|
<fieldset class="inputs"><legend>Track #2</legend>
|
451
|
-
<label>Number: <input id="album_tracks_attributes_1_number" name="album[tracks_attributes][1][number]" type="
|
451
|
+
<label>Number: <input id="album_tracks_attributes_1_number" inputmode="numeric" name="album[tracks_attributes][1][number]" pattern="-?[0-9]*" type="text" value="2"/></label>
|
452
452
|
<label>Name: <input id="album_tracks_attributes_1_name" name="album[tracks_attributes][1][name]" type="text" value="Almost Always True"/></label>
|
453
453
|
</fieldset>
|
454
454
|
|
data/lib/forme/bs3.rb
CHANGED
@@ -24,6 +24,7 @@ module Forme
|
|
24
24
|
attr = attr ? attr.dup : {}
|
25
25
|
Forme.attr_classes(attr, 'help-block with-errors')
|
26
26
|
return [tag] if input.opts[:skip_error_message]
|
27
|
+
attr[:id] ||= input.opts[:error_id]
|
27
28
|
|
28
29
|
case input.type
|
29
30
|
when :submit, :reset
|
@@ -84,11 +85,13 @@ module Forme
|
|
84
85
|
|
85
86
|
Forme.attr_classes(@attr, @opts[:class]) if @opts.has_key?(:class)
|
86
87
|
|
87
|
-
if @opts[:error]
|
88
|
+
if @opts[:error] && input.type != :submit && input.type != :reset
|
88
89
|
# Forme.attr_classes(@attr, 'error')
|
89
90
|
@attr["aria-invalid"] = "true"
|
90
91
|
if @opts.fetch(:error_handler, true)
|
91
|
-
|
92
|
+
if @opts[:error_id]
|
93
|
+
@attr['aria-describedby'] ||= @opts[:error_id]
|
94
|
+
else
|
92
95
|
if id = @attr[:id] || @attr['id']
|
93
96
|
error_id = @attr['aria-describedby'] ||= "#{id}_error_message"
|
94
97
|
@opts[:error_id] = error_id
|
@@ -127,7 +130,7 @@ module Forme
|
|
127
130
|
end
|
128
131
|
|
129
132
|
def _format_set(type, tag_attrs={})
|
130
|
-
raise Error, "can't have radioset with no options" unless @opts[:optgroups] || @opts[:options]
|
133
|
+
raise Error, "can't have radioset or checkboxset with no options" unless @opts[:optgroups] || @opts[:options]
|
131
134
|
key = @opts[:key]
|
132
135
|
name = @opts[:name]
|
133
136
|
id = @opts[:id]
|
@@ -282,7 +285,7 @@ module Forme
|
|
282
285
|
label_attr = input.opts[:label_attr]
|
283
286
|
label_attr = label_attr ? label_attr.dup : {}
|
284
287
|
|
285
|
-
label_attr[:for] = label_attr[:for]
|
288
|
+
label_attr[:for] = label_attr[:for] == false ? nil : input.opts.fetch(:label_for, id)
|
286
289
|
label = input.opts[:label]
|
287
290
|
lpos = input.opts[:label_position] || ([:radio, :checkbox].include?(input.type) ? :after : :before)
|
288
291
|
|
@@ -317,9 +320,6 @@ module Forme
|
|
317
320
|
|
318
321
|
case input.type
|
319
322
|
when :submit, :reset
|
320
|
-
klass.delete('form-group')
|
321
|
-
attr[:class] = klass.sort.uniq.join(' ').strip
|
322
|
-
attr.delete(:class) if attr[:class].empty?
|
323
323
|
[tag]
|
324
324
|
when :radio, :checkbox
|
325
325
|
klass.delete('form-group')
|
data/lib/forme/form.rb
CHANGED
@@ -49,17 +49,17 @@ module Forme
|
|
49
49
|
Forme.register_transformer(:error_handler, :after_legend, new)
|
50
50
|
|
51
51
|
def call(tag, input)
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
if tag.is_a?(Array) && tag.first.is_a?(Tag) && tag.first.type == :legend
|
53
|
+
first_input = input.opts[:first_input]
|
54
|
+
attr = first_input.opts[:attr] ||= {}
|
55
|
+
Forme.attr_classes(attr, 'error')
|
56
|
+
attr['aria-invalid'] = 'true'
|
57
|
+
attr['aria-describedby'] = input.opts[:error_id] = "#{first_input.opts[:id]}_error_message"
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
attr['aria-describedby'] = input.opts[:error_id] = "#{first_input.opts[:id]}_error_message"
|
61
|
-
|
62
|
-
tag.insert(1, error_tag(input))
|
59
|
+
tag.insert(1, error_tag(input))
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -220,7 +220,7 @@ module Forme
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def _format_set(type, tag_attrs={})
|
223
|
-
raise Error, "can't have radioset with no options" unless @opts[:optgroups] || @opts[:options]
|
223
|
+
raise Error, "can't have radioset or checkboxset with no options" unless @opts[:optgroups] || @opts[:options]
|
224
224
|
key = @opts[:key]
|
225
225
|
name = @opts[:name]
|
226
226
|
id = @opts[:id]
|
@@ -312,7 +312,9 @@ module Forme
|
|
312
312
|
Forme.attr_classes(@attr, 'error')
|
313
313
|
@attr["aria-invalid"] = "true"
|
314
314
|
if @opts.fetch(:error_handler, true)
|
315
|
-
|
315
|
+
if @opts[:error_id]
|
316
|
+
@attr['aria-describedby'] ||= @opts[:error_id]
|
317
|
+
else
|
316
318
|
if id = @attr[:id] || @attr['id']
|
317
319
|
error_id = @attr['aria-describedby'] ||= "#{id}_error_message"
|
318
320
|
@opts[:error_id] = error_id
|
@@ -397,9 +399,7 @@ module Forme
|
|
397
399
|
|
398
400
|
def set_error_from_namespaced_errors(namespaces, errors, key)
|
399
401
|
namespaces.each do |ns|
|
400
|
-
|
401
|
-
return unless e
|
402
|
-
errors = e
|
402
|
+
return unless errors = errors[ns] || errors[ns.to_s]
|
403
403
|
end
|
404
404
|
|
405
405
|
@opts[:error] = errors.fetch(key){errors.fetch(key.to_s){return}}
|
@@ -432,38 +432,36 @@ module Forme
|
|
432
432
|
# Iterate over the given options, yielding the option text, value, whether it is selected, and any attributes.
|
433
433
|
# The block should return an appropriate tag object.
|
434
434
|
def process_select_options(os)
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
sel = @opts[:selected] || @attr.delete(:value)
|
439
|
-
|
440
|
-
if @opts[:multiple]
|
441
|
-
sel = Array(sel)
|
442
|
-
cmp = lambda{|v| sel.include?(v)}
|
443
|
-
else
|
444
|
-
cmp = lambda{|v| v == sel}
|
445
|
-
end
|
435
|
+
vm = @opts[:value_method]
|
436
|
+
tm = @opts[:text_method]
|
437
|
+
sel = @opts[:selected] || @attr.delete(:value)
|
446
438
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
text = x.first
|
454
|
-
val = x.last
|
455
|
-
|
456
|
-
if val.is_a?(Hash)
|
457
|
-
value = val[:value]
|
458
|
-
attr.merge!(val)
|
459
|
-
val = value
|
460
|
-
end
|
461
|
-
else
|
462
|
-
text = x
|
463
|
-
end
|
439
|
+
if @opts[:multiple]
|
440
|
+
sel = Array(sel)
|
441
|
+
cmp = lambda{|v| sel.include?(v)}
|
442
|
+
else
|
443
|
+
cmp = lambda{|v| v == sel}
|
444
|
+
end
|
464
445
|
|
465
|
-
|
446
|
+
os.map do |x|
|
447
|
+
attr = {}
|
448
|
+
if tm
|
449
|
+
text = x.send(tm)
|
450
|
+
val = x.send(vm) if vm
|
451
|
+
elsif x.is_a?(Array)
|
452
|
+
text = x.first
|
453
|
+
val = x.last
|
454
|
+
|
455
|
+
if val.is_a?(Hash)
|
456
|
+
value = val[:value]
|
457
|
+
attr.merge!(val)
|
458
|
+
val = value
|
459
|
+
end
|
460
|
+
else
|
461
|
+
text = x
|
466
462
|
end
|
463
|
+
|
464
|
+
yield [text, val, !val.nil? ? cmp.call(val) : cmp.call(text), attr]
|
467
465
|
end
|
468
466
|
end
|
469
467
|
|
data/lib/forme/version.rb
CHANGED
data/lib/sequel/plugins/forme.rb
CHANGED
@@ -95,7 +95,7 @@ module Sequel # :nodoc:
|
|
95
95
|
end
|
96
96
|
|
97
97
|
if grid
|
98
|
-
labels = opts.fetch(:labels){opts[:inputs].map{|l
|
98
|
+
labels = opts.fetch(:labels){opts[:inputs].map{|l,| humanize(l)} if opts[:inputs]}
|
99
99
|
legend = opts.fetch(:legend){humanize(association)}
|
100
100
|
inputs_opts = opts[:inputs_opts] || {}
|
101
101
|
inputs(inputs_opts.merge(:inputs_wrapper=>:table, :nested_inputs_wrapper=>:tr, :wrapper=>:td, :labeler=>nil, :labels=>labels, :legend=>legend), &contents)
|
@@ -363,9 +363,10 @@ module Sequel # :nodoc:
|
|
363
363
|
opts[:as] = (sch[:allow_null] || opts[:required] == false) ? :select : :checkbox
|
364
364
|
end
|
365
365
|
|
366
|
+
v = opts.has_key?(:value) ? opts[:value] : obj.send(field)
|
367
|
+
|
366
368
|
case opts[:as]
|
367
369
|
when :radio
|
368
|
-
v = opts.has_key?(:value) ? opts[:value] : obj.send(field)
|
369
370
|
true_value = opts[:true_value]||'t'
|
370
371
|
false_value = opts[:false_value]||'f'
|
371
372
|
opts[:options] = [[opts[:true_label]||'Yes', {:value=>true_value, :key_id=>'yes'}], [opts[:false_label]||'No', {:value=>false_value, :key_id=>'no'}]]
|
@@ -374,13 +375,12 @@ module Sequel # :nodoc:
|
|
374
375
|
end
|
375
376
|
_input(:radioset, opts)
|
376
377
|
when :select
|
377
|
-
v = opts[:value] || obj.send(field)
|
378
378
|
opts[:value] = (v ? 't' : 'f') unless v.nil?
|
379
379
|
opts[:add_blank] = true unless opts.has_key?(:add_blank)
|
380
380
|
opts[:options] = [[opts[:true_label]||'True', opts[:true_value]||'t'], [opts[:false_label]||'False', opts[:false_value]||'f']]
|
381
381
|
_input(:select, opts)
|
382
382
|
else
|
383
|
-
opts[:checked] =
|
383
|
+
opts[:checked] = v
|
384
384
|
opts[:value] = 't'
|
385
385
|
_input(:checkbox, opts)
|
386
386
|
end
|
@@ -424,9 +424,11 @@ module Sequel # :nodoc:
|
|
424
424
|
end
|
425
425
|
end
|
426
426
|
|
427
|
-
# Use
|
427
|
+
# Use inputmode and pattern attributes for integers.
|
428
428
|
def input_integer(sch)
|
429
|
-
|
429
|
+
opts[:attr][:inputmode] ||= 'numeric'
|
430
|
+
opts[:attr][:pattern] ||= '-?[0-9]*'
|
431
|
+
standard_input(:text)
|
430
432
|
end
|
431
433
|
|
432
434
|
# Use date inputs for dates.
|
@@ -105,10 +105,8 @@ module Sequel # :nodoc:
|
|
105
105
|
opts = input.opts
|
106
106
|
return if SKIP_FORMATTERS.include?(opts.fetch(:formatter){input.form_opts[:formatter]})
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
return unless name ||= opts[:name] || opts[:key]
|
108
|
+
attr = opts[:attr] || {}
|
109
|
+
return unless name ||= attr[:name] || attr['name'] || opts[:name] || opts[:key]
|
112
110
|
|
113
111
|
# Pull out last component of the name if there is one
|
114
112
|
column = name.to_s.chomp('[]')
|