phlexi-display 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/phlexi/display/base.rb +37 -169
  3. data/lib/phlexi/display/builder.rb +117 -0
  4. data/lib/phlexi/display/components/base.rb +1 -42
  5. data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
  6. data/lib/phlexi/display/components/date_time.rb +49 -0
  7. data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
  8. data/lib/phlexi/display/components/hint.rb +1 -1
  9. data/lib/phlexi/display/components/label.rb +3 -15
  10. data/lib/phlexi/display/components/number.rb +37 -0
  11. data/lib/phlexi/display/components/placeholder.rb +15 -0
  12. data/lib/phlexi/display/components/string.rb +17 -0
  13. data/lib/phlexi/display/components/wrapper.rb +4 -18
  14. data/lib/phlexi/display/theme.rb +22 -0
  15. data/lib/phlexi/display/version.rb +1 -1
  16. data/lib/phlexi/display.rb +1 -1
  17. metadata +24 -43
  18. data/lib/phlexi/display/components/checkbox.rb +0 -48
  19. data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
  20. data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
  21. data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
  22. data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
  23. data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
  24. data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
  25. data/lib/phlexi/display/components/file_input.rb +0 -32
  26. data/lib/phlexi/display/components/full_error.rb +0 -21
  27. data/lib/phlexi/display/components/input.rb +0 -84
  28. data/lib/phlexi/display/components/input_array.rb +0 -45
  29. data/lib/phlexi/display/components/radio_button.rb +0 -41
  30. data/lib/phlexi/display/components/select.rb +0 -69
  31. data/lib/phlexi/display/components/submit_button.rb +0 -41
  32. data/lib/phlexi/display/components/textarea.rb +0 -34
  33. data/lib/phlexi/display/field_options/associations.rb +0 -21
  34. data/lib/phlexi/display/field_options/autofocus.rb +0 -18
  35. data/lib/phlexi/display/field_options/collection.rb +0 -54
  36. data/lib/phlexi/display/field_options/disabled.rb +0 -18
  37. data/lib/phlexi/display/field_options/errors.rb +0 -92
  38. data/lib/phlexi/display/field_options/hints.rb +0 -22
  39. data/lib/phlexi/display/field_options/inferred_types.rb +0 -155
  40. data/lib/phlexi/display/field_options/labels.rb +0 -28
  41. data/lib/phlexi/display/field_options/length.rb +0 -53
  42. data/lib/phlexi/display/field_options/limit.rb +0 -66
  43. data/lib/phlexi/display/field_options/min_max.rb +0 -92
  44. data/lib/phlexi/display/field_options/multiple.rb +0 -65
  45. data/lib/phlexi/display/field_options/pattern.rb +0 -38
  46. data/lib/phlexi/display/field_options/placeholder.rb +0 -18
  47. data/lib/phlexi/display/field_options/readonly.rb +0 -18
  48. data/lib/phlexi/display/field_options/required.rb +0 -37
  49. data/lib/phlexi/display/field_options/themes.rb +0 -207
  50. data/lib/phlexi/display/field_options/validators.rb +0 -48
  51. data/lib/phlexi/display/option_mapper.rb +0 -154
  52. data/lib/phlexi/display/structure/dom.rb +0 -62
  53. data/lib/phlexi/display/structure/field_builder.rb +0 -236
  54. data/lib/phlexi/display/structure/field_collection.rb +0 -54
  55. data/lib/phlexi/display/structure/namespace.rb +0 -135
  56. data/lib/phlexi/display/structure/namespace_collection.rb +0 -48
  57. data/lib/phlexi/display/structure/node.rb +0 -18
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Display
5
+ module Components
6
+ class String < Base
7
+ include Concerns::DisplaysValue
8
+
9
+ def render_value(value)
10
+ p(**attributes) {
11
+ value
12
+ }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -4,26 +4,12 @@ module Phlexi
4
4
  module Display
5
5
  module Components
6
6
  class Wrapper < Base
7
- attr_reader :inner_attributes
8
-
9
7
  def view_template
