phlexi-form 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 694c2f691f7e7b48e3b5df89dc1bc16badcbf88d4cb3fe528f106385aa448d93
4
- data.tar.gz: e0f6d6c3a12b7db210030d3cebfa2223d117839484bf6da38351281b219c1f34
3
+ metadata.gz: 8747d53fec5851c3ad3f78d2c60fecfea530de3b033eb074ee5f4ce41bcd3181
4
+ data.tar.gz: 51c02f430a3a81a4ee05197463a14aa9b00804c0a5b3a1837f36533b006d9860
5
5
  SHA512:
6
- metadata.gz: a269b67fc4679879244626a6734730f8b941a8fb1107837ecf057bb0d43c7003fe845f9614eb3f005a9cd594d2c2d048056f6aaf4858cb2be226c3b49d2cfb07
7
- data.tar.gz: a1b5899de6524100d3996d2594b0d544626c3e04df4c7c85f07b365864be73c0a957a10d5ac38d625d3622f47dbd20bd0bc2c826aa90904e8538fe1bff2a54fb
6
+ metadata.gz: 7434f1529fda38b7e02318c01be2fba09a97de755c874d2319730e4118d747a20bac457e7421bb34f0280f7e405079717df55e3d5ba3f32934f51deb1ebf43d7
7
+ data.tar.gz: 7457a359784b5404fee4a86ecdce99769f7899e080b7148aaff045719d536499efb4c6103c04334675258af94b74dbd10a9acacb7f327fb3a0f5f1508223f5bd
@@ -9,27 +9,57 @@ module Phlexi
9
9
 
10
10
  def build_attributes
11
11
  super
12
- @choice_collection = attributes.delete(:choices) || field.choices
13
12
  @label_method = attributes.delete(:label_method)
14
13
  @value_method = attributes.delete(:value_method)
14
+ @group_method = attributes.delete(:group_method)
15
+ @group_label_method = attributes.delete(:group_label_method)
15
16
  end
16
17
 
17
18
  def choices
18
- @choices ||= ChoicesMapper.new(@choice_collection, label_method: @label_method, value_method: @value_method)
19
+ @choices ||= begin
20
+ collection = attributes.delete(:choices) || field.choices
21
+ build_choice_mapper(collection)
22
+ end
19
23
  end
20
24
 
21
25
  def selected?(option)
22
26
  if attributes[:multiple]
23
- @options_list ||= Array(field.value)
24
- @options_list.any? { |item| item.to_s == option.to_s }
27
+ field_value.any? { |item| item.to_s == option.to_s }
28
+ else
29
+ field_value.to_s == option.to_s
30
+ end
31
+ end
32
+
33
+ def field_value
34
+ if attributes[:multiple]
35
+ Array(field.value)
25
36
  else
26
- field.value.to_s == option.to_s
37
+ field.value
27
38
  end
28
39
  end
29
40
 
30
41
  def normalize_simple_input(input_value)
42
+ # ensure that choice is in the list
31
43
  ([super] & choices.values)[0]
32
44
  end
45
+
46
+ def build_choice_mapper(collection)
47
+ if @group_method
48
+ GroupedChoicesMapper.new(
49
+ collection,
50
+ group_method: @group_method,
51
+ group_label_method: @group_label_method,
52
+ label_method: @label_method,
53
+ value_method: @value_method
54
+ )
55
+ else
56
+ SimpleChoicesMapper.new(
57
+ collection,
58
+ label_method: @label_method,
59
+ value_method: @value_method
60
+ )
61
+ end
62
+ end
33
63
  end
34
64
  end
35
65
  end
@@ -16,6 +16,8 @@ module Phlexi
16
16
  def build_input_attributes
17
17
  attributes[:type] = :file
18
18
  super
19
+
20
+ @include_hidden = attributes.delete(:include_hidden)
19
21
  # ensure we are always setting it to false
20
22
  attributes[:value] = false
21
23
  end
@@ -19,8 +19,18 @@ module Phlexi
19
19
  protected
20
20
 
21
21
  def options
22
- choices.each do |value, label|
23
- option(selected: selected?(value), value: value) { label }
22
+ if choices.is_a?(GroupedChoicesMapper)
23
+ choices.each do |group_label, group_choices|
24
+ optgroup(label: group_label) do
25
+ group_choices.each do |value, label|
26
+ option(selected: selected?(value), value: value) { label }
27
+ end
28
+ end
29
+ end
30
+ else
31
+ choices.each do |value, label|
32
+ option(selected: selected?(value), value: value) { label }
33
+ end
24
34
  end
25
35
  end
