phlexi-display 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/phlexi/display/base.rb +35 -158
- data/lib/phlexi/display/components/base.rb +1 -14
- data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
- data/lib/phlexi/display/components/date_time.rb +49 -0
- data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
- data/lib/phlexi/display/components/hint.rb +1 -1
- data/lib/phlexi/display/components/label.rb +3 -15
- data/lib/phlexi/display/components/number.rb +37 -0
- data/lib/phlexi/display/components/placeholder.rb +15 -0
- data/lib/phlexi/display/components/string.rb +17 -0
- data/lib/phlexi/display/components/wrapper.rb +4 -18
- data/lib/phlexi/display/field_options/associations.rb +2 -2
- data/lib/phlexi/display/field_options/attachments.rb +21 -0
- data/lib/phlexi/display/field_options/description.rb +22 -0
- data/lib/phlexi/display/field_options/hints.rb +1 -1
- data/lib/phlexi/display/field_options/inferred_types.rb +26 -52
- data/lib/phlexi/display/field_options/{placeholder.rb → placeholders.rb} +2 -2
- data/lib/phlexi/display/field_options/themes.rb +45 -120
- data/lib/phlexi/display/structure/dom.rb +7 -27
- data/lib/phlexi/display/structure/field_builder.rb +75 -151
- data/lib/phlexi/display/structure/field_collection.rb +5 -20
- data/lib/phlexi/display/structure/namespace.rb +22 -34
- data/lib/phlexi/display/structure/namespace_collection.rb +1 -9
- data/lib/phlexi/display/structure/node.rb +9 -3
- data/lib/phlexi/display/version.rb +1 -1
- data/lib/phlexi/display.rb +0 -1
- metadata +11 -31
- data/lib/phlexi/display/components/checkbox.rb +0 -48
- data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
- data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
- data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
- data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
- data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
- data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
- data/lib/phlexi/display/components/file_input.rb +0 -32
- data/lib/phlexi/display/components/full_error.rb +0 -21
- data/lib/phlexi/display/components/input.rb +0 -84
- data/lib/phlexi/display/components/input_array.rb +0 -45
- data/lib/phlexi/display/components/radio_button.rb +0 -41
- data/lib/phlexi/display/components/select.rb +0 -69
- data/lib/phlexi/display/components/submit_button.rb +0 -41
- data/lib/phlexi/display/components/textarea.rb +0 -34
- data/lib/phlexi/display/field_options/autofocus.rb +0 -18
- data/lib/phlexi/display/field_options/collection.rb +0 -54
- data/lib/phlexi/display/field_options/disabled.rb +0 -18
- data/lib/phlexi/display/field_options/errors.rb +0 -92
- data/lib/phlexi/display/field_options/length.rb +0 -53
- data/lib/phlexi/display/field_options/limit.rb +0 -66
- data/lib/phlexi/display/field_options/min_max.rb +0 -92
- data/lib/phlexi/display/field_options/multiple.rb +0 -65
- data/lib/phlexi/display/field_options/pattern.rb +0 -38
- data/lib/phlexi/display/field_options/readonly.rb +0 -18
- data/lib/phlexi/display/field_options/required.rb +0 -37
- data/lib/phlexi/display/field_options/validators.rb +0 -48
@@ -14,26 +14,16 @@ module Phlexi
|
|
14
14
|
# @attr_accessor [Object] value The value of the field.
|
15
15
|
class FieldBuilder < Node
|
16
16
|
include Phlex::Helpers
|
17
|
-
include FieldOptions::Associations
|
18
17
|
include FieldOptions::Themes
|
19
|
-
include FieldOptions::
|
20
|
-
include FieldOptions::
|
21
|
-
include FieldOptions::Hints
|
22
|
-
include FieldOptions::Errors
|
18
|
+
include FieldOptions::Associations
|
19
|
+
include FieldOptions::Attachments
|
23
20
|
include FieldOptions::InferredTypes
|
24
|
-
include FieldOptions::
|
25
|
-
include FieldOptions::
|
26
|
-
include FieldOptions::
|
27
|
-
include FieldOptions::
|
28
|
-
|
29
|
-
|
30
|
-
include FieldOptions::Length
|
31
|
-
include FieldOptions::MinMax
|
32
|
-
include FieldOptions::Pattern
|
33
|
-
include FieldOptions::Multiple
|
34
|
-
include FieldOptions::Limit
|
35
|
-
|
36
|
-
attr_reader :dom, :options, :object, :input_attributes, :value
|
21
|
+
include FieldOptions::Labels
|
22
|
+
include FieldOptions::Placeholders
|
23
|
+
include FieldOptions::Description
|
24
|
+
# include FieldOptions::Hints
|
25
|
+
|
26
|
+
attr_reader :dom, :options, :object, :value
|
37
27
|
|
38
28
|
# Initializes a new FieldBuilder instance.
|
39
29
|
#
|
@@ -41,14 +31,12 @@ module Phlexi
|
|
41
31
|
# @param parent [Structure::Namespace] The parent object.
|
42
32
|
# @param object [Object, nil] The associated object.
|
43
33
|
# @param value [Object] The initial value for the field.
|
44
|
-
# @param input_attributes [Hash] Default attributes to apply to input fields.
|
45
34
|
# @param options [Hash] Additional options for the field.
|
46
|
-
def initialize(key, parent:, object: nil, value: NIL_VALUE,
|
35
|
+
def initialize(key, parent:, object: nil, value: NIL_VALUE, **options)
|
47
36
|
super(key, parent: parent)
|
48
37
|
|
49
38
|
@object = object
|
50
|
-
@value =
|
51
|
-
@input_attributes = input_attributes
|
39
|
+
@value = determine_value(value)
|
52
40
|
@options = options
|
53
41
|
@dom = Structure::DOM.new(field: self)
|
54
42
|
end
|
@@ -61,175 +49,111 @@ module Phlexi
|
|
61
49
|
create_component(Components::Label, :label, **attributes, &)
|
62
50
|
end
|
63
51
|
|
64
|
-
# Creates
|
65
|
-
#
|
66
|
-
# @param attributes [Hash] Additional attributes for the input.
|
67
|
-
# @return [Components::Input] The input component.
|
68
|
-
def input_tag(**attributes, &)
|
69
|
-
create_component(Components::Input, :input, **attributes, &)
|
70
|
-
end
|
71
|
-
|
72
|
-
def file_input_tag(**attributes, &)
|
73
|
-
create_component(Components::FileInput, :file, **attributes, &)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Creates a checkbox tag for the field.
|
77
|
-
#
|
78
|
-
# @param attributes [Hash] Additional attributes for the checkbox.
|
79
|
-
# @return [Components::Checkbox] The checkbox component.
|
80
|
-
def checkbox_tag(**attributes, &)
|
81
|
-
create_component(Components::Checkbox, :checkbox, **attributes, &)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Creates collection checkboxes for the field.
|
85
|
-
#
|
86
|
-
# @param attributes [Hash] Additional attributes for the collection checkboxes.
|
87
|
-
# @yield [block] The block to be executed for each checkbox.
|
88
|
-
# @return [Components::CollectionCheckboxes] The collection checkboxes component.
|
89
|
-
def collection_checkboxes_tag(**attributes, &)
|
90
|
-
create_component(Components::CollectionCheckboxes, :collection_checkboxes, **attributes, &)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Creates a radio button tag for the field.
|
94
|
-
#
|
95
|
-
# @param attributes [Hash] Additional attributes for the radio button.
|
96
|
-
# @return [Components::RadioButton] The radio button component.
|
97
|
-
def radio_button_tag(**attributes, &)
|
98
|
-
create_component(Components::RadioButton, :radio, **attributes, &)
|
99
|
-
end
|
100
|
-
|
101
|
-
# Creates collection radio buttons for the field.
|
52
|
+
# Creates a Placeholder tag for the field.
|
102
53
|
#
|
103
|
-
# @param attributes [Hash] Additional attributes for the
|
104
|
-
# @
|
105
|
-
|
106
|
-
|
107
|
-
create_component(Components::CollectionRadioButtons, :collection_radio_buttons, **attributes, &)
|
54
|
+
# @param attributes [Hash] Additional attributes for the placeholder.
|
55
|
+
# @return [Components::Placeholder] The placeholder component.
|
56
|
+
def placeholder_tag(**attributes, &)
|
57
|
+
create_component(Components::Placeholder, :placeholder, **attributes, &)
|
108
58
|
end
|
109
59
|
|
110
|
-
# Creates a
|
60
|
+
# Creates a Description tag for the field.
|
111
61
|
#
|
112
|
-
# @param attributes [Hash] Additional attributes for the
|
113
|
-
# @return [Components::
|
114
|
-
def
|
115
|
-
create_component(Components::
|
62
|
+
# @param attributes [Hash] Additional attributes for the description.
|
63
|
+
# @return [Components::Description] The description component.
|
64
|
+
def description_tag(**attributes, &)
|
65
|
+
create_component(Components::Description, :description, **attributes, &)
|
116
66
|
end
|
117
67
|
|
118
|
-
# Creates a
|
68
|
+
# Creates a string display tag for the field.
|
119
69
|
#
|
120
|
-
# @param attributes [Hash] Additional attributes for the
|
121
|
-
# @return [Components::
|
122
|
-
def
|
123
|
-
create_component(
|
70
|
+
# @param attributes [Hash] Additional attributes for the string display.
|
71
|
+
# @return [Components::String] The string component.
|
72
|
+
def string_tag(**attributes, &)
|
73
|
+
create_component(Components::String, :string, **attributes, &)
|
124
74
|
end
|
125
75
|
|
126
|
-
|
127
|
-
|
128
|
-
|
76
|
+
# # Creates a text display tag for the field.
|
77
|
+
# #
|
78
|
+
# # @param attributes [Hash] Additional attributes for the text display.
|
79
|
+
# # @return [Components::Text] The text component.
|
80
|
+
# def text_tag(**attributes, &)
|
81
|
+
# create_component(Components::Text, :text, **attributes, &)
|
82
|
+
# end
|
129
83
|
|
130
|
-
# Creates a
|
84
|
+
# Creates a number display tag for the field.
|
131
85
|
#
|
132
|
-
# @param attributes [Hash] Additional attributes for the
|
133
|
-
# @return [Components::
|
134
|
-
def
|
135
|
-
create_component(Components::
|
86
|
+
# @param attributes [Hash] Additional attributes for the number display.
|
87
|
+
# @return [Components::Number] The number component.
|
88
|
+
def number_tag(**attributes, &)
|
89
|
+
create_component(Components::Number, :number, **attributes, &)
|
136
90
|
end
|
137
91
|
|
138
|
-
# Creates
|
92
|
+
# Creates a datetime display for the field.
|
139
93
|
#
|
140
|
-
# @param attributes [Hash] Additional attributes for the
|
141
|
-
# @return [Components::
|
142
|
-
def
|
143
|
-
create_component(Components::
|
144
|
-
end
|
145
|
-
|
146
|
-
# Creates a
|
147
|
-
#
|
148
|
-
# @param attributes [Hash] Additional attributes for the
|
149
|
-
# @return [Components::
|
150
|
-
def
|
151
|
-
|
152
|
-
end
|
94
|
+
# @param attributes [Hash] Additional attributes for the datetime display.
|
95
|
+
# @return [Components::DateTime] The datetime component.
|
96
|
+
def datetime_tag(**attributes, &)
|
97
|
+
create_component(Components::DateTime, :datetime, **attributes, &)
|
98
|
+
end
|
99
|
+
|
100
|
+
# # Creates a boolean display tag for the field.
|
101
|
+
# #
|
102
|
+
# # @param attributes [Hash] Additional attributes for the boolean display.
|
103
|
+
# # @return [Components::Boolean] The boolean component.
|
104
|
+
# def boolean_tag(**attributes, &)
|
105
|
+
# create_component(Components::Boolean, :boolean, **attributes, &)
|
106
|
+
# end
|
107
|
+
|
108
|
+
# # Creates an association display tag for the field.
|
109
|
+
# #
|
110
|
+
# # @param attributes [Hash] Additional attributes for the association display.
|
111
|
+
# # @return [Components::Association] The association component.
|
112
|
+
# def association_tag(**attributes, &)
|
113
|
+
# create_component(Components::Association, :association, **attributes, &)
|
114
|
+
# end
|
115
|
+
|
116
|
+
# # Creates an attachment display tag for the field.
|
117
|
+
# #
|
118
|
+
# # @param attributes [Hash] Additional attributes for the attachment display.
|
119
|
+
# # @return [Components::Attachment] The attachment component.
|
120
|
+
# def attachment_tag(**attributes, &)
|
121
|
+
# create_component(Components::Attachment, :attachment, **attributes, &)
|
122
|
+
# end
|
153
123
|
|
154
124
|
# Wraps the field with additional markup.
|
155
125
|
#
|
156
|
-
# @param inner [Hash] Attributes for the inner wrapper.
|
157
126
|
# @param attributes [Hash] Additional attributes for the wrapper.
|
158
127
|
# @yield [block] The block to be executed within the wrapper.
|
159
128
|
# @return [Components::Wrapper] The wrapper component.
|
160
|
-
def wrapped(
|
161
|
-
|
162
|
-
inner[:class] = inner.delete(:class) || themed(inner.delete(:theme) || :inner_wrapper)
|
163
|
-
Components::Wrapper.new(self, class: wrapper_class, inner: inner, **attributes, &)
|
129
|
+
def wrapped(**attributes, &)
|
130
|
+
create_component(Components::Wrapper, :wrapper, **attributes, &)
|
164
131
|
end
|
165
132
|
|
166
|
-
# Creates a
|
133
|
+
# Creates a repeated field collection.
|
167
134
|
#
|
168
|
-
# @param range [
|
135
|
+
# @param range [#each] The collection of items to generate displays for.
|
169
136
|
# @yield [block] The block to be executed for each item in the collection.
|
170
137
|
# @return [FieldCollection] The field collection.
|
171
|
-
def
|
172
|
-
FieldCollection.new(field: self,
|
173
|
-
end
|
174
|
-
|
175
|
-
# Creates a submit button
|
176
|
-
#
|
177
|
-
# @param attributes [Hash] Additional attributes for the submit.
|
178
|
-
# @return [Components::SubmitButton] The submit button component.
|
179
|
-
def submit_button_tag(**attributes, &)
|
180
|
-
create_component(Components::SubmitButton, :submit_button, **attributes, &)
|
181
|
-
end
|
182
|
-
|
183
|
-
def extract_input(params)
|
184
|
-
raise "field##{dom.name} did not define an input component" unless @field_input_component
|
185
|
-
|
186
|
-
@field_input_component.extract_input(params)
|
138
|
+
def repeated(collection = [], &)
|
139
|
+
FieldCollection.new(field: self, collection:, &)
|
187
140
|
end
|
188
141
|
|
189
142
|
protected
|
190
143
|
|
191
144
|
def create_component(component_class, theme_key, **attributes, &)
|
192
|
-
|
193
|
-
raise "input component already defined: #{@field_input_component.inspect}" if @field_input_component
|
194
|
-
|
195
|
-
attributes = input_attributes.deep_merge(attributes)
|
196
|
-
@field_input_component = component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
197
|
-
else
|
198
|
-
component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
199
|
-
end
|
145
|
+
component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
200
146
|
end
|
201
147
|
|
202
148
|
def component_class_for(theme_key, attributes)
|
203
149
|
attributes.delete(:class) || themed(attributes.key?(:theme) ? attributes.delete(:theme) : theme_key)
|
204
150
|
end
|
205
151
|
|
206
|
-
def
|
207
|
-
value.present?
|
208
|
-
end
|
209
|
-
|
210
|
-
def determine_initial_value(value)
|
152
|
+
def determine_value(value)
|
211
153
|
return value unless value == NIL_VALUE
|
212
154
|
|
213
|
-
determine_from_association || determine_value_from_object
|
214
|
-
end
|
215
|
-
|
216
|
-
def determine_value_from_object
|
217
155
|
object.respond_to?(key) ? object.public_send(key) : nil
|
218
156
|
end
|
219
|
-
|
220
|
-
def determine_from_association
|
221
|
-
return nil unless reflection.present?
|
222
|
-
|
223
|
-
value = object.public_send(key)
|
224
|
-
case reflection.macro
|
225
|
-
when :has_many, :has_and_belongs_to_many
|
226
|
-
value&.map { |v| v.public_send(reflection.klass.primary_key) }
|
227
|
-
when :belongs_to, :has_one
|
228
|
-
value&.public_send(reflection.klass.primary_key)
|
229
|
-
else
|
230
|
-
raise ArgumentError, "Unsupported association type: #{reflection.macro}"
|
231
|
-
end
|
232
|
-
end
|
233
157
|
end
|
234
158
|
end
|
235
159
|
end
|
@@ -16,36 +16,21 @@ module Phlexi
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def field(**)
|
19
|
-
@field.class.new(key,
|
19
|
+
@field.class.new(key, **, parent: @field).tap do |field|
|
20
20
|
yield field if block_given?
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
def hidden_field_tag(value: "", force: false)
|
25
|
-
raise "Attempting to build hidden field on non-first field in a collection" unless index == 0 || force
|
26
|
-
|
27
|
-
@field.class
|
28
|
-
.new("hidden", parent: @field)
|
29
|
-
.input_tag(type: :hidden, value:)
|
30
|
-
end
|
31
23
|
end
|
32
24
|
|
33
|
-
def initialize(field:,
|
25
|
+
def initialize(field:, collection:, &)
|
34
26
|
@field = field
|
35
|
-
@
|
36
|
-
when Range, Array
|
37
|
-
range
|
38
|
-
when Integer
|
39
|
-
1..range
|
40
|
-
else
|
41
|
-
range.to_a
|
42
|
-
end
|
27
|
+
@collection = collection
|
43
28
|
each(&) if block_given?
|
44
29
|
end
|
45
30
|
|
46
31
|
def each(&)
|
47
|
-
@
|
48
|
-
yield Builder.new(
|
32
|
+
@collection.each.with_index do |item, index|
|
33
|
+
yield Builder.new(item, @field, index)
|
49
34
|
end
|
50
35
|
end
|
51
36
|
end
|
@@ -3,13 +3,18 @@
|
|
3
3
|
module Phlexi
|
4
4
|
module Display
|
5
5
|
module Structure
|
6
|
-
# A Namespace maps
|
6
|
+
# A Namespace maps an object to values, but doesn't actually have a value itself. For
|
7
7
|
# example, a `User` object or ActiveRecord model could be passed into the `:user` namespace.
|
8
|
-
# To access the values on a Namespace, the `field` can be called for single values.
|
9
8
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
9
|
+
# To access single values on a Namespace, #field can be used.
|
10
|
+
#
|
11
|
+
# To access nested objects within a namespace, two methods are available:
|
12
|
+
#
|
13
|
+
# 1. #nest_one: Used for single nested objects, such as if a `User belongs_to :profile` in
|
14
|
+
# ActiveRecord. This method returns another Namespace object.
|
15
|
+
#
|
16
|
+
# 2. #nest_many: Used for collections of nested objects, such as if a `User has_many :addresses` in
|
17
|
+
# ActiveRecord. This method returns a NamespaceCollection object.
|
13
18
|
class Namespace < Structure::Node
|
14
19
|
include Enumerable
|
15
20
|
|
@@ -29,21 +34,17 @@ module Phlexi
|
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
|
-
def submit_button(key = nil, **attributes, &)
|
33
|
-
field(key || SecureRandom.hex).submit_button_tag(**attributes, &)
|
34
|
-
end
|
35
|
-
|
36
37
|
# Creates a `Namespace` child instance with the parent set to the current instance, adds to
|
37
38
|
# the `@children` Hash to ensure duplicate child namespaces aren't created, then calls the
|
38
39
|
# method on the `@object` to get the child object to pass into that namespace.
|
39
40
|
#
|
40
41
|
# For example, if a `User#permission` returns a `Permission` object, we could map that to a
|
41
|
-
#
|
42
|
+
# display like this:
|
42
43
|
#
|
43
44
|
# ```ruby
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
45
|
+
# Phlexi::Display(user) do |display|
|
46
|
+
# display.nest_one :profile do |profile|
|
47
|
+
# render profile.field(:gender).text
|
47
48
|
# end
|
48
49
|
# end
|
49
50
|
# ```
|
@@ -56,13 +57,13 @@ module Phlexi
|
|
56
57
|
# an enumerable or array of `Address` classes:
|
57
58
|
#
|
58
59
|
# ```ruby
|
59
|
-
# Phlexi::Display
|
60
|
-
# render
|
61
|
-
# render
|
62
|
-
#
|
63
|
-
# render address.field(:street).
|
64
|
-
# render address.field(:state).
|
65
|
-
# render address.field(:zip).
|
60
|
+
# Phlexi::Display(user) do |display|
|
61
|
+
# render display.field(:email).text
|
62
|
+
# render display.field(:name).text
|
63
|
+
# display.nest_many :addresses do |address|
|
64
|
+
# render address.field(:street).text
|
65
|
+
# render address.field(:state).text
|
66
|
+
# render address.field(:zip).text
|
66
67
|
# end
|
67
68
|
# end
|
68
69
|
# ```
|
@@ -73,19 +74,6 @@ module Phlexi
|
|
73
74
|
create_child(key, NamespaceCollection, collection:, &)
|
74
75
|
end
|
75
76
|
|
76
|
-
def extract_input(params)
|
77
|
-
if params.is_a?(Array)
|
78
|
-
each_with_object({}) do |child, hash|
|
79
|
-
hash.merge! child.extract_input(params[0])
|
80
|
-
end
|
81
|
-
else
|
82
|
-
input = each_with_object({}) do |child, hash|
|
83
|
-
hash.merge! child.extract_input(params[key])
|
84
|
-
end
|
85
|
-
{key => input}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
77
|
# Iterates through the children of the current namespace, which could be `Namespace` or `Field`
|
90
78
|
# objects.
|
91
79
|
def each(&)
|
@@ -105,7 +93,7 @@ module Phlexi
|
|
105
93
|
end
|
106
94
|
end
|
107
95
|
|
108
|
-
# Creates a root Namespace
|
96
|
+
# Creates a root Namespace
|
109
97
|
def self.root(*, builder_klass:, **, &)
|
110
98
|
new(*, parent: nil, builder_klass:, **, &)
|
111
99
|
end
|
@@ -16,14 +16,6 @@ module Phlexi
|
|
16
16
|
each(&block)
|
17
17
|
end
|
18
18
|
|
19
|
-
def extract_input(params)
|
20
|
-
namespace = build_namespace(0)
|
21
|
-
@block.call(namespace)
|
22
|
-
|
23
|
-
inputs = params[key].map { |param| namespace.extract_input([param]) }
|
24
|
-
{key => inputs}
|
25
|
-
end
|
26
|
-
|
27
19
|
private
|
28
20
|
|
29
21
|
def each(&)
|
@@ -32,7 +24,7 @@ module Phlexi
|
|
32
24
|
|
33
25
|
# Builds and memoizes namespaces for the collection.
|
34
26
|
#
|
35
|
-
# @return [Array<
|
27
|
+
# @return [Array<Namespace>] An array of namespace objects.
|
36
28
|
def namespaces
|
37
29
|
@namespaces ||= @collection.map.with_index do |object, key|
|
38
30
|
build_namespace(key, object: object)
|
@@ -3,13 +3,19 @@
|
|
3
3
|
module Phlexi
|
4
4
|
module Display
|
5
5
|
module Structure
|
6
|
-
# Superclass for Namespace and Field classes.
|
7
|
-
#
|
6
|
+
# Superclass for Namespace and Field classes. Represents a node in the display tree structure.
|
7
|
+
#
|
8
|
+
# @attr_reader [Symbol] key The node's key
|
9
|
+
# @attr_reader [Node, nil] parent The node's parent in the tree structure
|
8
10
|
class Node
|
9
11
|
attr_reader :key, :parent
|
10
12
|
|
13
|
+
# Initializes a new Node instance.
|
14
|
+
#
|
15
|
+
# @param key [Symbol, String] The key for the node
|
16
|
+
# @param parent [Node, nil] The parent node
|
11
17
|
def initialize(key, parent:)
|
12
|
-
@key = key
|
18
|
+
@key = :"#{key}"
|
13
19
|
@parent = parent
|
14
20
|
end
|
15
21
|
end
|
data/lib/phlexi/display.rb
CHANGED
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.
|
4
|
+
version: 0.0.2
|
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-
|
11
|
+
date: 2024-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -186,43 +186,23 @@ files:
|
|
186
186
|
- lib/phlexi/display.rb
|
187
187
|
- lib/phlexi/display/base.rb
|
188
188
|
- lib/phlexi/display/components/base.rb
|
189
|
-
- lib/phlexi/display/components/
|
190
|
-
- lib/phlexi/display/components/
|
191
|
-
- lib/phlexi/display/components/
|
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
|
189
|
+
- lib/phlexi/display/components/concerns/displays_value.rb
|
190
|
+
- lib/phlexi/display/components/date_time.rb
|
191
|
+
- lib/phlexi/display/components/description.rb
|
199
192
|
- lib/phlexi/display/components/hint.rb
|
200
|
-
- lib/phlexi/display/components/input.rb
|
201
|
-
- lib/phlexi/display/components/input_array.rb
|
202
193
|
- lib/phlexi/display/components/label.rb
|
203
|
-
- lib/phlexi/display/components/
|
204
|
-
- lib/phlexi/display/components/
|
205
|
-
- lib/phlexi/display/components/
|
206
|
-
- lib/phlexi/display/components/textarea.rb
|
194
|
+
- lib/phlexi/display/components/number.rb
|
195
|
+
- lib/phlexi/display/components/placeholder.rb
|
196
|
+
- lib/phlexi/display/components/string.rb
|
207
197
|
- lib/phlexi/display/components/wrapper.rb
|
208
198
|
- lib/phlexi/display/field_options/associations.rb
|
209
|
-
- lib/phlexi/display/field_options/
|
210
|
-
- lib/phlexi/display/field_options/
|
211
|
-
- lib/phlexi/display/field_options/disabled.rb
|
212
|
-
- lib/phlexi/display/field_options/errors.rb
|
199
|
+
- lib/phlexi/display/field_options/attachments.rb
|
200
|
+
- lib/phlexi/display/field_options/description.rb
|
213
201
|
- lib/phlexi/display/field_options/hints.rb
|
214
202
|
- lib/phlexi/display/field_options/inferred_types.rb
|
215
203
|
- lib/phlexi/display/field_options/labels.rb
|
216
|
-
- lib/phlexi/display/field_options/
|
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
|
204
|
+
- lib/phlexi/display/field_options/placeholders.rb
|
224
205
|
- lib/phlexi/display/field_options/themes.rb
|
225
|
-
- lib/phlexi/display/field_options/validators.rb
|
226
206
|
- lib/phlexi/display/option_mapper.rb
|
227
207
|
- lib/phlexi/display/structure/dom.rb
|
228
208
|
- lib/phlexi/display/structure/field_builder.rb
|
@@ -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
|