10
- div(**attributes) do
8
+ div(**attributes) {
11
9
  render field.label_tag
12
- div(**inner_attributes) do
13
- yield field if block_given?
14
- render field.full_error_tag
15
- render field.hint_tag
16
- end
17
- end
18
- end
19
-
20
- protected
21
-
22
- def build_attributes
23
- super
24
-
25
- @inner_attributes = attributes.delete(:inner) || {}
26
- inner_attributes[:class] = tokens("inner-wrapper", inner_attributes[:class])
10
+ yield field if block_given?
11
+ render field.description_tag
12
+ }
27
13
  end
28
14
  end
29
15
  end
@@ -0,0 +1,22 @@
1
+ module Phlexi
2
+ module Display
3
+ class Theme
4
+ include Phlexi::Field::Theme
5
+
6
+ DEFAULT_THEME = {
7
+ label: nil,
8
+ description: nil,
9
+ placeholder: nil,
10
+ string: nil,
11
+ number: :string,
12
+ datetime: :string,
13
+ attachment: :string,
14
+ wrapper: nil
15
+ }.freeze
16
+
17
+ def theme
18
+ DEFAULT_THEME
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlexi
4
4
  module Display
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.3"
6
6
  end
7
7
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "zeitwerk"
4
4
  require "phlex"
5
+ require "phlexi-field"
5
6
  require "active_support/core_ext/object/blank"
6
7
 
7
8
  module Phlexi
@@ -14,7 +15,6 @@ module Phlexi
14
15
  "dom" => "DOM"
15
16
  )
16
17
  loader.push_dir(File.expand_path("..", __dir__))
17
- loader.ignore(File.expand_path("../generators", __dir__))
18
18
  loader.setup
19
19
  end
20
20
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-display
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
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-08-24 00:00:00.000000000 Z
11
+ date: 2024-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: phlexi-field
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -185,51 +199,18 @@ files:
185
199
  - lib/phlexi-display.rb
186
200
  - lib/phlexi/display.rb
187
201
  - lib/phlexi/display/base.rb
202
+ - lib/phlexi/display/builder.rb
188
203
  - lib/phlexi/display/components/base.rb
189
- - lib/phlexi/display/components/checkbox.rb
190
- - lib/phlexi/display/components/collection_checkboxes.rb
191
- - lib/phlexi/display/components/collection_radio_buttons.rb
192
- - lib/phlexi/display/components/concerns/handles_array_input.rb
193
- - lib/phlexi/display/components/concerns/handles_input.rb
194
- - lib/phlexi/display/components/concerns/has_options.rb
195
- - lib/phlexi/display/components/concerns/submits_form.rb
196
- - lib/phlexi/display/components/error.rb
197
- - lib/phlexi/display/components/file_input.rb
198
- - lib/phlexi/display/components/full_error.rb
204
+ - lib/phlexi/display/components/concerns/displays_value.rb
205
+ - lib/phlexi/display/components/date_time.rb
206
+ - lib/phlexi/display/components/description.rb
199
207
  - lib/phlexi/display/components/hint.rb
200
- - lib/phlexi/display/components/input.rb
201
- - lib/phlexi/display/components/input_array.rb
202
208
  - lib/phlexi/display/components/label.rb
203
- - lib/phlexi/display/components/radio_button.rb
204
- - lib/phlexi/display/components/select.rb
205
- - lib/phlexi/display/components/submit_button.rb
206
- - lib/phlexi/display/components/textarea.rb
209
+ - lib/phlexi/display/components/number.rb
210
+ - lib/phlexi/display/components/placeholder.rb
211
+ - lib/phlexi/display/components/string.rb
207
212
  - lib/phlexi/display/components/wrapper.rb
