dry_crud 7.1.0 → 8.0.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 +4 -4
- data/VERSION +1 -1
- data/app/controllers/crud_controller.rb +5 -7
- data/app/controllers/dry_crud/generic_model.rb +4 -8
- data/app/controllers/dry_crud/nestable.rb +1 -4
- data/app/controllers/dry_crud/rememberable.rb +1 -4
- data/app/controllers/dry_crud/render_callbacks.rb +2 -10
- data/app/controllers/dry_crud/searchable.rb +3 -10
- data/app/controllers/dry_crud/sortable.rb +3 -10
- data/app/controllers/list_controller.rb +0 -2
- data/app/helpers/actions_helper.rb +8 -10
- data/app/helpers/dry_crud/form/builder.rb +23 -26
- data/app/helpers/dry_crud/form/control.rb +7 -11
- data/app/helpers/dry_crud/table/actions.rb +8 -13
- data/app/helpers/dry_crud/table/builder.rb +3 -6
- data/app/helpers/dry_crud/table/col.rb +1 -4
- data/app/helpers/dry_crud/table/sorting.rb +3 -6
- data/app/helpers/form_helper.rb +5 -7
- data/app/helpers/format_helper.rb +11 -13
- data/app/helpers/i18n_helper.rb +8 -10
- data/app/helpers/table_helper.rb +2 -4
- data/app/helpers/utility_helper.rb +9 -11
- data/app/views/layouts/application.html.erb +1 -1
- data/app/views/layouts/application.html.haml +1 -1
- data/lib/dry_crud/engine.rb +1 -3
- data/lib/dry_crud.rb +1 -1
- data/lib/generators/dry_crud/dry_crud_generator.rb +17 -17
- data/lib/generators/dry_crud/dry_crud_generator_base.rb +8 -8
- data/lib/generators/dry_crud/file_generator.rb +6 -6
- data/lib/generators/dry_crud/templates/config/initializers/field_error_proc.rb +1 -1
- data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +119 -119
- data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/form/builder_spec.rb +54 -59
- data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/table/builder_spec.rb +23 -25
- data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +10 -13
- data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +88 -92
- data/lib/generators/dry_crud/templates/spec/helpers/i18n_helper_spec.rb +33 -34
- data/lib/generators/dry_crud/templates/spec/helpers/table_helper_spec.rb +57 -59
- data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +18 -21
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +62 -62
- data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +8 -10
- data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +63 -65
- data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +20 -22
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +74 -74
- data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +21 -21
- data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +13 -15
- data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +68 -70
- data/lib/generators/dry_crud/templates/test/helpers/i18n_helper_test.rb +26 -28
- data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +25 -27
- data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +15 -17
- data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +13 -15
- data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +9 -13
- data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +7 -11
- data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +13 -15
- data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +2 -4
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 728d9df7af506d9680cf74d6b7031db221a645816ef03307f1f9a8abca8bd40b
|
4
|
+
data.tar.gz: 748c707433dd4dfea6069f482276e48f45124ba3e26d1ba956d78ab3fc629702
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 692538e533f409bee57aa7ebc5ac99d040d3fabd2e376ecd4edf4057f1f8732011f4753178af4abffe36973baa2dad81c9afa5edc55047bf6c93eb68aef2b80b
|
7
|
+
data.tar.gz: 247d2b34b35ec952f334635a50e5bba85733f0ffef5abbc2efcafa5b5a581aca44f188946eab0bdef662734554e87ae268638a1674720df773599135fd4ee9b9
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
8.0.0
|
@@ -8,7 +8,6 @@
|
|
8
8
|
# With the help of additional callbacks, it is possible to hook into the
|
9
9
|
# action procedures without overriding the entire method.
|
10
10
|
class CrudController < ListController
|
11
|
-
|
12
11
|
class_attribute :permitted_attrs
|
13
12
|
|
14
13
|
# Defines before and after callback hooks for create, update, save and
|
@@ -139,7 +138,7 @@ class CrudController < ListController
|
|
139
138
|
|
140
139
|
# The form params for this model.
|
141
140
|
def model_params
|
142
|
-
params.
|
141
|
+
params.expect(model_identifier => permitted_attrs)
|
143
142
|
end
|
144
143
|
|
145
144
|
# Path of the index page to return to.
|
@@ -186,7 +185,7 @@ class CrudController < ListController
|
|
186
185
|
# Perform a redirect after a failed operation and set a flash alert.
|
187
186
|
def redirect_on_failure(**options)
|
188
187
|
location = options[:location] ||
|
189
|
-
request.env[
|
188
|
+
request.env["HTTP_REFERER"].presence ||
|
190
189
|
index_path
|
191
190
|
flash[:alert] ||= error_messages.presence || flash_message(:failure)
|
192
191
|
redirect_to location
|
@@ -211,10 +210,10 @@ class CrudController < ListController
|
|
211
210
|
# or crud.{action_name}.flash.{state} as fallback.
|
212
211
|
def flash_message(state)
|
213
212
|
scope = "#{action_name}.flash.#{state}"
|
214
|
-
keys = [:"#{controller_name}.#{scope}_html",
|
213
|
+
keys = [ :"#{controller_name}.#{scope}_html",
|
215
214
|
:"#{controller_name}.#{scope}",
|
216
215
|
:"crud.#{scope}_html",
|
217
|
-
:"crud.#{scope}"]
|
216
|
+
:"crud.#{scope}" ]
|
218
217
|
I18n.t(keys.shift, model: full_entry_label, default: keys)
|
219
218
|
end
|
220
219
|
|
@@ -229,7 +228,7 @@ class CrudController < ListController
|
|
229
228
|
def error_messages
|
230
229
|
# rubocop:disable Rails/OutputSafety
|
231
230
|
escaped = entry.errors.full_messages.map { |m| ERB::Util.html_escape(m) }
|
232
|
-
escaped.join(
|
231
|
+
escaped.join("<br/>").html_safe
|
233
232
|
# rubocop:enable Rails/OutputSafety
|
234
233
|
end
|
235
234
|
|
@@ -242,5 +241,4 @@ class CrudController < ListController
|
|
242
241
|
before_render_edit(*methods)
|
243
242
|
end
|
244
243
|
end
|
245
|
-
|
246
244
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# Connects the including controller to the model whose name corrsponds to
|
4
3
|
# the controller's name.
|
5
4
|
#
|
@@ -7,13 +6,12 @@ module DryCrud
|
|
7
6
|
# Additional helper methods store and retrieve values in instance variables
|
8
7
|
# named after their class.
|
9
8
|
module GenericModel
|
10
|
-
|
11
9
|
extend ActiveSupport::Concern
|
12
10
|
|
13
11
|
included do
|
14
12
|
helper_method :model_class, :models_label, :path_args
|
15
13
|
|
16
|
-
delegate :model_class, :models_label, :model_identifier, to:
|
14
|
+
delegate :model_class, :models_label, :model_identifier, to: "self.class"
|
17
15
|
end
|
18
16
|
|
19
17
|
# The scope where model entries will be listed and created.
|
@@ -43,11 +41,11 @@ module DryCrud
|
|
43
41
|
def model_ivar_set(value)
|
44
42
|
name = if value.respond_to?(:klass) # ActiveRecord::Relation
|
45
43
|
ivar_name(value.klass).pluralize
|
46
|
-
|
44
|
+
elsif value.respond_to?(:each) # Array
|
47
45
|
ivar_name(value.first.class).pluralize
|
48
|
-
|
46
|
+
else
|
49
47
|
ivar_name(value.class)
|
50
|
-
|
48
|
+
end
|
51
49
|
instance_variable_set(:"@#{name}", value)
|
52
50
|
end
|
53
51
|
|
@@ -57,7 +55,6 @@ module DryCrud
|
|
57
55
|
|
58
56
|
# Class methods from GenericModel.
|
59
57
|
module ClassMethods
|
60
|
-
|
61
58
|
# The ActiveRecord class of the model.
|
62
59
|
def model_class
|
63
60
|
@model_class ||= controller_name.classify.constantize
|
@@ -77,7 +74,6 @@ module DryCrud
|
|
77
74
|
|
78
75
|
model_class.model_name.human(opts)
|
79
76
|
end
|
80
|
-
|
81
77
|
end
|
82
78
|
end
|
83
79
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# Provides functionality to nest controllers/resources.
|
4
3
|
# If a controller is nested, the parent classes and namespaces
|
5
4
|
# may be defined as an array in the +nesting+ class attribute.
|
@@ -8,7 +7,6 @@ module DryCrud
|
|
8
7
|
# namespace, may define this attribute as follows:
|
9
8
|
# self.nesting = :admin, Country
|
10
9
|
module Nestable
|
11
|
-
|
12
10
|
# Adds the :nesting class attribute and parent helper methods
|
13
11
|
# to the including controller.
|
14
12
|
def self.prepended(klass)
|
@@ -45,7 +43,7 @@ module DryCrud
|
|
45
43
|
|
46
44
|
# An array of objects used in url_for and related functions.
|
47
45
|
def path_args(last)
|
48
|
-
parents + [last]
|
46
|
+
parents + [ last ]
|
49
47
|
end
|
50
48
|
|
51
49
|
# Uses the parent entry (if any) to constrain the model scope.
|
@@ -61,6 +59,5 @@ module DryCrud
|
|
61
59
|
def parent_scope
|
62
60
|
parent.send(model_class.name.underscore.pluralize)
|
63
61
|
end
|
64
|
-
|
65
62
|
end
|
66
63
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# Remembers certain params of the index action in order to return
|
4
3
|
# to the same list after an entry was viewed or edited.
|
5
4
|
# If the index is called with a param :returning, the remembered params
|
@@ -11,14 +10,13 @@ module DryCrud
|
|
11
10
|
# The params are stored separately for each different +remember_key+, which
|
12
11
|
# defaults to the current request's path.
|
13
12
|
module Rememberable
|
14
|
-
|
15
13
|
extend ActiveSupport::Concern
|
16
14
|
|
17
15
|
included do
|
18
16
|
class_attribute :remember_params
|
19
17
|
self.remember_params = %w[q sort sort_dir page]
|
20
18
|
|
21
|
-
before_action :handle_remember_params, only: [:index]
|
19
|
+
before_action :handle_remember_params, only: [ :index ]
|
22
20
|
end
|
23
21
|
|
24
22
|
private
|
@@ -61,6 +59,5 @@ module DryCrud
|
|
61
59
|
def remember_key
|
62
60
|
request.path
|
63
61
|
end
|
64
|
-
|
65
62
|
end
|
66
63
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# Provide +before_render+ callbacks.
|
4
3
|
module RenderCallbacks
|
5
|
-
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
|
8
6
|
included do
|
@@ -12,16 +10,14 @@ module DryCrud
|
|
12
10
|
|
13
11
|
# Prepended methods for callbacks.
|
14
12
|
module Prepends
|
15
|
-
|
16
13
|
# Helper method to run +before_render+ callbacks and render the action.
|
17
14
|
# If a callback renders or redirects, the action is not rendered.
|
18
15
|
def render(...)
|
19
16
|
options = _normalize_render(...)
|
20
|
-
callback = "render_#{options[:template]}"
|
21
|
-
|
17
|
+
callback = "render_#{options[:template] || options[:action] || action_name}"
|
22
18
|
run_callbacks(callback) if respond_to?(:"_#{callback}_callbacks", true)
|
23
19
|
|
24
|
-
super
|
20
|
+
super unless performed?
|
25
21
|
end
|
26
22
|
|
27
23
|
private
|
@@ -33,12 +29,10 @@ module DryCrud
|
|
33
29
|
-> { run_callbacks(e, &a) }
|
34
30
|
end.call
|
35
31
|
end
|
36
|
-
|
37
32
|
end
|
38
33
|
|
39
34
|
# Class methods for callbacks.
|
40
35
|
module ClassMethods
|
41
|
-
|
42
36
|
# Defines before callbacks for the render actions.
|
43
37
|
def define_render_callbacks(*actions)
|
44
38
|
args = actions.map { |a| :"render_#{a}" }
|
@@ -58,8 +52,6 @@ module DryCrud
|
|
58
52
|
terminate
|
59
53
|
end
|
60
54
|
end
|
61
|
-
|
62
55
|
end
|
63
|
-
|
64
56
|
end
|
65
57
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# The search functionality for the index table.
|
4
3
|
# Define an array of searchable string columns in your subclassing
|
5
4
|
# controllers using the class attribute +search_columns+.
|
6
5
|
module Searchable
|
7
|
-
|
8
6
|
extend ActiveSupport::Concern
|
9
7
|
|
10
8
|
included do
|
@@ -18,7 +16,6 @@ module DryCrud
|
|
18
16
|
|
19
17
|
# Prepended methods for searching.
|
20
18
|
module Prepends
|
21
|
-
|
22
19
|
private
|
23
20
|
|
24
21
|
# Enhance the list entries with an optional search criteria
|
@@ -61,24 +58,20 @@ module DryCrud
|
|
61
58
|
def search_support?
|
62
59
|
search_columns.present?
|
63
60
|
end
|
64
|
-
|
65
61
|
end
|
66
62
|
|
67
63
|
# Class methods for Searchable.
|
68
64
|
module ClassMethods
|
69
|
-
|
70
65
|
# All search columns divided in table and field names.
|
71
66
|
def search_tables_and_fields
|
72
67
|
@search_tables_and_fields ||= search_columns.map do |f|
|
73
|
-
if f.to_s.include?(
|
74
|
-
f.split(
|
68
|
+
if f.to_s.include?(".")
|
69
|
+
f.split(".", 2)
|
75
70
|
else
|
76
|
-
[model_class.table_name, f]
|
71
|
+
[ model_class.table_name, f ]
|
77
72
|
end
|
78
73
|
end
|
79
74
|
end
|
80
|
-
|
81
75
|
end
|
82
|
-
|
83
76
|
end
|
84
77
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module DryCrud
|
2
|
-
|
3
2
|
# Sort functionality for the index table.
|
4
3
|
# Define a default sort expression that is always appended to the
|
5
4
|
# current sort params with the class attribute +default_sort+.
|
6
5
|
module Sortable
|
7
|
-
|
8
6
|
extend ActiveSupport::Concern
|
9
7
|
|
10
8
|
included do
|
@@ -20,7 +18,6 @@ module DryCrud
|
|
20
18
|
|
21
19
|
# Class methods for sorting.
|
22
20
|
module ClassMethods
|
23
|
-
|
24
21
|
# Define a map of (virtual) attributes to SQL order expressions.
|
25
22
|
# May be used for sorting table columns that do not appear directly
|
26
23
|
# in the database table. E.g., map city_id: 'cities.name' to
|
@@ -29,20 +26,18 @@ module DryCrud
|
|
29
26
|
self.sort_mappings_with_indifferent_access =
|
30
27
|
hash.with_indifferent_access
|
31
28
|
end
|
32
|
-
|
33
29
|
end
|
34
30
|
|
35
31
|
# Prepended methods for sorting.
|
36
32
|
module Prepends
|
37
|
-
|
38
33
|
private
|
39
34
|
|
40
35
|
# Enhance the list entries with an optional sort order.
|
41
36
|
def list_entries
|
42
37
|
sortable = sortable?(params[:sort])
|
43
38
|
if sortable || default_sort
|
44
|
-
clause = [sortable ? sort_expression : nil, default_sort]
|
45
|
-
super.reorder(Arel.sql(clause.compact.join(
|
39
|
+
clause = [ sortable ? sort_expression : nil, default_sort ]
|
40
|
+
super.reorder(Arel.sql(clause.compact.join(", ")))
|
46
41
|
else
|
47
42
|
super
|
48
43
|
end
|
@@ -57,7 +52,7 @@ module DryCrud
|
|
57
52
|
|
58
53
|
# The sort direction, either 'asc' or 'desc'.
|
59
54
|
def sort_dir
|
60
|
-
params[:sort_dir] ==
|
55
|
+
params[:sort_dir] == "desc" ? "DESC" : "ASC"
|
61
56
|
end
|
62
57
|
|
63
58
|
# Returns true if the passed attribute is sortable.
|
@@ -66,8 +61,6 @@ module DryCrud
|
|
66
61
|
model_class.column_names.include?(attr.to_s) ||
|
67
62
|
sort_mappings_with_indifferent_access.include?(attr))
|
68
63
|
end
|
69
|
-
|
70
64
|
end
|
71
|
-
|
72
65
|
end
|
73
66
|
end
|
@@ -7,7 +7,6 @@
|
|
7
7
|
# Furthermore, it remembers the last search and sort parameters after the
|
8
8
|
# user returns from a displayed or edited entry.
|
9
9
|
class ListController < ApplicationController
|
10
|
-
|
11
10
|
include DryCrud::GenericModel
|
12
11
|
prepend DryCrud::Nestable
|
13
12
|
include DryCrud::RenderCallbacks
|
@@ -48,5 +47,4 @@ class ListController < ApplicationController
|
|
48
47
|
# Include these modules after the #list_entries method is defined.
|
49
48
|
include DryCrud::Searchable
|
50
49
|
include DryCrud::Sortable
|
51
|
-
|
52
50
|
end
|
@@ -3,19 +3,18 @@
|
|
3
3
|
# of action links, change the method #action_link, e.g. to generate a button.
|
4
4
|
# The common crud actions show, edit, destroy, index and add are provided here.
|
5
5
|
module ActionsHelper
|
6
|
-
|
7
6
|
# A generic helper method to create action links.
|
8
7
|
# These link could be styled to look like buttons, for example.
|
9
8
|
def action_link(label, icon = nil, url = {}, html_options = {})
|
10
|
-
add_css_class html_options,
|
9
|
+
add_css_class html_options, "action btn btn-light"
|
11
10
|
link_to(icon ? action_icon(icon, label) : label,
|
12
11
|
url, html_options)
|
13
12
|
end
|
14
13
|
|
15
14
|
# Outputs an icon for an action with an optional label.
|
16
15
|
def action_icon(icon, label = nil)
|
17
|
-
html = tag.i(
|
18
|
-
html <<
|
16
|
+
html = tag.i("", class: "bi-#{icon}")
|
17
|
+
html << " " << label if label
|
19
18
|
html
|
20
19
|
end
|
21
20
|
|
@@ -23,7 +22,7 @@ module ActionsHelper
|
|
23
22
|
# Uses the current +entry+ if no path is given.
|
24
23
|
def show_action_link(path = nil)
|
25
24
|
path ||= path_args(entry)
|
26
|
-
action_link(ti(
|
25
|
+
action_link(ti("link.show"), "zoom-in", path)
|
27
26
|
end
|
28
27
|
|
29
28
|
# Standard edit action to given path.
|
@@ -31,14 +30,14 @@ module ActionsHelper
|
|
31
30
|
def edit_action_link(path = nil)
|
32
31
|
path ||= path_args(entry)
|
33
32
|
path = edit_polymorphic_path(path) unless path.is_a?(String)
|
34
|
-
action_link(ti(
|
33
|
+
action_link(ti("link.edit"), "pencil", path)
|
35
34
|
end
|
36
35
|
|
37
36
|
# Standard destroy action to the given path.
|
38
37
|
# Uses the current +entry+ if no path is given.
|
39
38
|
def destroy_action_link(path = nil)
|
40
39
|
path ||= path_args(entry)
|
41
|
-
action_link(ti(
|
40
|
+
action_link(ti("link.delete"), "trash", path,
|
42
41
|
data: { 'turbo-confirm': ti(:confirm_delete),
|
43
42
|
'turbo-method': :delete })
|
44
43
|
end
|
@@ -48,7 +47,7 @@ module ActionsHelper
|
|
48
47
|
def index_action_link(path = nil, url_options = { returning: true })
|
49
48
|
path ||= path_args(model_class)
|
50
49
|
path = polymorphic_path(path, url_options) unless path.is_a?(String)
|
51
|
-
action_link(ti(
|
50
|
+
action_link(ti("link.list"), "list", path)
|
52
51
|
end
|
53
52
|
|
54
53
|
# Standard add action to given path.
|
@@ -56,7 +55,6 @@ module ActionsHelper
|
|
56
55
|
def add_action_link(path = nil, url_options = {})
|
57
56
|
path ||= path_args(model_class)
|
58
57
|
path = new_polymorphic_path(path, url_options) unless path.is_a?(String)
|
59
|
-
action_link(ti(
|
58
|
+
action_link(ti("link.add"), "plus", path)
|
60
59
|
end
|
61
|
-
|
62
60
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module DryCrud
|
2
2
|
module Form
|
3
|
-
|
4
3
|
# A form builder that automatically selects the corresponding input field
|
5
4
|
# for ActiveRecord column types. Convenience methods for each column type
|
6
5
|
# allow one to customize the different fields.
|
@@ -14,7 +13,6 @@ module DryCrud
|
|
14
13
|
# See the Control class for how to customize the html rendered for a
|
15
14
|
# single input field.
|
16
15
|
class Builder < ActionView::Helpers::FormBuilder
|
17
|
-
|
18
16
|
class_attribute :control_class
|
19
17
|
self.control_class = Control
|
20
18
|
|
@@ -70,10 +68,10 @@ module DryCrud
|
|
70
68
|
|
71
69
|
# Render a boolean field.
|
72
70
|
def boolean_field(attr, **html_options)
|
73
|
-
tag.div(class:
|
71
|
+
tag.div(class: "checkbox") do
|
74
72
|
tag.label do
|
75
|
-
detail = html_options.delete(:detail) ||
|
76
|
-
safe_join([check_box(attr, html_options),
|
73
|
+
detail = html_options.delete(:detail) || " ".html_safe
|
74
|
+
safe_join([ check_box(attr, html_options), " ", detail ])
|
77
75
|
end
|
78
76
|
end
|
79
77
|
end
|
@@ -82,7 +80,7 @@ module DryCrud
|
|
82
80
|
%w[text_field password_field email_field
|
83
81
|
number_field date_field time_field datetime_field].each do |method|
|
84
82
|
define_method(method) do |attr, **html_options|
|
85
|
-
add_css_class(html_options,
|
83
|
+
add_css_class(html_options, "form-control")
|
86
84
|
super(attr, html_options)
|
87
85
|
end
|
88
86
|
end
|
@@ -93,7 +91,7 @@ module DryCrud
|
|
93
91
|
end
|
94
92
|
|
95
93
|
def float_field(attr, **html_options)
|
96
|
-
html_options[:step] ||=
|
94
|
+
html_options[:step] ||= "any"
|
97
95
|
number_field(attr, **html_options)
|
98
96
|
end
|
99
97
|
|
@@ -105,9 +103,9 @@ module DryCrud
|
|
105
103
|
|
106
104
|
# Customize the standard text area to have 5 rows by default.
|
107
105
|
def text_area(attr, **html_options)
|
108
|
-
add_css_class(html_options,
|
106
|
+
add_css_class(html_options, "form-control")
|
109
107
|
html_options[:rows] ||= 5
|
110
|
-
super
|
108
|
+
super
|
111
109
|
end
|
112
110
|
|
113
111
|
# Render a select element for a :belongs_to association defined by attr.
|
@@ -118,7 +116,7 @@ module DryCrud
|
|
118
116
|
def belongs_to_field(attr, **html_options)
|
119
117
|
list = association_entries(attr, **html_options).to_a
|
120
118
|
if list.present?
|
121
|
-
add_css_class(html_options,
|
119
|
+
add_css_class(html_options, "form-control")
|
122
120
|
collection_select(attr, list, :id, :to_s,
|
123
121
|
select_options(attr, **html_options),
|
124
122
|
**html_options)
|
@@ -140,7 +138,7 @@ module DryCrud
|
|
140
138
|
# association.
|
141
139
|
def has_many_field(attr, **html_options)
|
142
140
|
html_options[:multiple] = true
|
143
|
-
add_css_class(html_options,
|
141
|
+
add_css_class(html_options, "multiselect")
|
144
142
|
belongs_to_field(attr, **html_options)
|
145
143
|
end
|
146
144
|
# rubocop:enable Naming/PredicateName
|
@@ -149,46 +147,46 @@ module DryCrud
|
|
149
147
|
|
150
148
|
# Render the error messages for the current form.
|
151
149
|
def error_messages
|
152
|
-
@template.render(
|
150
|
+
@template.render("shared/error_messages",
|
153
151
|
errors: @object.errors,
|
154
152
|
object: @object)
|
155
153
|
end
|
156
154
|
|
157
155
|
# Renders the given content with an addon.
|
158
156
|
def with_addon(content, addon)
|
159
|
-
tag.div(class:
|
160
|
-
content + tag.span(addon, class:
|
157
|
+
tag.div(class: "input-group") do
|
158
|
+
content + tag.span(addon, class: "input-group-text")
|
161
159
|
end
|
162
160
|
end
|
163
161
|
|
164
162
|
# Renders a static text where otherwise form inputs appear.
|
165
163
|
def static_text(text)
|
166
|
-
tag.p(text, class:
|
164
|
+
tag.p(text, class: "form-control-static")
|
167
165
|
end
|
168
166
|
|
169
167
|
# Generates a help block for fields
|
170
168
|
def help_block(text)
|
171
|
-
tag.p(text, class:
|
169
|
+
tag.p(text, class: "help-block")
|
172
170
|
end
|
173
171
|
|
174
172
|
# Render a submit button and a cancel link for this form.
|
175
|
-
def standard_actions(submit_label = ti(
|
176
|
-
tag.div(class:
|
177
|
-
safe_join([submit_button(submit_label),
|
178
|
-
cancel_link(cancel_url)],
|
179
|
-
|
173
|
+
def standard_actions(submit_label = ti("button.save"), cancel_url = nil)
|
174
|
+
tag.div(class: "col-md-offset-2 col-md-8") do
|
175
|
+
safe_join([ submit_button(submit_label),
|
176
|
+
cancel_link(cancel_url) ],
|
177
|
+
" ")
|
180
178
|
end
|
181
179
|
end
|
182
180
|
|
183
181
|
# Render a standard submit button with the given label.
|
184
|
-
def submit_button(label = ti(
|
185
|
-
button(label, class:
|
182
|
+
def submit_button(label = ti("button.save"))
|
183
|
+
button(label, class: "btn btn-primary", data: { disable_with: label })
|
186
184
|
end
|
187
185
|
|
188
186
|
# Render a cancel link pointing to the given url.
|
189
187
|
def cancel_link(url = nil)
|
190
188
|
url ||= cancel_url
|
191
|
-
link_to(ti(
|
189
|
+
link_to(ti("button.cancel"), url, class: "cancel")
|
192
190
|
end
|
193
191
|
|
194
192
|
# Depending if the given attribute must be present, return
|
@@ -265,7 +263,7 @@ module DryCrud
|
|
265
263
|
# Checks if the passed name corresponds to a field method with a
|
266
264
|
# 'labeled_' prefix.
|
267
265
|
def labeled_field_method?(name)
|
268
|
-
prefix =
|
266
|
+
prefix = "labeled_"
|
269
267
|
if name.to_s.start_with?(prefix)
|
270
268
|
field_method = name.to_s[prefix.size..]
|
271
269
|
field_method if respond_to?(field_method)
|
@@ -321,7 +319,6 @@ module DryCrud
|
|
321
319
|
options[:cancel_url_edit] || options[:cancel_url]
|
322
320
|
end
|
323
321
|
end
|
324
|
-
|
325
322
|
end
|
326
323
|
end
|
327
324
|
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
module DryCrud
|
2
2
|
module Form
|
3
|
-
|
4
3
|
# Internal class to handle the rendering of a single form control,
|
5
4
|
# consisting of a label, input field, addon, help text or
|
6
5
|
# required mark.
|
7
6
|
class Control
|
8
|
-
|
9
7
|
attr_reader :builder, :attr, :args, :options, :addon, :help
|
10
8
|
|
11
9
|
delegate :tag, :object, :add_css_class,
|
12
10
|
to: :builder
|
13
11
|
|
14
12
|
# Html displayed to mark an input as required.
|
15
|
-
REQUIRED_MARK =
|
13
|
+
REQUIRED_MARK = "*".freeze
|
16
14
|
|
17
15
|
# Number of default input field span columns depending
|
18
16
|
# on the #field_method.
|
@@ -70,8 +68,8 @@ module DryCrud
|
|
70
68
|
|
71
69
|
# Create the HTML markup for any labeled content.
|
72
70
|
def labeled
|
73
|
-
tag.div(class:
|
74
|
-
builder.label(attr, caption, class:
|
71
|
+
tag.div(class: "row mb-3") do
|
72
|
+
builder.label(attr, caption, class: "col-md-2 col-form-label") +
|
75
73
|
tag.div(content, class: "col-md-#{span}")
|
76
74
|
end
|
77
75
|
end
|
@@ -98,8 +96,8 @@ module DryCrud
|
|
98
96
|
# depending on the attribute.
|
99
97
|
def input
|
100
98
|
@input ||= begin
|
101
|
-
options[:required] =
|
102
|
-
add_css_class(options,
|
99
|
+
options[:required] = "required" if required
|
100
|
+
add_css_class(options, "is-invalid") if errors?
|
103
101
|
builder.send(field_method, attr, *args, **options)
|
104
102
|
end
|
105
103
|
end
|
@@ -143,9 +141,9 @@ module DryCrud
|
|
143
141
|
:belongs_to_field
|
144
142
|
elsif association_kind?(:has_and_belongs_to_many, :has_many)
|
145
143
|
:has_many_field
|
146
|
-
elsif attr.to_s.include?(
|
144
|
+
elsif attr.to_s.include?("password")
|
147
145
|
:password_field
|
148
|
-
elsif attr.to_s.include?(
|
146
|
+
elsif attr.to_s.include?("email")
|
149
147
|
:email_field
|
150
148
|
elsif builder.respond_to?(:"#{type}_field")
|
151
149
|
:"#{type}_field"
|
@@ -170,8 +168,6 @@ module DryCrud
|
|
170
168
|
false
|
171
169
|
end
|
172
170
|
end
|
173
|
-
|
174
171
|
end
|
175
|
-
|
176
172
|
end
|
177
173
|
end
|