26
36
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Form
5
+ class GroupedChoicesMapper
6
+ include Enumerable
7
+
8
+ def initialize(collection, group_method:, group_label_method: :to_s, label_method: nil, value_method: nil)
9
+ @collection = collection
10
+ @group_method = group_method
11
+ @group_label_method = group_label_method
12
+ @label_method = label_method
13
+ @value_method = value_method
14
+ end
15
+
16
+ def each(&)
17
+ grouped_choices.each(&)
18
+ end
19
+
20
+ def grouped_choices
21
+ @grouped_choices ||= materialize_grouped_choices(@collection)
22
+ end
23
+
24
+ def materialize_grouped_choices(collection)
25
+ case collection
26
+ in Hash => hash
27
+ hash.transform_values { |items| to_choices_mapper(items) }
28
+ in Array => arr
29
+ array_to_grouped_hash(arr)
30
+ in Proc => proc
31
+ materialize_grouped_choices(proc.call)
32
+ else
33
+ record_collection_to_hash
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def array_to_grouped_hash(array)
40
+ sample = array.first
41
+ if group_method == :last && sample.is_a?(Array) && sample.size == 2
42
+ array.each_with_object({}) do |(label, items), hash|
43
+ hash[label.to_s] = to_choices_mapper(items)
44
+ end
45
+ else
46
+ record_collection_to_hash
47
+ end
48
+ end
49
+
50
+ def record_collection_to_hash
51
+ @collection.group_by do |item|
52
+ group = item.public_send(@group_method)
53
+ group.public_send(@group_label_method).to_s
54
+ end.transform_values { |items| to_choices_mapper(items) }
55
+ end
56
+
57
+ def to_choices_mapper(items)
58
+ SimpleChoicesMapper.new(items, label_method: @label_method, value_method: @value_method)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -2,31 +2,31 @@
2
2
 
3
3
  module Phlexi
4
4
  module Form
5
- # ChoicesMapper is responsible for converting a collection of objects into a hash of options
5
+ # SimpleChoicesMapper is responsible for converting a collection of objects into a hash of options
6
6
  # suitable for form controls, such as `select > options`.
7
7
  # Both values and labels are converted to strings.
8
8
  #
9
9
  # @example Basic usage
10
10
  # collection = [["First", 1], ["Second", 2]]
11
- # mapper = ChoicesMapper.new(collection)
11
+ # mapper = SimpleChoicesMapper.new(collection)
12
12
  # mapper.each { |value, label| puts "#{value}: #{label}" }
13
13
  #
14
14
  # @example Using with ActiveRecord objects
15
15
  # users = User.all
16
- # mapper = ChoicesMapper.new(users)
16
+ # mapper = SimpleChoicesMapper.new(users)
17
17
  # mapper.each { |id, name| puts "#{id}: #{name}" }
18
18
  #
19
19
  # @example Array access with different value types
20
- # mapper = ChoicesMapper.new([["Integer", 1], ["String", "2"], ["Symbol", :three]])
20
+ # mapper = SimpleChoicesMapper.new([["Integer", 1], ["String", "2"], ["Symbol", :three]])
21
21
  # puts mapper["1"] # Output: "Integer"
22
22
  # puts mapper["2"] # Output: "String"
23
23
  # puts mapper["three"] # Output: "Symbol"
24
24
  #
25
25
  # @note This class is thread-safe as it doesn't maintain mutable state.
26
- class ChoicesMapper
26
+ class SimpleChoicesMapper
27
27
  include Enumerable
28
28
 
29
- # Initializes a new ChoicesMapper instance.
29
+ # Initializes a new SimpleChoicesMapper instance.
30
30
  #
31
31
  # @param collection [#call, #to_a] The collection to be mapped.
32
32
  # @param label_method [Symbol, nil] The method to call on each object to get the label.
@@ -93,9 +93,9 @@ module Phlexi
93
93
  else
94
94
  array_to_hash(Array(collection))
95
95
  end
96
- rescue ArgumentError
97
- # Rails.logger.warn("Unhandled inclusion collection type: #{e}")TODO
98
- {}
96
+ # rescue ArgumentError
97
+ # # Rails.logger.warn("Unhandled inclusion collection type: #{e}")TODO
98
+ # {}
99
99
  end
100
100
 
101
101
  # Converts an array to a hash using detected or specified methods.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlexi
4
4
  module Form
5
- VERSION = "0.7.1"
5
+ VERSION = "0.8.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-29 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -205,7 +205,6 @@ files:
205
205
  - lib/phlexi/form.rb
206
206
  - lib/phlexi/form/base.rb
207
207
  - lib/phlexi/form/builder.rb
208
- - lib/phlexi/form/choices_mapper.rb
209
208
  - lib/phlexi/form/components/base.rb
210
209
  - lib/phlexi/form/components/belongs_to.rb
211
210
  - lib/phlexi/form/components/checkbox.rb
@@ -231,6 +230,7 @@ files:
231
230
  - lib/phlexi/form/components/submit_button.rb
232
231
  - lib/phlexi/form/components/textarea.rb
233
232
  - lib/phlexi/form/components/wrapper.rb
233
+ - lib/phlexi/form/grouped_choices_mapper.rb
234
234
  - lib/phlexi/form/html.rb
235
235
  - lib/phlexi/form/options/autofocus.rb
236
236
  - lib/phlexi/form/options/choices.rb
@@ -247,6 +247,7 @@ files:
247
247
  - lib/phlexi/form/options/required.rb
248
248
  - lib/phlexi/form/options/step.rb
249
249
  - lib/phlexi/form/options/validators.rb
250
+ - lib/phlexi/form/simple_choices_mapper.rb
250
251
  - lib/phlexi/form/structure/field_collection.rb
251
252
  - lib/phlexi/form/structure/manages_fields.rb
252
253
  - lib/phlexi/form/structure/namespace.rb