208
- - lib/phlexi/display/field_options/associations.rb
209
- - lib/phlexi/display/field_options/autofocus.rb
210
- - lib/phlexi/display/field_options/collection.rb
211
- - lib/phlexi/display/field_options/disabled.rb
212
- - lib/phlexi/display/field_options/errors.rb
213
- - lib/phlexi/display/field_options/hints.rb
214
- - lib/phlexi/display/field_options/inferred_types.rb
215
- - lib/phlexi/display/field_options/labels.rb
216
- - lib/phlexi/display/field_options/length.rb
217
- - lib/phlexi/display/field_options/limit.rb
218
- - lib/phlexi/display/field_options/min_max.rb
219
- - lib/phlexi/display/field_options/multiple.rb
220
- - lib/phlexi/display/field_options/pattern.rb
221
- - lib/phlexi/display/field_options/placeholder.rb
222
- - lib/phlexi/display/field_options/readonly.rb
223
- - lib/phlexi/display/field_options/required.rb
224
- - lib/phlexi/display/field_options/themes.rb
225
- - lib/phlexi/display/field_options/validators.rb
226
- - lib/phlexi/display/option_mapper.rb
227
- - lib/phlexi/display/structure/dom.rb
228
- - lib/phlexi/display/structure/field_builder.rb
229
- - lib/phlexi/display/structure/field_collection.rb
230
- - lib/phlexi/display/structure/namespace.rb
231
- - lib/phlexi/display/structure/namespace_collection.rb
232
- - lib/phlexi/display/structure/node.rb
213
+ - lib/phlexi/display/theme.rb
233
214
  - lib/phlexi/display/version.rb
234
215
  - sig/phlexi/display.rbs
