dsfr-form_builder 0.0.7 → 0.0.9
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/lib/dsfr-form_builder.rb +130 -103
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9bd7c63d280b90c223ac24825d70fd3b529c71fb1d242335785235a5a6e7370c
|
|
4
|
+
data.tar.gz: c90dbb0f5479e9401afebcd99e199c0d2c95be725b2333d84f1b2dd03b24bdee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f8d706444e7afec231c0bd8cf094be44c9a8ad4b0c5af3149749fca02d9da74b51d13c69b884183ad97fda19d8f847006f4f7501b9df43b5dbf8436c5764397f
|
|
7
|
+
data.tar.gz: e1297220a5fef326d01d1381d70fe85543b9d3371327f25f7d294ac7564ccea48d28d54db4edc747ce199e8765b0fa474ae67ffafa2f340ebcf9d1a2914b33d2
|
data/lib/dsfr-form_builder.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module Dsfr
|
|
2
2
|
include ActiveSupport::Configurable
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
class FormBuilder < ActionView::Helpers::FormBuilder
|
|
6
5
|
include ActionView::Helpers::OutputSafetyHelper
|
|
7
6
|
|
|
@@ -12,160 +11,179 @@ module Dsfr
|
|
|
12
11
|
self.display_required_tags = options.fetch(:display_required_tags, true)
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def dsfr_email_field(attribute, opts = {})
|
|
24
|
-
dsfr_input_field(attribute, :email_field, opts)
|
|
14
|
+
def dsfr_button(value = nil, options = {}, &block)
|
|
15
|
+
if block_given?
|
|
16
|
+
options = value || {}
|
|
17
|
+
value = @template.capture { yield(value) }
|
|
18
|
+
end
|
|
19
|
+
options[:type] ||= :button
|
|
20
|
+
options[:class] = @template.class_names("fr-btn", options[:class])
|
|
21
|
+
button(value, options)
|
|
25
22
|
end
|
|
26
23
|
|
|
27
|
-
def
|
|
28
|
-
|
|
24
|
+
def dsfr_submit(value = nil, options = {}, &block)
|
|
25
|
+
if block_given?
|
|
26
|
+
options = value || {}
|
|
27
|
+
value = @template.capture { yield(value) }
|
|
28
|
+
end
|
|
29
|
+
options[:type] = :submit
|
|
30
|
+
dsfr_button(value, options)
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
%i[text_field text_area email_field url_field phone_field number_field].each do |field_type|
|
|
34
|
+
define_method("dsfr_#{field_type}") do |attribute, **options|
|
|
35
|
+
dsfr_input_field(attribute, field_type, **options)
|
|
36
|
+
end
|
|
33
37
|
end
|
|
34
38
|
|
|
35
|
-
def
|
|
36
|
-
|
|
39
|
+
def dsfr_input_group(attribute, opts, kind: :input, &block)
|
|
40
|
+
@template.tag.div(
|
|
41
|
+
yield(block),
|
|
42
|
+
data: opts[:data],
|
|
43
|
+
class: @template.class_names(
|
|
44
|
+
"fr-#{kind}-group",
|
|
45
|
+
opts[:class],
|
|
46
|
+
"fr-#{kind}-group--error" => @object&.errors&.include?(attribute)
|
|
47
|
+
)
|
|
48
|
+
)
|
|
37
49
|
end
|
|
38
50
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
def dsfr_input_field(attribute, input_kind, opts = {})
|
|
52
|
+
dsfr_input_group(attribute, opts) do
|
|
53
|
+
@template.safe_join([
|
|
54
|
+
dsfr_label_with_hint(attribute, opts),
|
|
55
|
+
public_send(input_kind, attribute, class: "fr-input", **opts.except(:class, :hint, :label, :data)),
|
|
56
|
+
dsfr_error_message(attribute)
|
|
57
|
+
])
|
|
42
58
|
end
|
|
43
59
|
end
|
|
44
60
|
|
|
45
|
-
def
|
|
46
|
-
dsfr_input_group(attribute, opts) do
|
|
47
|
-
@template.safe_join(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
]
|
|
53
|
-
)
|
|
61
|
+
def dsfr_file_field(attribute, opts = {})
|
|
62
|
+
dsfr_input_group(attribute, opts, kind: :upload) do
|
|
63
|
+
@template.safe_join([
|
|
64
|
+
dsfr_label_with_hint(attribute, opts.except(:class)),
|
|
65
|
+
file_field(attribute, class: "fr-upload", **opts.except(:class, :hint, :label, :data)),
|
|
66
|
+
dsfr_error_message(attribute)
|
|
67
|
+
])
|
|
54
68
|
end
|
|
55
69
|
end
|
|
56
70
|
|
|
57
71
|
def dsfr_check_box(attribute, opts = {}, checked_value = "1", unchecked_value = "0")
|
|
58
|
-
@template.
|
|
59
|
-
|
|
60
|
-
@template.safe_join(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
]
|
|
65
|
-
)
|
|
72
|
+
@template.tag.div(class: @template.class_names("fr-fieldset__element", "fr-fieldset__element--inline" => opts.delete(:inline))) do
|
|
73
|
+
dsfr_input_group(attribute, opts, kind: :checkbox) do
|
|
74
|
+
@template.safe_join([
|
|
75
|
+
check_box(attribute, opts.except(:label, :hint), checked_value, unchecked_value),
|
|
76
|
+
dsfr_label_with_hint(attribute, opts)
|
|
77
|
+
])
|
|
66
78
|
end
|
|
67
79
|
end
|
|
68
80
|
end
|
|
69
81
|
|
|
82
|
+
def dsfr_collection_check_boxes(method, collection, value_method, text_method, opts = {}, html_options = {})
|
|
83
|
+
legend = opts.delete(:legend) || @object&.class&.human_attribute_name(method)
|
|
84
|
+
if legend.blank?
|
|
85
|
+
raise ArgumentError.new("Please provide the legend option, or use an object whose class responds to :human_attribute_name")
|
|
86
|
+
end
|
|
87
|
+
legend = @template.safe_join([ legend, hint_tag(opts.delete(:hint)) ])
|
|
88
|
+
name = opts.delete(:name) || "#{@object_name}[#{method}][]"
|
|
89
|
+
html_options[:class] = @template.class_names("fr-fieldset", html_options[:class])
|
|
90
|
+
@template.tag.fieldset(**html_options) do
|
|
91
|
+
@template.safe_join([
|
|
92
|
+
@template.tag.legend(legend, class: "fr-fieldset__legend--regular fr-fieldset__legend"),
|
|
93
|
+
@template.hidden_field_tag(name, "", id: nil),
|
|
94
|
+
collection.map do |item|
|
|
95
|
+
value = item.send(value_method)
|
|
96
|
+
checkbox_options = {
|
|
97
|
+
name: name,
|
|
98
|
+
value: value,
|
|
99
|
+
id: field_id(method, value),
|
|
100
|
+
label: item.send(text_method),
|
|
101
|
+
inline: opts[:inline],
|
|
102
|
+
checked: selected?(method, value),
|
|
103
|
+
include_hidden: false
|
|
104
|
+
}
|
|
105
|
+
dsfr_check_box(method, checkbox_options, value, "")
|
|
106
|
+
end
|
|
107
|
+
])
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
70
111
|
def dsfr_select(attribute, choices, input_options: {}, **opts)
|
|
71
|
-
|
|
72
|
-
@template.safe_join(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
]
|
|
78
|
-
)
|
|
112
|
+
dsfr_input_group(attribute, opts, kind: :select) do
|
|
113
|
+
@template.safe_join([
|
|
114
|
+
dsfr_label_with_hint(attribute, opts),
|
|
115
|
+
dsfr_select_tag(attribute, choices, opts.merge(input_options).except(:hint, :name)),
|
|
116
|
+
dsfr_error_message(attribute)
|
|
117
|
+
])
|
|
79
118
|
end
|
|
80
119
|
end
|
|
81
120
|
|
|
82
121
|
def dsfr_select_tag(attribute, choices, opts)
|
|
83
|
-
|
|
122
|
+
opts[:class] = @template.class_names("fr-select", opts[:class])
|
|
123
|
+
options = opts.slice(:include_blank, :selected, :disabled)
|
|
124
|
+
html_options = opts.except(:include_blank, :selected, :disabled)
|
|
125
|
+
select(attribute, choices, options, **html_options)
|
|
84
126
|
end
|
|
85
127
|
|
|
86
128
|
def dsfr_radio_buttons(attribute, choices, legend: nil, hint: nil, **opts)
|
|
87
129
|
legend_content = @template.safe_join([
|
|
88
130
|
legend || @object.class.human_attribute_name(attribute),
|
|
89
|
-
|
|
90
|
-
]
|
|
91
|
-
@template.
|
|
92
|
-
@template.safe_join(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
131
|
+
hint_tag(hint)
|
|
132
|
+
])
|
|
133
|
+
@template.tag.fieldset(class: "fr-fieldset") do
|
|
134
|
+
@template.safe_join([
|
|
135
|
+
@template.tag.legend(legend_content, class: "fr-fieldset__legend--regular fr-fieldset__legend"),
|
|
136
|
+
choices.map do |choice|
|
|
137
|
+
dsfr_radio_option(
|
|
138
|
+
attribute,
|
|
139
|
+
value: choice[:value],
|
|
140
|
+
label_text: choice[:label],
|
|
141
|
+
hint: choice[:hint],
|
|
142
|
+
checked: choice[:checked],
|
|
143
|
+
**opts
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
])
|
|
98
147
|
end
|
|
99
148
|
end
|
|
100
149
|
|
|
101
150
|
def dsfr_radio_option(attribute, value:, label_text:, hint:, checked:, rich: false, **opts)
|
|
102
|
-
@template.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
label([ attribute, value ].join("_").to_sym) do
|
|
109
|
-
@template.safe_join(
|
|
110
|
-
[
|
|
111
|
-
label_text,
|
|
112
|
-
hint.present? ? @template.content_tag(:span, hint, class: "fr-hint-text") : nil
|
|
113
|
-
]
|
|
114
|
-
)
|
|
115
|
-
end
|
|
116
|
-
]
|
|
117
|
-
)
|
|
151
|
+
@template.tag.div(class: "fr-fieldset__element") do
|
|
152
|
+
@template.tag.div(class: @template.class_names("fr-radio-group", "fr-radio-rich" => rich)) do
|
|
153
|
+
@template.safe_join([
|
|
154
|
+
radio_button(attribute, value, checked:, **opts),
|
|
155
|
+
dsfr_label_with_hint(attribute, opts.merge(label_text: label_text, hint: hint, value: value))
|
|
156
|
+
])
|
|
118
157
|
end
|
|
119
158
|
end
|
|
120
159
|
end
|
|
121
160
|
|
|
122
161
|
def dsfr_label_with_hint(attribute, opts = {})
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@template.safe_join(label_and_tags)
|
|
162
|
+
label(attribute, class: @template.class_names("fr-label", opts[:class]), value: opts[:value]) do
|
|
163
|
+
@template.safe_join([
|
|
164
|
+
opts[:label_text] || label_value(attribute, opts),
|
|
165
|
+
(required_tag if opts[:required] && display_required_tags),
|
|
166
|
+
(hint_tag(opts[:hint]) if opts[:hint])
|
|
167
|
+
])
|
|
130
168
|
end
|
|
131
169
|
end
|
|
132
170
|
|
|
133
171
|
def required_tag
|
|
134
|
-
@template.
|
|
172
|
+
@template.tag.span("*", class: "fr-text-error")
|
|
135
173
|
end
|
|
136
174
|
|
|
137
175
|
def dsfr_error_message(attr)
|
|
138
|
-
return if @object.errors[attr].none?
|
|
176
|
+
return if @object.nil? || @object.errors[attr].none?
|
|
139
177
|
|
|
140
|
-
@template.
|
|
178
|
+
@template.tag.p(class: "fr-messages-group") do
|
|
141
179
|
safe_join(@object.errors.full_messages_for(attr).map do |msg|
|
|
142
|
-
@template.
|
|
180
|
+
@template.tag.span(msg, class: "fr-message fr-message--error")
|
|
143
181
|
end)
|
|
144
182
|
end
|
|
145
183
|
end
|
|
146
184
|
|
|
147
185
|
def hint_tag(text)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
@template.content_tag(:span, class: "fr-hint-text") do
|
|
151
|
-
text
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
@template.content_tag(:span, text, class: "fr-hint-text")
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def join_classes(arr)
|
|
158
|
-
arr.compact.join(" ")
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def input_group_classes(attribute, opts)
|
|
162
|
-
join_classes(
|
|
163
|
-
[
|
|
164
|
-
"fr-input-group",
|
|
165
|
-
@object.errors[attribute].any? ? "fr-input-group--error" : nil,
|
|
166
|
-
opts[:class]
|
|
167
|
-
]
|
|
168
|
-
)
|
|
186
|
+
@template.tag.span(text, class: "fr-hint-text") if text
|
|
169
187
|
end
|
|
170
188
|
|
|
171
189
|
def label_value(attribute, opts)
|
|
@@ -173,5 +191,14 @@ module Dsfr
|
|
|
173
191
|
|
|
174
192
|
(@object.try(:object) || @object).class.human_attribute_name(attribute)
|
|
175
193
|
end
|
|
194
|
+
|
|
195
|
+
private
|
|
196
|
+
|
|
197
|
+
# TODO: Allow this helper to be used by select options and radio buttons.
|
|
198
|
+
def selected?(method, value)
|
|
199
|
+
return unless @object.respond_to?(method)
|
|
200
|
+
|
|
201
|
+
(@object.send(method) || []).include?(value)
|
|
202
|
+
end
|
|
176
203
|
end
|
|
177
204
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dsfr-form_builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BetaGouv developers
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionview
|
|
@@ -104,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
104
104
|
- !ruby/object:Gem::Version
|
|
105
105
|
version: '0'
|
|
106
106
|
requirements: []
|
|
107
|
-
rubygems_version: 3.
|
|
107
|
+
rubygems_version: 3.4.1
|
|
108
108
|
signing_key:
|
|
109
109
|
specification_version: 4
|
|
110
110
|
summary: Ruby on Rails form builder pour le Système de Design de l'État (DSFR)
|