formstrap 0.1.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 +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +33 -0
- data/CHANGELOG.md +1 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +28 -0
- data/LICENSE.txt +21 -0
- data/README.md +118 -0
- data/Rakefile +10 -0
- data/app/assets/config/headmin_manifest.js +2 -0
- data/app/assets/images/avatar.jpg +0 -0
- data/app/assets/images/document.docx +0 -0
- data/app/assets/images/document.pdf +0 -0
- data/app/assets/images/image.jpg +0 -0
- data/app/assets/images/spreadsheet.xls +0 -0
- data/app/assets/images/video.mp4 +0 -0
- data/app/assets/javascripts/formstrap/config/i18n.js +11 -0
- data/app/assets/javascripts/formstrap/controllers/autocomplete_controller.js +318 -0
- data/app/assets/javascripts/formstrap/controllers/date_range_controller.js +38 -0
- data/app/assets/javascripts/formstrap/controllers/dropzone_controller.js +31 -0
- data/app/assets/javascripts/formstrap/controllers/file_preview_controller.js +244 -0
- data/app/assets/javascripts/formstrap/controllers/flatpickr_controller.js +35 -0
- data/app/assets/javascripts/formstrap/controllers/infinite_scroller_controller.js +28 -0
- data/app/assets/javascripts/formstrap/controllers/media_controller.js +252 -0
- data/app/assets/javascripts/formstrap/controllers/media_modal_controller.js +147 -0
- data/app/assets/javascripts/formstrap/controllers/redactorx_controller.js +40 -0
- data/app/assets/javascripts/formstrap/controllers/repeater_controller.js +148 -0
- data/app/assets/javascripts/formstrap/controllers/select_controller.js +49 -0
- data/app/assets/javascripts/formstrap/controllers/textarea_controller.js +48 -0
- data/app/assets/javascripts/formstrap/index.js +32 -0
- data/app/assets/javascripts/formstrap.js +11515 -0
- data/app/assets/stylesheets/formstrap/forms/autocomplete.scss +27 -0
- data/app/assets/stylesheets/formstrap/forms/file.scss +83 -0
- data/app/assets/stylesheets/formstrap/forms/media.scss +10 -0
- data/app/assets/stylesheets/formstrap/forms/repeater.scss +62 -0
- data/app/assets/stylesheets/formstrap/forms/search.scss +12 -0
- data/app/assets/stylesheets/formstrap/forms.scss +12 -0
- data/app/assets/stylesheets/formstrap/general.scss +18 -0
- data/app/assets/stylesheets/formstrap/media/index.scss +9 -0
- data/app/assets/stylesheets/formstrap/media.scss +1 -0
- data/app/assets/stylesheets/formstrap/utilities/buttons.scss +27 -0
- data/app/assets/stylesheets/formstrap/utilities/dropzone.scss +72 -0
- data/app/assets/stylesheets/formstrap/utilities.scss +2 -0
- data/app/assets/stylesheets/formstrap/vendor/flatpickr.css +903 -0
- data/app/assets/stylesheets/formstrap/vendor/tom-select-bootstrap.scss +535 -0
- data/app/assets/stylesheets/formstrap.css +1559 -0
- data/app/assets/stylesheets/formstrap.scss +11 -0
- data/app/controllers/concerns/formstrap/pagination.rb +27 -0
- data/app/controllers/formstrap/media_controller.rb +68 -0
- data/app/controllers/formstrap_controller.rb +2 -0
- data/app/models/concerns/formstrap/autocompletable.rb +36 -0
- data/app/models/concerns/formstrap/hintable.rb +22 -0
- data/app/models/concerns/formstrap/input_groupable.rb +21 -0
- data/app/models/concerns/formstrap/labelable.rb +31 -0
- data/app/models/concerns/formstrap/listable.rb +26 -0
- data/app/models/concerns/formstrap/placeholderable.rb +11 -0
- data/app/models/concerns/formstrap/validatable.rb +38 -0
- data/app/models/concerns/formstrap/wrappable.rb +19 -0
- data/app/models/formstrap/.DS_Store +0 -0
- data/app/models/formstrap/association_view.rb +100 -0
- data/app/models/formstrap/blocks_view.rb +43 -0
- data/app/models/formstrap/checkbox_view.rb +50 -0
- data/app/models/formstrap/color_view.rb +45 -0
- data/app/models/formstrap/date_range_view.rb +23 -0
- data/app/models/formstrap/date_view.rb +43 -0
- data/app/models/formstrap/datetime_range_view.rb +23 -0
- data/app/models/formstrap/datetime_view.rb +43 -0
- data/app/models/formstrap/email_view.rb +46 -0
- data/app/models/formstrap/file_view.rb +106 -0
- data/app/models/formstrap/flatpickr_range_view.rb +89 -0
- data/app/models/formstrap/flatpickr_view.rb +27 -0
- data/app/models/formstrap/hidden_view.rb +8 -0
- data/app/models/formstrap/hint_view.rb +4 -0
- data/app/models/formstrap/input_group_view.rb +17 -0
- data/app/models/formstrap/label_view.rb +22 -0
- data/app/models/formstrap/media_item_view.rb +41 -0
- data/app/models/formstrap/media_view.rb +143 -0
- data/app/models/formstrap/number_view.rb +47 -0
- data/app/models/formstrap/password_view.rb +42 -0
- data/app/models/formstrap/redactorx_view.rb +57 -0
- data/app/models/formstrap/search_view.rb +46 -0
- data/app/models/formstrap/select_view.rb +61 -0
- data/app/models/formstrap/switch_view.rb +21 -0
- data/app/models/formstrap/text_view.rb +46 -0
- data/app/models/formstrap/textarea_view.rb +47 -0
- data/app/models/formstrap/url_view.rb +46 -0
- data/app/models/formstrap/wrapper_view.rb +17 -0
- data/app/models/formstrap/wysiwyg_view.rb +15 -0
- data/app/models/view_model.rb +62 -0
- data/app/views/formstrap/_association.html.erb +30 -0
- data/app/views/formstrap/_autocomplete.html.erb +11 -0
- data/app/views/formstrap/_blocks.html.erb +45 -0
- data/app/views/formstrap/_checkbox.html.erb +34 -0
- data/app/views/formstrap/_color.html.erb +32 -0
- data/app/views/formstrap/_datalist.html.erb +3 -0
- data/app/views/formstrap/_date.html.erb +41 -0
- data/app/views/formstrap/_date_range.html.erb +40 -0
- data/app/views/formstrap/_datetime.html.erb +41 -0
- data/app/views/formstrap/_datetime_range.html.erb +40 -0
- data/app/views/formstrap/_email.html.erb +43 -0
- data/app/views/formstrap/_errors.html.erb +19 -0
- data/app/views/formstrap/_file.html.erb +94 -0
- data/app/views/formstrap/_flatpickr.html.erb +33 -0
- data/app/views/formstrap/_flatpickr_range.html.erb +40 -0
- data/app/views/formstrap/_hidden.html.erb +23 -0
- data/app/views/formstrap/_hint.html.erb +21 -0
- data/app/views/formstrap/_input_group.html.erb +21 -0
- data/app/views/formstrap/_label.html.erb +22 -0
- data/app/views/formstrap/_media.html.erb +60 -0
- data/app/views/formstrap/_number.html.erb +41 -0
- data/app/views/formstrap/_password.html.erb +39 -0
- data/app/views/formstrap/_redactorx.html.erb +31 -0
- data/app/views/formstrap/_repeater.html.erb +128 -0
- data/app/views/formstrap/_search.html.erb +43 -0
- data/app/views/formstrap/_select.html.erb +43 -0
- data/app/views/formstrap/_switch.html.erb +29 -0
- data/app/views/formstrap/_text.html.erb +42 -0
- data/app/views/formstrap/_textarea.html.erb +39 -0
- data/app/views/formstrap/_to_ary.html.erb +0 -0
- data/app/views/formstrap/_url.html.erb +43 -0
- data/app/views/formstrap/_validation.html.erb +18 -0
- data/app/views/formstrap/_wrapper.html.erb +8 -0
- data/app/views/formstrap/_wysiwyg.html.erb +28 -0
- data/app/views/formstrap/autocomplete/_item.html.erb +3 -0
- data/app/views/formstrap/autocomplete/_list.html.erb +3 -0
- data/app/views/formstrap/blocks/_modal.html.erb +20 -0
- data/app/views/formstrap/fields/_base.html.erb +25 -0
- data/app/views/formstrap/fields/_file.html.erb +17 -0
- data/app/views/formstrap/fields/_files.html.erb +17 -0
- data/app/views/formstrap/fields/_group.html.erb +52 -0
- data/app/views/formstrap/fields/_list.html.erb +31 -0
- data/app/views/formstrap/fields/_text.html.erb +17 -0
- data/app/views/formstrap/media/_item.html.erb +38 -0
- data/app/views/formstrap/media/_media_item_modal.html.erb +77 -0
- data/app/views/formstrap/media/_modal.html.erb +40 -0
- data/app/views/formstrap/media/_thumbnail.html.erb +20 -0
- data/app/views/formstrap/media/_validation.html.erb +10 -0
- data/app/views/formstrap/media/create.turbo_stream.erb +5 -0
- data/app/views/formstrap/media/index.html.erb +3 -0
- data/app/views/formstrap/media/index.turbo_stream.erb +11 -0
- data/app/views/formstrap/media/show.html.erb +9 -0
- data/app/views/formstrap/media/thumbnail.html.erb +3 -0
- data/app/views/formstrap/media/update.turbo_stream.erb +3 -0
- data/app/views/formstrap/pagination/_infinite.html.erb +7 -0
- data/app/views/formstrap/repeater/_row.html.erb +53 -0
- data/app/views/formstrap/shared/_notifications.html.erb +20 -0
- data/app/views/formstrap/shared/_popup.html.erb +32 -0
- data/app/views/formstrap/shared/_thumbnail.html.erb +35 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/importmap.rb +2 -0
- data/config/locales/activerecord/en.yml +12 -0
- data/config/locales/activerecord/nl.yml +13 -0
- data/config/locales/defaults/en.yml +215 -0
- data/config/locales/defaults/nl.yml +213 -0
- data/config/locales/devise/en.yml +65 -0
- data/config/locales/devise/nl.yml +85 -0
- data/config/locales/en.yml +6 -0
- data/config/locales/formstrap/forms/en.yml +39 -0
- data/config/locales/formstrap/forms/nl.yml +39 -0
- data/config/locales/formstrap/media/en.yml +24 -0
- data/config/locales/formstrap/media/nl.yml +24 -0
- data/config/locales/formstrap/thumbnail/en.yml +4 -0
- data/config/locales/formstrap/thumbnail/nl.yml +4 -0
- data/config/locales/nl.yml +6 -0
- data/config/routes.rb +11 -0
- data/esbuild-css.js +25 -0
- data/esbuild-js.js +11 -0
- data/formstrap.gemspec +37 -0
- data/formstrap.iml +34 -0
- data/lib/formstrap/engine.rb +27 -0
- data/lib/formstrap/form_builder.rb +177 -0
- data/lib/formstrap/form_helper.rb +19 -0
- data/lib/formstrap/version.rb +3 -0
- data/lib/formstrap.rb +6 -0
- data/package.json +54 -0
- data/src/js/formstrap.js +1 -0
- data/src/scss/formstrap.scss +1 -0
- data/yarn.lock +1998 -0
- metadata +224 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class DatetimeView < ViewModel
|
3
|
+
include Formstrap::Hintable
|
4
|
+
include Formstrap::InputGroupable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Listable
|
7
|
+
include Formstrap::Placeholderable
|
8
|
+
include Formstrap::Validatable
|
9
|
+
include Formstrap::Wrappable
|
10
|
+
|
11
|
+
def input_options
|
12
|
+
keys = attributes - %i[append attribute float form input_group input_group label prepend validate wrapper]
|
13
|
+
options = to_h.slice(*keys)
|
14
|
+
default_input_options.deep_merge(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def input_group_options
|
18
|
+
default_input_group_options
|
19
|
+
.deep_merge(label_input_group_options)
|
20
|
+
.deep_merge(@input_group || {})
|
21
|
+
end
|
22
|
+
|
23
|
+
def wrapper_options
|
24
|
+
default_wrapper_options.deep_merge({
|
25
|
+
class: ["mb-3", ("form-floating" if float)]
|
26
|
+
}).deep_merge(@wrapper || {})
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def default_input_options
|
32
|
+
{
|
33
|
+
aria: {describedby: validation_id},
|
34
|
+
class: [form_control_class, validation_class],
|
35
|
+
placeholder: placeholder
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def form_control_class
|
40
|
+
plaintext ? "form-control-plaintext" : "form-control"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class EmailView < ViewModel
|
3
|
+
include Formstrap::Autocompletable
|
4
|
+
include Formstrap::Hintable
|
5
|
+
include Formstrap::InputGroupable
|
6
|
+
include Formstrap::Labelable
|
7
|
+
include Formstrap::Listable
|
8
|
+
include Formstrap::Placeholderable
|
9
|
+
include Formstrap::Validatable
|
10
|
+
include Formstrap::Wrappable
|
11
|
+
|
12
|
+
def input_options
|
13
|
+
keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
|
14
|
+
options = to_h.slice(*keys)
|
15
|
+
options = default_input_options.deep_merge(options)
|
16
|
+
options.deep_merge(autocomplete_input_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def input_group_options
|
20
|
+
default_input_group_options
|
21
|
+
.deep_merge(autocomplete_input_group_options)
|
22
|
+
.deep_merge(label_input_group_options)
|
23
|
+
.deep_merge(@input_group || {})
|
24
|
+
end
|
25
|
+
|
26
|
+
def wrapper_options
|
27
|
+
default_wrapper_options.deep_merge({
|
28
|
+
class: ["mb-3", ("form-floating" if float)]
|
29
|
+
}).deep_merge(@wrapper || {})
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def default_input_options
|
35
|
+
{
|
36
|
+
aria: {describedby: validation_id},
|
37
|
+
class: [form_control_class, validation_class],
|
38
|
+
placeholder: placeholder
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def form_control_class
|
43
|
+
plaintext ? "form-control-plaintext" : "form-control"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class FileView < ViewModel
|
3
|
+
include Formstrap::Hintable
|
4
|
+
include Formstrap::InputGroupable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Placeholderable
|
7
|
+
include Formstrap::Validatable
|
8
|
+
include Formstrap::Wrappable
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = attributes - %i[append attribute dropzone destroy form input_group label prepend preview validate wrapper]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
options = default_input_options.deep_merge(options)
|
14
|
+
options = options.deep_merge(required: false) if attachments.any?
|
15
|
+
options
|
16
|
+
end
|
17
|
+
|
18
|
+
def input_group_options
|
19
|
+
default_input_group_options
|
20
|
+
.deep_merge(label_input_group_options)
|
21
|
+
.deep_merge(@input_group || {})
|
22
|
+
end
|
23
|
+
|
24
|
+
def wrapper_options
|
25
|
+
default_wrapper_options.deep_merge({
|
26
|
+
class: ["mb-3 h-form-file", ("form-floating" if float)],
|
27
|
+
data: {
|
28
|
+
controller: ("file-preview" if preview)
|
29
|
+
}
|
30
|
+
}).deep_merge(@wrapper || {})
|
31
|
+
end
|
32
|
+
|
33
|
+
def preview
|
34
|
+
@preview || dropzone
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
@destroy || false
|
39
|
+
end
|
40
|
+
|
41
|
+
def attached
|
42
|
+
form.object&.send(attribute)
|
43
|
+
end
|
44
|
+
|
45
|
+
def attachments
|
46
|
+
attached&.attachments || []
|
47
|
+
end
|
48
|
+
|
49
|
+
def number_of_files
|
50
|
+
multiple ? 2 : 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def nested_attribute
|
54
|
+
attached.is_a?(ActiveStorage::Attached::Many) ? :"#{attribute}_attachments" : :"#{attribute}_attachment"
|
55
|
+
end
|
56
|
+
|
57
|
+
def dropzone_options
|
58
|
+
if dropzone
|
59
|
+
{
|
60
|
+
class: ["h-dropzone", validation_class],
|
61
|
+
data: {
|
62
|
+
controller: "dropzone"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
else
|
66
|
+
{
|
67
|
+
class: validation_class
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# def input_group_options
|
73
|
+
# {
|
74
|
+
# prepend: prepend,
|
75
|
+
# append: append,
|
76
|
+
# class: "h-form-file",
|
77
|
+
# data: {
|
78
|
+
# controller: "#{"file-preview" if preview} #{"dropzone" if dropzone}"
|
79
|
+
# }
|
80
|
+
# }
|
81
|
+
# end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def default_input_options
|
86
|
+
{
|
87
|
+
aria: {describedby: validation_id},
|
88
|
+
class: ["form-control", validation_class],
|
89
|
+
placeholder: placeholder,
|
90
|
+
data: preview_data
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def preview_data
|
95
|
+
if preview
|
96
|
+
{
|
97
|
+
"file-preview-target": "input",
|
98
|
+
"dropzone-target": "input",
|
99
|
+
action: "change->file-preview#preview dropEnd->file-preview#preview"
|
100
|
+
}
|
101
|
+
else
|
102
|
+
{}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class FlatpickrRangeView < ViewModel
|
3
|
+
include Formstrap::Hintable
|
4
|
+
include Formstrap::InputGroupable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Listable
|
7
|
+
include Formstrap::Placeholderable
|
8
|
+
include Formstrap::Validatable
|
9
|
+
include Formstrap::Wrappable
|
10
|
+
|
11
|
+
def attribute
|
12
|
+
@attribute || :period
|
13
|
+
end
|
14
|
+
|
15
|
+
def start_attribute
|
16
|
+
@start.dig(:attribute) || :start_date
|
17
|
+
end
|
18
|
+
|
19
|
+
def end_attribute
|
20
|
+
@end.dig(:attribute) || :end_date
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_options
|
24
|
+
default_start_options.deep_merge(@start || {})
|
25
|
+
end
|
26
|
+
|
27
|
+
def end_options
|
28
|
+
default_end_options.deep_merge(@end || {})
|
29
|
+
end
|
30
|
+
|
31
|
+
def input_options
|
32
|
+
keys = attributes - %i[append attribute end float form input_group label prepend start validate wrapper]
|
33
|
+
options = to_h.slice(*keys)
|
34
|
+
default_input_options.deep_merge(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def input_group_options
|
38
|
+
default_input_group_options
|
39
|
+
.deep_merge(label_input_group_options)
|
40
|
+
.deep_merge(@input_group || {})
|
41
|
+
end
|
42
|
+
|
43
|
+
def wrapper_options
|
44
|
+
default_wrapper_options.deep_merge({
|
45
|
+
class: ["mb-3", ("form-floating" if float)]
|
46
|
+
}).deep_merge(@wrapper || {})
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def default_options
|
52
|
+
{
|
53
|
+
name: nil
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_start_options
|
58
|
+
{}
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_end_options
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_input_options
|
66
|
+
{
|
67
|
+
aria: {describedby: validation_id},
|
68
|
+
class: [form_control_class, validation_class],
|
69
|
+
placeholder: placeholder,
|
70
|
+
name: nil,
|
71
|
+
data: {
|
72
|
+
controller: "flatpickr date-range",
|
73
|
+
action: "change->date-range#update",
|
74
|
+
flatpickr: {
|
75
|
+
mode: "range",
|
76
|
+
defaultDate: [
|
77
|
+
form.object&.send(start_attribute)&.strftime("%d/%m/%Y"),
|
78
|
+
form.object&.send(end_attribute)&.strftime("%d/%m/%Y")
|
79
|
+
]
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def form_control_class
|
86
|
+
plaintext ? "form-control-plaintext" : "form-control"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class FlatpickrView < ViewModel
|
3
|
+
def options
|
4
|
+
keys = attributes - %i[data]
|
5
|
+
options = to_h.slice(*keys)
|
6
|
+
default_options.deep_merge(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_options
|
12
|
+
{
|
13
|
+
data: default_data.deep_merge(data || {})
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_data
|
18
|
+
{
|
19
|
+
controller: "flatpickr",
|
20
|
+
|
21
|
+
flatpickr: {
|
22
|
+
defaultDate: attribute.nil? ? Date.today : form.object&.send(attribute)&.strftime("%d/%m/%Y")
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class InputGroupView < ViewModel
|
3
|
+
def options
|
4
|
+
keys = attributes - %i[bypass append prepend]
|
5
|
+
options = to_h.slice(*keys)
|
6
|
+
default_options.deep_merge(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_options
|
12
|
+
{
|
13
|
+
class: ["input-group"]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class LabelView < ViewModel
|
3
|
+
def form
|
4
|
+
@form.object_id
|
5
|
+
end
|
6
|
+
|
7
|
+
def options
|
8
|
+
keys = attributes - %i[attribute form text]
|
9
|
+
options = to_h.slice(*keys)
|
10
|
+
default_options.deep_merge(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def default_options
|
16
|
+
{
|
17
|
+
class: "form-label",
|
18
|
+
required: required
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class MediaItemView < ViewModel
|
3
|
+
include Rails.application.routes.url_helpers
|
4
|
+
|
5
|
+
def thumbnail_options
|
6
|
+
options = {
|
7
|
+
file: attachment
|
8
|
+
}
|
9
|
+
|
10
|
+
# Don't pass width or height if it was not defined
|
11
|
+
options = options.merge(width: width) if is_defined?(:width)
|
12
|
+
options = options.merge(height: height) if is_defined?(:height)
|
13
|
+
|
14
|
+
options
|
15
|
+
end
|
16
|
+
|
17
|
+
def attachment
|
18
|
+
form.object
|
19
|
+
end
|
20
|
+
|
21
|
+
def position_value
|
22
|
+
attachment.new_record? ? nil : attachment.position
|
23
|
+
end
|
24
|
+
|
25
|
+
def id
|
26
|
+
attachment.blob ? attachment.blob.id : "$1"
|
27
|
+
end
|
28
|
+
|
29
|
+
def filename
|
30
|
+
attachment.blob&.filename&.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def content_type
|
34
|
+
attachment.blob&.content_type
|
35
|
+
end
|
36
|
+
|
37
|
+
def size
|
38
|
+
number_to_human_size(attachment.blob&.byte_size || 0)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class MediaView < ViewModel
|
3
|
+
include Rails.application.routes.url_helpers
|
4
|
+
include Formstrap::Hintable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Placeholderable
|
7
|
+
include Formstrap::Validatable
|
8
|
+
include Formstrap::Wrappable
|
9
|
+
|
10
|
+
def input_group_options
|
11
|
+
default_input_group_options
|
12
|
+
.deep_merge(label_input_group_options)
|
13
|
+
.deep_merge(@input_group || {})
|
14
|
+
end
|
15
|
+
|
16
|
+
def wrapper_options
|
17
|
+
default_wrapper_options.deep_merge({
|
18
|
+
class: ["mb-3", ("form-floating" if float)],
|
19
|
+
data: {
|
20
|
+
controller: "media",
|
21
|
+
name: name,
|
22
|
+
min: min,
|
23
|
+
max: max,
|
24
|
+
sort: sort,
|
25
|
+
accept: accept,
|
26
|
+
required: required.nil? ? 0 : required
|
27
|
+
}
|
28
|
+
}).deep_merge(@wrapper || {})
|
29
|
+
end
|
30
|
+
|
31
|
+
def item_options
|
32
|
+
options = {
|
33
|
+
sort: sort
|
34
|
+
}
|
35
|
+
|
36
|
+
# Don't pass width or height if it was not defined
|
37
|
+
options = options.merge(width: width) if is_defined?(:width)
|
38
|
+
options = options.merge(height: height) if is_defined?(:height)
|
39
|
+
|
40
|
+
options
|
41
|
+
end
|
42
|
+
|
43
|
+
def custom_validation_options
|
44
|
+
{
|
45
|
+
form: form,
|
46
|
+
attribute: attribute,
|
47
|
+
min: min,
|
48
|
+
max: max,
|
49
|
+
accept: accept
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def thumbnail_options
|
54
|
+
options = {
|
55
|
+
icon: "plus"
|
56
|
+
}
|
57
|
+
|
58
|
+
# Don't pass width or height if it was not defined
|
59
|
+
options = options.merge(width: width) unless is_defined?(:width)
|
60
|
+
options = options.merge(height: height) unless is_defined?(:height)
|
61
|
+
|
62
|
+
options
|
63
|
+
end
|
64
|
+
|
65
|
+
def association_object
|
66
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
67
|
+
result = form.object.send(nested_attribute)
|
68
|
+
|
69
|
+
# We sort the collection with ruby to prevent a new query to be made that would dispose of the objects in memory
|
70
|
+
result = result.sort_by { |item| item.position } if sort
|
71
|
+
result
|
72
|
+
else
|
73
|
+
form.object.send(nested_attribute)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def attachments
|
78
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
79
|
+
result = form.object.send(nested_attribute)
|
80
|
+
|
81
|
+
# We sort the collection with ruby to prevent a new query to be made that would dispose of the objects in memory
|
82
|
+
result = result.sort_by { |item| item.position } if sort
|
83
|
+
result.to_a.compact
|
84
|
+
else
|
85
|
+
[form.object.send(nested_attribute)].compact
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def attached
|
90
|
+
form.object.send(attribute)
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_nested_attribute
|
94
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
95
|
+
form.object.send(nested_attribute).build
|
96
|
+
else
|
97
|
+
form.object.send("build_#{nested_attribute}")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def nested_attribute
|
102
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
103
|
+
:"#{attribute}_attachments"
|
104
|
+
else
|
105
|
+
:"#{attribute}_attachment"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def min
|
110
|
+
if @required
|
111
|
+
(@min.to_i < 1) ? 1 : @min.to_i
|
112
|
+
else
|
113
|
+
(@min.to_i < 1) ? 0 : @min.to_i
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def max
|
118
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
119
|
+
@max
|
120
|
+
else
|
121
|
+
1
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
attr_reader :accept
|
126
|
+
|
127
|
+
def required
|
128
|
+
@required ? 1 : nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def blob_ids
|
132
|
+
attachments.map { |attachment| attachment.blob_id }
|
133
|
+
end
|
134
|
+
|
135
|
+
def name
|
136
|
+
"#{attribute}_#{object_id}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def sort
|
140
|
+
@sort == true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class NumberView < ViewModel
|
3
|
+
include Formstrap::Hintable
|
4
|
+
include Formstrap::InputGroupable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Listable
|
7
|
+
include Formstrap::Placeholderable
|
8
|
+
include Formstrap::Validatable
|
9
|
+
include Formstrap::Wrappable
|
10
|
+
|
11
|
+
def input_options
|
12
|
+
keys = attributes - %i[append attribute float form input_group label prepend validate wrapper]
|
13
|
+
options = to_h.slice(*keys)
|
14
|
+
default_input_options.deep_merge(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def input_group_options
|
18
|
+
default_input_group_options
|
19
|
+
.deep_merge(label_input_group_options)
|
20
|
+
.deep_merge(@input_group || {})
|
21
|
+
end
|
22
|
+
|
23
|
+
def wrapper_options
|
24
|
+
default_wrapper_options.deep_merge({
|
25
|
+
class: ["mb-3", float_class]
|
26
|
+
}).deep_merge(@wrapper || {})
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def float_class
|
32
|
+
"form-floating" if float
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_input_options
|
36
|
+
{
|
37
|
+
aria: {describedby: validation_id},
|
38
|
+
class: [form_control_class, validation_class],
|
39
|
+
placeholder: placeholder
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def form_control_class
|
44
|
+
plaintext ? "form-control-plaintext" : "form-control"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class PasswordView < ViewModel
|
3
|
+
include Formstrap::Hintable
|
4
|
+
include Formstrap::InputGroupable
|
5
|
+
include Formstrap::Labelable
|
6
|
+
include Formstrap::Placeholderable
|
7
|
+
include Formstrap::Validatable
|
8
|
+
include Formstrap::Wrappable
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = attributes - %i[append attribute float form input_group label prepend validate wrapper]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.deep_merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def input_group_options
|
17
|
+
default_input_group_options
|
18
|
+
.deep_merge(label_input_group_options)
|
19
|
+
.deep_merge(@input_group || {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def wrapper_options
|
23
|
+
default_wrapper_options.deep_merge({
|
24
|
+
class: ["mb-3", ("form-floating" if float)]
|
25
|
+
}).deep_merge(@wrapper || {})
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def default_input_options
|
31
|
+
{
|
32
|
+
aria: {describedby: validation_id},
|
33
|
+
class: [form_control_class, validation_class],
|
34
|
+
placeholder: placeholder
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def form_control_class
|
39
|
+
plaintext ? "form-control-plaintext" : "form-control"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Formstrap
|
2
|
+
class RedactorxView < ViewModel
|
3
|
+
def options
|
4
|
+
default_options.deep_merge(to_h)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def default_options
|
10
|
+
{
|
11
|
+
data: {
|
12
|
+
controller: "redactorx",
|
13
|
+
"redactor-options": redactor_options
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def control
|
19
|
+
@control || (hybrid ? true : nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
def context
|
23
|
+
@context || (hybrid ? true : nil)
|
24
|
+
end
|
25
|
+
|
26
|
+
def toolbar
|
27
|
+
@toolbar || (hybrid ? false : nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
def addbar
|
31
|
+
@addbar || %w[paragraph image embed table quote pre line]
|
32
|
+
end
|
33
|
+
|
34
|
+
def plugins
|
35
|
+
@plugins || %w[shortcut]
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :topbar
|
39
|
+
|
40
|
+
def redactor_options
|
41
|
+
default_redactor_options.deep_merge(redactor || {})
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_redactor_options
|
45
|
+
{
|
46
|
+
control: control,
|
47
|
+
context: context,
|
48
|
+
toolbar: toolbar,
|
49
|
+
buttons: {
|
50
|
+
addbar: addbar,
|
51
|
+
plugins: plugins,
|
52
|
+
topbar: topbar
|
53
|
+
}
|
54
|
+
}.delete_if { |k, v| v.nil? }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|