phlexi-form 0.3.0 → 0.4.1
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 +4 -4
- data/README.md +1 -1
- data/gemfiles/default.gemfile.lock +34 -32
- data/gemfiles/rails_7.gemfile.lock +16 -18
- data/lib/phlexi/form/base.rb +18 -9
- data/lib/phlexi/form/builder.rb +297 -0
- data/lib/phlexi/form/components/base.rb +1 -1
- data/lib/phlexi/form/components/input.rb +16 -2
- data/lib/phlexi/form/components/select.rb +4 -0
- data/lib/phlexi/form/html.rb +18 -0
- data/lib/phlexi/form/{field_options → options}/autofocus.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/collection.rb +6 -2
- data/lib/phlexi/form/{field_options → options}/disabled.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/errors.rb +11 -11
- data/lib/phlexi/form/options/hints.rb +13 -0
- data/lib/phlexi/form/options/inferred_types.rb +32 -0
- data/lib/phlexi/form/{field_options → options}/length.rb +3 -3
- data/lib/phlexi/form/{field_options → options}/limit.rb +2 -2
- data/lib/phlexi/form/options/max.rb +55 -0
- data/lib/phlexi/form/options/min.rb +55 -0
- data/lib/phlexi/form/{field_options → options}/pattern.rb +2 -2
- data/lib/phlexi/form/{field_options → options}/readonly.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/required.rb +2 -2
- data/lib/phlexi/form/options/step.rb +39 -0
- data/lib/phlexi/form/options/validators.rb +24 -0
- data/lib/phlexi/form/structure/field_collection.rb +9 -29
- data/lib/phlexi/form/structure/namespace.rb +2 -114
- data/lib/phlexi/form/structure/namespace_collection.rb +1 -32
- data/lib/phlexi/form/theme.rb +160 -0
- data/lib/phlexi/form/version.rb +1 -1
- data/lib/phlexi/form.rb +3 -6
- metadata +34 -23
- data/lib/phlexi/form/field_options/associations.rb +0 -21
- data/lib/phlexi/form/field_options/hints.rb +0 -26
- data/lib/phlexi/form/field_options/inferred_types.rb +0 -159
- data/lib/phlexi/form/field_options/labels.rb +0 -28
- data/lib/phlexi/form/field_options/min_max.rb +0 -92
- data/lib/phlexi/form/field_options/multiple.rb +0 -65
- data/lib/phlexi/form/field_options/placeholder.rb +0 -18
- data/lib/phlexi/form/field_options/themes.rb +0 -207
- data/lib/phlexi/form/field_options/validators.rb +0 -48
- data/lib/phlexi/form/structure/dom.rb +0 -62
- data/lib/phlexi/form/structure/field_builder.rb +0 -243
- data/lib/phlexi/form/structure/node.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa37fb3ecaded18bae5e7be4d2773c227acc970c588eceb276214f39597cf5cf
|
4
|
+
data.tar.gz: cc06f9e6d21d87e66efe7eb4a27fd1b2e9721b14f9dab5b1ab7df5c74ff58834
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d37efe7ef9526991cce1495180edeacab2322c499302dab5e1118731bf2410e708e1404a6dfc1c3bebaf7846366fa05c57acc94669cc6caf60a798159ff9bf8b
|
7
|
+
data.tar.gz: ec2a45b47b89e0215cf034584d7d1d7cd5f60aa3fc640447492ba184a01069150879ddb101e7616b71fbde770222701df50ac96f0361e7a848967bc17c405885
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
phlexi-form (0.3.
|
4
|
+
phlexi-form (0.3.1)
|
5
5
|
activesupport
|
6
6
|
phlex (~> 1.11)
|
7
7
|
zeitwerk
|
@@ -9,32 +9,34 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actionpack (7.1
|
13
|
-
actionview (= 7.1
|
14
|
-
activesupport (= 7.1
|
12
|
+
actionpack (7.2.1)
|
13
|
+
actionview (= 7.2.1)
|
14
|
+
activesupport (= 7.2.1)
|
15
15
|
nokogiri (>= 1.8.5)
|
16
16
|
racc
|
17
|
-
rack (>= 2.2.4)
|
17
|
+
rack (>= 2.2.4, < 3.2)
|
18
18
|
rack-session (>= 1.0.1)
|
19
19
|
rack-test (>= 0.6.3)
|
20
20
|
rails-dom-testing (~> 2.2)
|
21
21
|
rails-html-sanitizer (~> 1.6)
|
22
|
-
|
23
|
-
|
22
|
+
useragent (~> 0.16)
|
23
|
+
actionview (7.2.1)
|
24
|
+
activesupport (= 7.2.1)
|
24
25
|
builder (~> 3.1)
|
25
26
|
erubi (~> 1.11)
|
26
27
|
rails-dom-testing (~> 2.2)
|
27
28
|
rails-html-sanitizer (~> 1.6)
|
28
|
-
activesupport (7.1
|
29
|
+
activesupport (7.2.1)
|
29
30
|
base64
|
30
31
|
bigdecimal
|
31
|
-
concurrent-ruby (~> 1.0, >= 1.
|
32
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
32
33
|
connection_pool (>= 2.2.5)
|
33
34
|
drb
|
34
35
|
i18n (>= 1.6, < 2)
|
36
|
+
logger (>= 1.4.2)
|
35
37
|
minitest (>= 5.1)
|
36
|
-
|
37
|
-
tzinfo (~> 2.0)
|
38
|
+
securerandom (>= 0.3)
|
39
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
38
40
|
addressable (2.8.7)
|
39
41
|
public_suffix (>= 2.0.2, < 7.0)
|
40
42
|
ansi (1.5.0)
|
@@ -48,7 +50,7 @@ GEM
|
|
48
50
|
builder (3.3.0)
|
49
51
|
bundle-audit (0.1.0)
|
50
52
|
bundler-audit
|
51
|
-
bundler-audit (0.9.
|
53
|
+
bundler-audit (0.9.2)
|
52
54
|
bundler (>= 1.2.0, < 3)
|
53
55
|
thor (~> 1.0)
|
54
56
|
capybara (3.40.0)
|
@@ -64,7 +66,7 @@ GEM
|
|
64
66
|
activesupport (>= 3.0.0)
|
65
67
|
railties (>= 3.0.0)
|
66
68
|
thor (>= 0.14.6)
|
67
|
-
concurrent-ruby (1.3.
|
69
|
+
concurrent-ruby (1.3.4)
|
68
70
|
connection_pool (2.4.1)
|
69
71
|
crass (1.0.6)
|
70
72
|
drb (2.2.1)
|
@@ -78,22 +80,22 @@ GEM
|
|
78
80
|
json (2.7.2)
|
79
81
|
language_server-protocol (3.17.0.3)
|
80
82
|
lint_roller (1.1.0)
|
83
|
+
logger (1.6.1)
|
81
84
|
loofah (2.22.0)
|
82
85
|
crass (~> 1.0.2)
|
83
86
|
nokogiri (>= 1.12.0)
|
84
87
|
matrix (0.4.2)
|
85
88
|
mini_mime (1.1.5)
|
86
|
-
minitest (5.
|
89
|
+
minitest (5.25.1)
|
87
90
|
minitest-reporters (1.7.1)
|
88
91
|
ansi
|
89
92
|
builder
|
90
93
|
minitest (>= 5.0)
|
91
94
|
ruby-progressbar
|
92
|
-
mutex_m (0.2.0)
|
93
95
|
nokogiri (1.16.7-x86_64-darwin)
|
94
96
|
racc (~> 1.4)
|
95
|
-
parallel (1.
|
96
|
-
parser (3.3.
|
97
|
+
parallel (1.26.3)
|
98
|
+
parser (3.3.5.0)
|
97
99
|
ast (~> 2.4.1)
|
98
100
|
racc
|
99
101
|
phlex (1.11.0)
|
@@ -119,10 +121,10 @@ GEM
|
|
119
121
|
rails-html-sanitizer (1.6.0)
|
120
122
|
loofah (~> 2.21)
|
121
123
|
nokogiri (~> 1.14)
|
122
|
-
railties (7.1
|
123
|
-
actionpack (= 7.1
|
124
|
-
activesupport (= 7.1
|
125
|
-
irb
|
124
|
+
railties (7.2.1)
|
125
|
+
actionpack (= 7.2.1)
|
126
|
+
activesupport (= 7.2.1)
|
127
|
+
irb (~> 1.13)
|
126
128
|
rackup (>= 1.0.0)
|
127
129
|
rake (>= 12.2)
|
128
130
|
thor (~> 1.0, >= 1.2.2)
|
@@ -132,31 +134,31 @@ GEM
|
|
132
134
|
rdoc (6.7.0)
|
133
135
|
psych (>= 4.0.0)
|
134
136
|
regexp_parser (2.9.2)
|
135
|
-
reline (0.5.
|
137
|
+
reline (0.5.10)
|
136
138
|
io-console (~> 0.5)
|
137
|
-
rexml (3.3.
|
138
|
-
|
139
|
-
rubocop (1.64.1)
|
139
|
+
rexml (3.3.7)
|
140
|
+
rubocop (1.65.1)
|
140
141
|
json (~> 2.3)
|
141
142
|
language_server-protocol (>= 3.17.0)
|
142
143
|
parallel (~> 1.10)
|
143
144
|
parser (>= 3.3.0.2)
|
144
145
|
rainbow (>= 2.2.2, < 4.0)
|
145
|
-
regexp_parser (>=
|
146
|
+
regexp_parser (>= 2.4, < 3.0)
|
146
147
|
rexml (>= 3.2.5, < 4.0)
|
147
148
|
rubocop-ast (>= 1.31.1, < 2.0)
|
148
149
|
ruby-progressbar (~> 1.7)
|
149
150
|
unicode-display_width (>= 2.4.0, < 3.0)
|
150
|
-
rubocop-ast (1.
|
151
|
+
rubocop-ast (1.32.3)
|
151
152
|
parser (>= 3.3.1.0)
|
152
153
|
rubocop-performance (1.21.1)
|
153
154
|
rubocop (>= 1.48.1, < 2.0)
|
154
155
|
rubocop-ast (>= 1.31.1, < 2.0)
|
155
156
|
ruby-progressbar (1.13.0)
|
156
|
-
|
157
|
+
securerandom (0.3.1)
|
158
|
+
standard (1.40.0)
|
157
159
|
language_server-protocol (~> 3.17.0.2)
|
158
160
|
lint_roller (~> 1.0)
|
159
|
-
rubocop (~> 1.
|
161
|
+
rubocop (~> 1.65.0)
|
160
162
|
standard-custom (~> 1.0.0)
|
161
163
|
standard-performance (~> 1.4)
|
162
164
|
standard-custom (1.0.2)
|
@@ -166,15 +168,15 @@ GEM
|
|
166
168
|
lint_roller (~> 1.1)
|
167
169
|
rubocop-performance (~> 1.21.0)
|
168
170
|
stringio (3.1.1)
|
169
|
-
|
170
|
-
thor (1.3.1)
|
171
|
+
thor (1.3.2)
|
171
172
|
tzinfo (2.0.6)
|
172
173
|
concurrent-ruby (~> 1.0)
|
173
174
|
unicode-display_width (2.5.0)
|
175
|
+
useragent (0.16.10)
|
174
176
|
webrick (1.8.1)
|
175
177
|
xpath (3.2.0)
|
176
178
|
nokogiri (~> 1.8)
|
177
|
-
zeitwerk (2.6.
|
179
|
+
zeitwerk (2.6.18)
|
178
180
|
|
179
181
|
PLATFORMS
|
180
182
|
x86_64-darwin
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
phlexi-form (0.3.
|
4
|
+
phlexi-form (0.3.1)
|
5
5
|
activesupport
|
6
6
|
phlex (~> 1.11)
|
7
7
|
zeitwerk
|
@@ -96,7 +96,7 @@ GEM
|
|
96
96
|
builder (3.3.0)
|
97
97
|
bundle-audit (0.1.0)
|
98
98
|
bundler-audit
|
99
|
-
bundler-audit (0.9.
|
99
|
+
bundler-audit (0.9.2)
|
100
100
|
bundler (>= 1.2.0, < 3)
|
101
101
|
thor (~> 1.0)
|
102
102
|
capybara (3.40.0)
|
@@ -112,7 +112,7 @@ GEM
|
|
112
112
|
activesupport (>= 3.0.0)
|
113
113
|
railties (>= 3.0.0)
|
114
114
|
thor (>= 0.14.6)
|
115
|
-
concurrent-ruby (1.3.
|
115
|
+
concurrent-ruby (1.3.4)
|
116
116
|
connection_pool (2.4.1)
|
117
117
|
crass (1.0.6)
|
118
118
|
date (3.3.4)
|
@@ -140,14 +140,14 @@ GEM
|
|
140
140
|
marcel (1.0.4)
|
141
141
|
matrix (0.4.2)
|
142
142
|
mini_mime (1.1.5)
|
143
|
-
minitest (5.
|
143
|
+
minitest (5.25.1)
|
144
144
|
minitest-reporters (1.7.1)
|
145
145
|
ansi
|
146
146
|
builder
|
147
147
|
minitest (>= 5.0)
|
148
148
|
ruby-progressbar
|
149
149
|
mutex_m (0.2.0)
|
150
|
-
net-imap (0.4.
|
150
|
+
net-imap (0.4.16)
|
151
151
|
date
|
152
152
|
net-protocol
|
153
153
|
net-pop (0.1.2)
|
@@ -159,8 +159,8 @@ GEM
|
|
159
159
|
nio4r (2.7.3)
|
160
160
|
nokogiri (1.16.7-x86_64-darwin)
|
161
161
|
racc (~> 1.4)
|
162
|
-
parallel (1.
|
163
|
-
parser (3.3.
|
162
|
+
parallel (1.26.3)
|
163
|
+
parser (3.3.5.0)
|
164
164
|
ast (~> 2.4.1)
|
165
165
|
racc
|
166
166
|
phlex (1.11.0)
|
@@ -213,32 +213,31 @@ GEM
|
|
213
213
|
rdoc (6.7.0)
|
214
214
|
psych (>= 4.0.0)
|
215
215
|
regexp_parser (2.9.2)
|
216
|
-
reline (0.5.
|
216
|
+
reline (0.5.10)
|
217
217
|
io-console (~> 0.5)
|
218
|
-
rexml (3.3.
|
219
|
-
|
220
|
-
rubocop (1.64.1)
|
218
|
+
rexml (3.3.7)
|
219
|
+
rubocop (1.65.1)
|
221
220
|
json (~> 2.3)
|
222
221
|
language_server-protocol (>= 3.17.0)
|
223
222
|
parallel (~> 1.10)
|
224
223
|
parser (>= 3.3.0.2)
|
225
224
|
rainbow (>= 2.2.2, < 4.0)
|
226
|
-
regexp_parser (>=
|
225
|
+
regexp_parser (>= 2.4, < 3.0)
|
227
226
|
rexml (>= 3.2.5, < 4.0)
|
228
227
|
rubocop-ast (>= 1.31.1, < 2.0)
|
229
228
|
ruby-progressbar (~> 1.7)
|
230
229
|
unicode-display_width (>= 2.4.0, < 3.0)
|
231
|
-
rubocop-ast (1.
|
230
|
+
rubocop-ast (1.32.3)
|
232
231
|
parser (>= 3.3.1.0)
|
233
232
|
rubocop-performance (1.21.1)
|
234
233
|
rubocop (>= 1.48.1, < 2.0)
|
235
234
|
rubocop-ast (>= 1.31.1, < 2.0)
|
236
235
|
ruby-progressbar (1.13.0)
|
237
236
|
sqlite3 (1.7.3-x86_64-darwin)
|
238
|
-
standard (1.
|
237
|
+
standard (1.40.0)
|
239
238
|
language_server-protocol (~> 3.17.0.2)
|
240
239
|
lint_roller (~> 1.0)
|
241
|
-
rubocop (~> 1.
|
240
|
+
rubocop (~> 1.65.0)
|
242
241
|
standard-custom (~> 1.0.0)
|
243
242
|
standard-performance (~> 1.4)
|
244
243
|
standard-custom (1.0.2)
|
@@ -248,8 +247,7 @@ GEM
|
|
248
247
|
lint_roller (~> 1.1)
|
249
248
|
rubocop-performance (~> 1.21.0)
|
250
249
|
stringio (3.1.1)
|
251
|
-
|
252
|
-
thor (1.3.1)
|
250
|
+
thor (1.3.2)
|
253
251
|
timeout (0.4.1)
|
254
252
|
tzinfo (2.0.6)
|
255
253
|
concurrent-ruby (~> 1.0)
|
@@ -260,7 +258,7 @@ GEM
|
|
260
258
|
websocket-extensions (0.1.5)
|
261
259
|
xpath (3.2.0)
|
262
260
|
nokogiri (~> 1.8)
|
263
|
-
zeitwerk (2.6.
|
261
|
+
zeitwerk (2.6.18)
|
264
262
|
|
265
263
|
PLATFORMS
|
266
264
|
x86_64-darwin
|
data/lib/phlexi/form/base.rb
CHANGED
@@ -17,10 +17,18 @@ module Phlexi
|
|
17
17
|
#
|
18
18
|
# @attr_reader [Symbol] key The form's key, derived from the record or explicitly set
|
19
19
|
# @attr_reader [ActiveModel::Model, nil] object The form's associated object
|
20
|
-
class Base <
|
21
|
-
class Namespace < Structure::Namespace; end
|
20
|
+
class Base < Phlexi::Form::HTML
|
21
|
+
class Namespace < Phlexi::Form::Structure::Namespace; end
|
22
22
|
|
23
|
-
class
|
23
|
+
class Builder < Phlexi::Form::Builder; end
|
24
|
+
|
25
|
+
def self.inline(*, **, &block)
|
26
|
+
raise ArgumentError, "block is required" unless block
|
27
|
+
|
28
|
+
new(*, **) do |f|
|
29
|
+
f.instance_exec(&block)
|
30
|
+
end
|
31
|
+
end
|
24
32
|
|
25
33
|
attr_reader :key, :object
|
26
34
|
|
@@ -39,7 +47,6 @@ module Phlexi
|
|
39
47
|
def initialize(record, action: nil, method: nil, attributes: {}, **options)
|
40
48
|
@form_action = action
|
41
49
|
@form_method = method
|
42
|
-
@form_class = options.delete(:class)
|
43
50
|
@attributes = attributes
|
44
51
|
@namespace_klass = options.delete(:namespace_klass) || default_namespace_klass
|
45
52
|
@builder_klass = options.delete(:builder_klass) || default_builder_klass
|
@@ -53,8 +60,8 @@ module Phlexi
|
|
53
60
|
# Renders the form template.
|
54
61
|
#
|
55
62
|
# @return [void]
|
56
|
-
def view_template
|
57
|
-
form_tag { form_template }
|
63
|
+
def view_template(&)
|
64
|
+
form_tag { form_template(&) }
|
58
65
|
end
|
59
66
|
|
60
67
|
# Executes the form's content block.
|
@@ -62,7 +69,7 @@ module Phlexi
|
|
62
69
|
#
|
63
70
|
# @return [void]
|
64
71
|
def form_template
|
65
|
-
|
72
|
+
yield if block_given?
|
66
73
|
end
|
67
74
|
|
68
75
|
def extract_input(params)
|
@@ -117,7 +124,9 @@ module Phlexi
|
|
117
124
|
# Retrieves the form's CSS classes.
|
118
125
|
#
|
119
126
|
# @return [String] The form's CSS classes
|
120
|
-
|
127
|
+
def form_class
|
128
|
+
themed(:base, nil)
|
129
|
+
end
|
121
130
|
|
122
131
|
# Renders the form tag with its contents.
|
123
132
|
#
|
@@ -236,7 +245,7 @@ module Phlexi
|
|
236
245
|
end
|
237
246
|
|
238
247
|
def default_builder_klass
|
239
|
-
self.class::
|
248
|
+
self.class::Builder
|
240
249
|
end
|
241
250
|
end
|
242
251
|
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlexi
|
4
|
+
module Form
|
5
|
+
# Builder class is responsible for building form fields with various options and components.
|
6
|
+
class Builder < Phlexi::Field::Builder
|
7
|
+
include Phlexi::Form::HTML::Behaviour
|
8
|
+
include Options::Validators
|
9
|
+
include Options::InferredTypes
|
10
|
+
include Options::Errors
|
11
|
+
include Options::Collection
|
12
|
+
include Options::Hints
|
13
|
+
include Options::Required
|
14
|
+
include Options::Autofocus
|
15
|
+
include Options::Disabled
|
16
|
+
include Options::Readonly
|
17
|
+
include Options::Length
|
18
|
+
include Options::Max
|
19
|
+
include Options::Min
|
20
|
+
include Options::Pattern
|
21
|
+
include Options::Limit
|
22
|
+
include Options::Step
|
23
|
+
|
24
|
+
class FieldCollection < Phlexi::Form::Structure::FieldCollection; end
|
25
|
+
|
26
|
+
attr_reader :input_attributes
|
27
|
+
|
28
|
+
# Initializes a new Builder instance.
|
29
|
+
#
|
30
|
+
# @param key [Symbol, String] The key for the field.
|
31
|
+
# @param parent [Structure::Namespace] The parent object.
|
32
|
+
# @param object [Object, nil] The associated object.
|
33
|
+
# @param value [Object] The initial value for the field.
|
34
|
+
# @param input_attributes [Hash] Default attributes to apply to input fields.
|
35
|
+
# @param options [Hash] Additional options for the field.
|
36
|
+
def initialize(*, input_attributes: {}, **)
|
37
|
+
super(*, **)
|
38
|
+
|
39
|
+
@input_attributes = input_attributes
|
40
|
+
end
|
41
|
+
|
42
|
+
# Creates an input tag for the field.
|
43
|
+
#
|
44
|
+
# @param attributes [Hash] Additional attributes for the input.
|
45
|
+
# @return [Components::Input] The input component.
|
46
|
+
def input_tag(**, &)
|
47
|
+
create_component(Components::Input, :input, **, &)
|
48
|
+
end
|
49
|
+
|
50
|
+
def string_tag(**, &)
|
51
|
+
input_tag(type: :text, theme: :string, **, &)
|
52
|
+
end
|
53
|
+
|
54
|
+
def number_tag(**, &)
|
55
|
+
input_tag(type: :number, theme: :number, **, &)
|
56
|
+
end
|
57
|
+
|
58
|
+
def date_tag(**, &)
|
59
|
+
input_tag(type: :date, theme: :date, **, &)
|
60
|
+
end
|
61
|
+
|
62
|
+
def time_tag(**, &)
|
63
|
+
input_tag(type: :time, theme: :time, **, &)
|
64
|
+
end
|
65
|
+
|
66
|
+
def datetime_local_tag(**, &)
|
67
|
+
input_tag(type: :"datetime-local", theme: :datetime, **, &)
|
68
|
+
end
|
69
|
+
alias_method :datetime_tag, :datetime_local_tag
|
70
|
+
|
71
|
+
def email_tag(**, &)
|
72
|
+
input_tag(type: :email, theme: :email, **, &)
|
73
|
+
end
|
74
|
+
|
75
|
+
def password_tag(**, &)
|
76
|
+
input_tag(type: :password, theme: :password, **, &)
|
77
|
+
end
|
78
|
+
|
79
|
+
def phone_tag(**, &)
|
80
|
+
input_tag(type: :tel, theme: :phone, **, &)
|
81
|
+
end
|
82
|
+
|
83
|
+
def color_tag(**, &)
|
84
|
+
input_tag(type: :color, theme: :color, **, &)
|
85
|
+
end
|
86
|
+
|
87
|
+
def url_tag(**, &)
|
88
|
+
input_tag(type: :url, theme: :url, **, &)
|
89
|
+
end
|
90
|
+
|
91
|
+
def search_tag(**, &)
|
92
|
+
input_tag(type: :search, theme: :search, **, &)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Creates a checkbox tag for the field.
|
96
|
+
#
|
97
|
+
# @param attributes [Hash] Additional attributes for the checkbox.
|
98
|
+
# @return [Components::Checkbox] The checkbox component.
|
99
|
+
def checkbox_tag(**, &)
|
100
|
+
create_component(Components::Checkbox, :checkbox, **, &)
|
101
|
+
end
|
102
|
+
|
103
|
+
def boolean_tag(**, &)
|
104
|
+
checkbox_tag(**, theme: :boolean, &)
|
105
|
+
end
|
106
|
+
|
107
|
+
def file_input_tag(**, &)
|
108
|
+
create_component(Components::FileInput, :file, **, &)
|
109
|
+
end
|
110
|
+
alias_method :file_tag, :file_input_tag
|
111
|
+
|
112
|
+
# Creates collection checkboxes for the field.
|
113
|
+
#
|
114
|
+
# @param attributes [Hash] Additional attributes for the collection checkboxes.
|
115
|
+
# @yield [block] The block to be executed for each checkbox.
|
116
|
+
# @return [Components::CollectionCheckboxes] The collection checkboxes component.
|
117
|
+
def collection_checkboxes_tag(**, &)
|
118
|
+
create_component(Components::CollectionCheckboxes, :collection_checkboxes, **, &)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Creates a radio button tag for the field.
|
122
|
+
#
|
123
|
+
# @param attributes [Hash] Additional attributes for the radio button.
|
124
|
+
# @return [Components::RadioButton] The radio button component.
|
125
|
+
def radio_button_tag(**, &)
|
126
|
+
create_component(Components::RadioButton, :radio, **, &)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Creates collection radio buttons for the field.
|
130
|
+
#
|
131
|
+
# @param attributes [Hash] Additional attributes for the collection radio buttons.
|
132
|
+
# @yield [block] The block to be executed for each radio button.
|
133
|
+
# @return [Components::CollectionRadioButtons] The collection radio buttons component.
|
134
|
+
def collection_radio_buttons_tag(**, &)
|
135
|
+
create_component(Components::CollectionRadioButtons, :collection_radio_buttons, **, &)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Creates a textarea tag for the field.
|
139
|
+
#
|
140
|
+
# @param attributes [Hash] Additional attributes for the textarea.
|
141
|
+
# @return [Components::Textarea] The textarea component.
|
142
|
+
def textarea_tag(**, &)
|
143
|
+
create_component(Components::Textarea, :textarea, **, &)
|
144
|
+
end
|
145
|
+
alias_method :text_tag, :textarea_tag
|
146
|
+
|
147
|
+
def hstore_tag(**, &)
|
148
|
+
@value = @value.to_s.tr("{}", "")
|
149
|
+
textarea_tag(**, theme: :hstore, &)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Creates a select tag for the field.
|
153
|
+
#
|
154
|
+
# @param attributes [Hash] Additional attributes for the select.
|
155
|
+
# @return [Components::Select] The select component.
|
156
|
+
def select_tag(**, &)
|
157
|
+
create_component(Components::Select, :select, **, &)
|
158
|
+
end
|
159
|
+
|
160
|
+
def belongs_to_tag(**options, &)
|
161
|
+
options.fetch(:input_param) {
|
162
|
+
options[:input_param] = if association_reflection.respond_to?(:options) && association_reflection.options[:foreign_key]
|
163
|
+
association_reflection.options[:foreign_key]
|
164
|
+
else
|
165
|
+
:"#{association_reflection.name}_id"
|
166
|
+
end
|
167
|
+
}
|
168
|
+
select_tag(**options, &)
|
169
|
+
end
|
170
|
+
|
171
|
+
def polymorphic_belongs_to_tag(**, &)
|
172
|
+
# TODO: this requires a grouped_select component
|
173
|
+
# see: Plutonium::Core::Fields::Inputs::PolymorphicBelongsToAssociationInput
|
174
|
+
raise NotImplementedError, "polymorphic belongs_to associations are not YET supported"
|
175
|
+
end
|
176
|
+
|
177
|
+
def has_one_tag(**, &)
|
178
|
+
raise NotImplementedError, "has_one associations are NOT supported"
|
179
|
+
end
|
180
|
+
|
181
|
+
def has_many_tag(**options, &)
|
182
|
+
options.fetch(:input_param) {
|
183
|
+
options[:input_param] = :"#{association_reflection.name.to_s.singularize}_ids"
|
184
|
+
}
|
185
|
+
|
186
|
+
select_tag(**options, &)
|
187
|
+
end
|
188
|
+
|
189
|
+
def input_array_tag(**, &)
|
190
|
+
create_component(Components::InputArray, :array, **, &)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Creates a label tag for the field.
|
194
|
+
#
|
195
|
+
# @param attributes [Hash] Additional attributes for the label.
|
196
|
+
# @return [Components::Label] The label component.
|
197
|
+
def label_tag(**, &)
|
198
|
+
create_component(Components::Label, :label, **, &)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Creates a hint tag for the field.
|
202
|
+
#
|
203
|
+
# @param attributes [Hash] Additional attributes for the hint.
|
204
|
+
# @return [Components::Hint] The hint component.
|
205
|
+
def hint_tag(**, &)
|
206
|
+
create_component(Components::Hint, :hint, **, &)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Creates an error tag for the field.
|
210
|
+
#
|
211
|
+
# @param attributes [Hash] Additional attributes for the error.
|
212
|
+
# @return [Components::Error] The error component.
|
213
|
+
def error_tag(**, &)
|
214
|
+
create_component(Components::Error, :error, **, &)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Creates a full error tag for the field.
|
218
|
+
#
|
219
|
+
# @param attributes [Hash] Additional attributes for the full error.
|
220
|
+
# @return [Components::FullError] The full error component.
|
221
|
+
def full_error_tag(**, &)
|
222
|
+
create_component(Components::FullError, :full_error, **, &)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Wraps the field with additional markup.
|
226
|
+
#
|
227
|
+
# @param inner [Hash] Attributes for the inner wrapper.
|
228
|
+
# @param attributes [Hash] Additional attributes for the wrapper.
|
229
|
+
# @yield [block] The block to be executed within the wrapper.
|
230
|
+
# @return [Components::Wrapper] The wrapper component.
|
231
|
+
def wrapped(inner: {}, **attributes, &)
|
232
|
+
attributes = apply_component_theme(attributes, :wrapper)
|
233
|
+
inner = apply_component_theme(inner, :inner_wrapper)
|
234
|
+
Components::Wrapper.new(self, inner: inner, **attributes, &)
|
235
|
+
end
|
236
|
+
|
237
|
+
# Creates a submit button
|
238
|
+
#
|
239
|
+
# @param attributes [Hash] Additional attributes for the submit.
|
240
|
+
# @return [Components::SubmitButton] The submit button component.
|
241
|
+
def submit_button_tag(**, &)
|
242
|
+
create_component(Components::SubmitButton, :submit_button, **, &)
|
243
|
+
end
|
244
|
+
|
245
|
+
def extract_input(params)
|
246
|
+
raise "field##{dom.name} did not define an input component" unless @field_input_extractor
|
247
|
+
|
248
|
+
@field_input_extractor.extract_input(params)
|
249
|
+
end
|
250
|
+
|
251
|
+
protected
|
252
|
+
|
253
|
+
def create_component(component_class, theme_key, **attributes, &)
|
254
|
+
attributes = mix(input_attributes, attributes) if component_class.include?(Phlexi::Form::Components::Concerns::HandlesInput)
|
255
|
+
component = component_class.new(self, **apply_component_theme(attributes, theme_key), &)
|
256
|
+
if component_class.include?(Components::Concerns::ExtractsInput)
|
257
|
+
raise "input component already defined: #{@field_input_extractor.inspect}" if @field_input_extractor
|
258
|
+
|
259
|
+
@field_input_extractor = component
|
260
|
+
end
|
261
|
+
|
262
|
+
component
|
263
|
+
end
|
264
|
+
|
265
|
+
def apply_component_theme(attributes, theme_key)
|
266
|
+
return attributes if attributes.key?(:class!)
|
267
|
+
|
268
|
+
theme_key = attributes.delete(:theme) || theme_key
|
269
|
+
mix({class: themed(theme_key, self)}, attributes)
|
270
|
+
end
|
271
|
+
|
272
|
+
def determine_initial_value(value)
|
273
|
+
return value unless value == NIL_VALUE
|
274
|
+
|
275
|
+
determine_value_from_association || super
|
276
|
+
end
|
277
|
+
|
278
|
+
def determine_value_from_object
|
279
|
+
object.respond_to?(key) ? object.public_send(key) : nil
|
280
|
+
end
|
281
|
+
|
282
|
+
def determine_value_from_association
|
283
|
+
return nil unless association_reflection.present?
|
284
|
+
|
285
|
+
value = object.public_send(key)
|
286
|
+
case association_reflection.macro
|
287
|
+
when :has_many, :has_and_belongs_to_many
|
288
|
+
value&.map { |v| v.public_send(association_reflection.klass.primary_key) }
|
289
|
+
when :belongs_to, :has_one
|
290
|
+
value&.public_send(association_reflection.klass.primary_key)
|
291
|
+
else
|
292
|
+
raise ArgumentError, "Unsupported association type: #{association_reflection.macro}"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|