phlexi-form 0.7.2 → 0.8.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: 5efa476cb7e4856462046b6658c996843537b102f807e5c7c08a2d8e88520d11
4
- data.tar.gz: 1938daa8358013cee51abd0b4d50188c99459c6b714470002e4ec26a77e0b224
3
+ metadata.gz: 8747d53fec5851c3ad3f78d2c60fecfea530de3b033eb074ee5f4ce41bcd3181
4
+ data.tar.gz: 51c02f430a3a81a4ee05197463a14aa9b00804c0a5b3a1837f36533b006d9860
5
5
  SHA512:
6
- metadata.gz: a0b9918b54df47959563f801982e0cbfae8b2a22f21ea2900cb64be952c891b7df7702361255c09063b45a858ed4fc9445911bc73d1766edf3f91ed91000417a
7
- data.tar.gz: 73de9965cf5106cefe30081ba2d2a822d725ec203cb26d4d1fd2f2be53b336fd56aa227c2935b85b6d405ddf9a4dca35096f010d98d4724285d9dbfd9c2d8df8
6
+ metadata.gz: 7434f1529fda38b7e02318c01be2fba09a97de755c874d2319730e4118d747a20bac457e7421bb34f0280f7e405079717df55e3d5ba3f32934f51deb1ebf43d7
7
+ data.tar.gz: 7457a359784b5404fee4a86ecdce99769f7899e080b7148aaff045719d536499efb4c6103c04334675258af94b74dbd10a9acacb7f327fb3a0f5f1508223f5bd
@@ -9,13 +9,17 @@ 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)
@@ -35,8 +39,27 @@ module Phlexi
35
39
  end
36
40
 
37
41
  def normalize_simple_input(input_value)
42
+ # ensure that choice is in the list
38
43
  ([super] & choices.values)[0]
39
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
40
63
  end
41
64
  end
42
65
  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.2"
5
+ VERSION = "0.8.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
@@ -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