forme 2.1.0 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16429cabb255a24eacd8d108a6c0d1ed771581148f5f344a876ceb1da4082a3f
4
- data.tar.gz: 7fc3607cba35093e78bdfb3f6892bd94289c698b6d015e1a701303e5f5435b1a
3
+ metadata.gz: 81ec9ce1b755276902340c709aa7addbd73b6b80252fcf0cbaac236098c62ac1
4
+ data.tar.gz: 35e17dd67304585e027dca62d6181eff1d30a0fcc7aa128879c9d8d54fd78f55
5
5
  SHA512:
6
- metadata.gz: e399a4c2aa701ee112c1c3ed4f95854611781929b5ebcdc7b0c925c703d80b79d5cb77c1b1427e60be98b47e6308aac3cb2a231895874696a8265502fced126a
7
- data.tar.gz: 4397400180f4398ca5a553acf2b2845607952cfadfa8126ea88e473b161b8ac7e04589fcf89a62291b3e6218dbb6cf29d83825090c076d020181d3d1f2b05de7
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="number" value="100000"/>
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="number" value="1"/></label>
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="number" value="2"/></label>
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
- unless @opts[:error_id]
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] === false ? nil : input.opts.fetch(:label_for, id)
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
@@ -333,7 +333,9 @@ module Forme
333
333
  copy_inputs_wrapper_from_wrapper(opts, @opts)
334
334
  yield
335
335
  ensure
336
+ # :nocov:
336
337
  @opts = orig_opts if orig_opts
338
+ # :nocov:
337
339
  end
338
340
 
339
341
  private
@@ -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
- return super unless tag.is_a?(Array)
53
- return super unless tag.first.is_a?(Tag)
54
- return super unless tag.first.type == :legend
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
- first_input = input.opts[:first_input]
57
- attr = first_input.opts[:attr] ||= {}
58
- Forme.attr_classes(attr, 'error')
59
- attr['aria-invalid'] = 'true'
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
- unless @opts[:error_id]
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
- e = errors[ns] || errors[ns.to_s]
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
- if os
436
- vm = @opts[:value_method]
437
- tm = @opts[:text_method]
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
- os.map do |x|
448
- attr = {}
449
- if tm
450
- text = x.send(tm)
451
- val = x.send(vm) if vm
452
- elsif x.is_a?(Array)
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
- yield [text, val, !val.nil? ? cmp.call(val) : cmp.call(text), attr]
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
@@ -6,7 +6,7 @@ module Forme
6
6
  MAJOR = 2
7
7
 
8
8
  # The minor version of Forme, updated for new feature releases of Forme.
9
- MINOR = 1
9
+ MINOR = 2
10
10
 
11
11
  # The patch version of Forme, updated only for bug fixes from the last
12
12
  # feature release.
@@ -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, *| humanize(l)} if opts[:inputs]}
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] = obj.send(field)
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 number inputs for integers.
427
+ # Use inputmode and pattern attributes for integers.
428
428
  def input_integer(sch)
429
- standard_input(:number)
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
- if attr = opts[:attr]
109
- name = attr[:name] || attr['name']
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('[]')