235
216
  homepage: https://github.com/radioactive-labs/phlexi-display
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class Checkbox < Input
7
- def view_template
8
- input(type: :hidden, name: attributes[:name], value: @unchecked_value, autocomplete: "off", hidden: true) if include_hidden?
9
- input(**attributes, value: @checked_value)
10
- end
11
-
12
- protected
13
-
14
- def build_input_attributes
15
- attributes[:type] = :checkbox
16
- super
17
-
18
- @include_hidden = attributes.delete(:include_hidden)
19
- @checked_value = (attributes.key?(:checked_value) ? attributes.delete(:checked_value) : "1").to_s
20
- @unchecked_value = (attributes.key?(:unchecked_value) ? attributes.delete(:unchecked_value) : "0").to_s
21
-
22
- attributes[:value] = @checked_value
23
- attributes[:checked] = attributes.fetch(:checked) { checked? }
24
- end
25
-
26
- def include_hidden?
27
- @include_hidden != false
28
- end
29
-
30
- def checked?
31
- return false if field.dom.value == @unchecked_value
32
-
33
- if @checked_value == "1" # using default values
34
- # handle nils, numbers and booleans
35
- !["", "0", "false"].include?(field.dom.value)
36
- else # custom value, so explicit match
37
- field.dom.value == @checked_value
38
- end
39
- end
40
-
41
- def normalize_input(...)
42
- input_value = super
43
- [@checked_value, @unchecked_value].include?(input_value) ? input_value : @unchecked_value
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class CollectionCheckboxes < Base
7
- include Concerns::HandlesInput
8
- include Concerns::HandlesArrayInput
9
- include Concerns::HasOptions
10
-
11
- def view_template
12
- div(**attributes.slice(:id, :class)) do
13
- field.multi(option_mapper.values) do |builder|
14
- render builder.hidden_field_tag if builder.index == 0
15
-
16
- field = builder.field(
17
- label: option_mapper[builder.key],
18
- # We set the attributes here so they are applied to all input components even if the user decides to use a block
19
- input_attributes: {
20
- checked_value: builder.key,
21
- include_hidden: false,
22
- checked: selected?(builder.key)
23
- }
24
- )
25
- if block_given?
26
- yield field
27
- else
28
- render field.checkbox_tag
29
- render field.label_tag
30
- end
31
- end
32
- end
33
- end
34
-
35
- protected
36
-
37
- def build_attributes
38
- super
39
- attributes[:multiple] = true
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class CollectionRadioButtons < Base
7
- include Concerns::HandlesInput
8
- include Concerns::HasOptions
9
-
10
- def view_template
11
- div(**attributes.slice(:id, :class)) do
12
- field.multi(option_mapper.values) do |builder|
13
- render builder.hidden_field_tag if builder.index == 0
14
-
15
- field = builder.field(
16
- label: option_mapper[builder.key],
17
- # We set the attributes here so they are applied to all input components even if the user decides to use a block
18
- input_attributes: {
19
- checked_value: builder.key,
20
- checked: selected?(builder.key)
21
- }
22
- )
23
- if block_given?
24
- yield field
25
- else
26
- render field.radio_button_tag
27
- render field.label_tag
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- module Concerns
7
- module HandlesArrayInput
8
- protected
9
-
10
- def normalize_input(input_value)
11
- normalize_array_input(input_value)
12
- end
13
-
14
- def normalize_array_input(input_value)
15
- Array(input_value).map { |nested_input_value| normalize_simple_input(nested_input_value) }.compact
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- module Concerns
7
- module HandlesInput
8
- # Collects parameters matching the input field's param key.
9
- #
10
- # @param params [Hash] the parameters to collect from.
11
- # @return [Hash] the collected parameters.
12
- def extract_input(params)
13
- # # Handles multi parameter attributes
14
- # # https://www.cookieshq.co.uk/posts/rails-spelunking-date-select
15
- # # https://www.cookieshq.co.uk/posts/multiparameter-attributes
16
-
17
- # # Matches
18
- # # - parameter
19
- # # - parameter(1)
20
- # # - parameter(2)
21
- # # - parameter(1i)
22
- # # - parameter(2f)
23
- # regex = /^#{param}(\(\d+[if]?\))?$/
24
- # keys = params.select { |key, _| regex.match?(key) }.keys
25
- # params.slice(*keys)
26
-
27
- params ||= {}
28
- {input_param => normalize_input(params[field.key])}
29
- end
30
-
31
- protected
32
-
33
- def build_attributes
34
- super
35
- @input_param = attributes.delete(:input_param) || field.key
36
- end
37
-
38
- def input_param
39
- @input_param
40
- end
41
-
42
- def normalize_input(input_value)
43
- normalize_simple_input(input_value)
44
- end
45
-
46
- def normalize_simple_input(input_value)
47
- input_value.to_s.presence
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- module Concerns
7
- module HasOptions
8
- protected
9
-
10
- def build_attributes
11
- super
12
- @collection = attributes.delete(:collection) || field.collection
13
- @label_method = attributes.delete(:label_method)
14
- @value_method = attributes.delete(:value_method)
15
- end
16
-
17
- def option_mapper
18
- @option_mapper ||= OptionMapper.new(@collection, label_method: @label_method, value_method: @value_method)
19
- end
20
-
21
- def selected?(option)
22
- if attributes[:multiple]
23
- @options_list ||= Array(field.value)
24
- @options_list.any? { |item| item.to_s == option.to_s }
25
- else
26
- field.value.to_s == option.to_s
27
- end
28
- end
29
-
30
- def normalize_simple_input(input_value)
31
- ([super] & option_mapper.values)[0]
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- module Concerns
7
- module SubmitsDisplay
8
- def submit_type_value
9
- if field.object.respond_to?(:persisted?)
10
- field.object.persisted? ? :update : :create
11
- else
12
- :submit
13
- end
14
- end
15
-
16
- def submit_type_label
17
- @submit_type_label ||= begin
18
- key = submit_type_value
19
-
20
- model_object = field.dom.lineage.first.key.to_s
21
- model_name_human = if field.object.respond_to?(:model_name)
22
- field.object.model_name.human
23
- else
24
- model_object.humanize
25
- end
26
-
27
- defaults = []
28
- defaults << :"helpers.submit.#{model_object}.#{key}"
29
- defaults << :"helpers.submit.#{key}"
30
- defaults << "#{key.to_s.humanize} #{model_name_human}"
31
-
32
- I18n.t(defaults.shift, model: model_name_human, default: defaults)
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class FileInput < Input
7
- def view_template
8
- input(type: :hidden, name: attributes[:name], value: "", autocomplete: "off", hidden: true) if include_hidden?
9
- input(**attributes)
10
- end
11
-
12
- protected
13
-
14
- def build_input_attributes
15
- attributes[:type] = :file
16
- super
17
- attributes[:value] = false
18
- end
19
-
20
- def include_hidden?
21
- return false if @include_hidden == false
22
-
23
- attributes[:multiple]
24
- end
25
-
26
- def normalize_input(input_value)
27
- input_value
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class FullError < Base
7
- def view_template
8
- p(**attributes) do
9
- field.full_error
10
- end
11
- end
12
-
13
- private
14
-
15
- def render?
16
- field.show_errors? && field.has_errors?
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class Input < Base
7
- include Concerns::HandlesInput
8
-
9
- def view_template
10
- input(**attributes)
11
- end
12
-
13
- protected
14
-
15
- def build_attributes
16
- super
17
-
18
- # only overwrite id if it was set in Base
19
- attributes[:id] = field.dom.id if attributes[:id] == "#{field.dom.id}_#{component_name}"
20
-
21
- attributes[:name] = field.dom.name
22
- attributes[:value] = field.dom.value
23
-
24
- build_input_attributes
25
- end
26
-
27
- def build_input_attributes
28
- attributes.fetch(:type) { attributes[:type] = field.inferred_input_type }
29
- attributes.fetch(:disabled) { attributes[:disabled] = field.disabled? }
30
-
31
- case attributes[:type]
32
- when :text, :password, :email, :tel, :url, :search
33
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
34
- attributes.fetch(:placeholder) { attributes[:placeholder] = field.placeholder }
35
- attributes.fetch(:minlength) { attributes[:minlength] = field.minlength }
36
- attributes.fetch(:maxlength) { attributes[:maxlength] = field.maxlength }
37
- attributes.fetch(:readonly) { attributes[:readonly] = field.readonly? }
38
- attributes.fetch(:required) { attributes[:required] = field.required? }
39
- attributes.fetch(:pattern) { attributes[:pattern] = field.pattern }
40
- when :number
41
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
42
- attributes.fetch(:placeholder) { attributes[:placeholder] = field.placeholder }
43
- attributes.fetch(:readonly) { attributes[:readonly] = field.readonly? }
44
- attributes.fetch(:required) { attributes[:required] = field.required? }
45
- attributes.fetch(:min) { attributes[:min] = field.min }
46
- attributes.fetch(:max) { attributes[:max] = field.max }
47
- attributes.fetch(:step) { attributes[:step] = field.step }
48
- when :checkbox, :radio
49
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
50
- attributes.fetch(:required) { attributes[:required] = field.required? }
51
- when :file
52
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
53
- attributes.fetch(:required) { attributes[:required] = field.required? }
54
- attributes.fetch(:multiple) { attributes[:multiple] = field.multiple? }
55
- when :date, :time, :datetime_local
56
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
57
- attributes.fetch(:readonly) { attributes[:readonly] = field.readonly? }
58
- attributes.fetch(:required) { attributes[:required] = field.required? }
59
- attributes.fetch(:min) { attributes[:min] = field.min }
60
- attributes.fetch(:max) { attributes[:max] = field.max }
61
- when :color
62
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
63
- when :range
64
- attributes.fetch(:autofocus) { attributes[:autofocus] = field.focused? }
65
- attributes.fetch(:min) { attributes[:min] = field.min }
66
- attributes.fetch(:max) { attributes[:max] = field.max }
67
- attributes.fetch(:step) { attributes[:step] = field.step }
68
- when :hidden
69
- attributes[:class] = false
70
- attributes[:hidden] = true
71
- attributes[:autocomplete] = "off"
72
- else
73
- # Handle any unrecognized input types
74
- # Rails.logger.warn("Unhandled input type: #{attributes[:type]}")
75
- end
76
-
77
- if (attributes[:type] == :file) ? attributes[:multiple] : attributes.delete(:multiple)
78
- attributes[:name] = "#{attributes[:name].sub(/\[\]$/, "")}[]"
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Display
5
- module Components
6
- class InputArray < Base
7
- include Concerns::HandlesInput
8
- include Concerns::HandlesArrayInput
9
-
10
- def view_template
11
- div(**attributes.slice(:id, :class)) do
12
- field.multi(values.length) do |builder|
13
- render builder.hidden_field_tag if builder.index == 0
14
-
15
- field = builder.field(
16
- label: builder.key,
17
- # we expect key to be an integer string starting from "1"
18
- value: values[builder.index]
19
- )
20
- if block_given?
21
- yield field
22
- else
23
- render field.input_tag
24
- end
25
- end
26
- end
27
- end
28
-
29
- protected
30
-
31
- def build_attributes
32
- super
33
-
34
- attributes[:multiple] = true
35
- end
36
-
37
- private
38
-
39
- def values
40
- @values ||= Array(field.value)
41
- end
42
- end
43
- end
44
- end
45
- end