active_scaffold 3.4.43 → 3.5.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/CHANGELOG +39 -0
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +27 -19
- data/app/assets/javascripts/active_scaffold.js.erb +1 -1
- data/app/assets/javascripts/jquery/active_scaffold.js +95 -43
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +30 -6
- data/app/assets/javascripts/prototype/tiny_mce_bridge.js +11 -1
- data/app/assets/stylesheets/active_scaffold_colors.scss +2 -2
- data/app/assets/stylesheets/active_scaffold_layout.css +36 -28
- data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -3
- data/app/views/active_scaffold_overrides/_field_search.html.erb +8 -7
- data/app/views/active_scaffold_overrides/_form_association.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -6
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +52 -50
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_human_conditions.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +2 -0
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +5 -3
- data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_messages.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +18 -10
- data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -3
- data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
- data/app/views/active_scaffold_overrides/_show_actions.html.erb +14 -0
- data/app/views/active_scaffold_overrides/_show_association.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_actions.html.erb +6 -2
- data/app/views/active_scaffold_overrides/_update_column.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/destroy.js.erb +2 -3
- data/app/views/active_scaffold_overrides/edit_associated.js.erb +4 -3
- data/app/views/active_scaffold_overrides/on_action_update.js.erb +5 -3
- data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
- data/app/views/active_scaffold_overrides/on_update.js.erb +6 -6
- data/app/views/active_scaffold_overrides/show.html.erb +6 -0
- data/app/views/active_scaffold_overrides/update.html.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
- data/config/brakeman.ignore +26 -0
- data/config/brakeman.yml +3 -0
- data/config/i18n-tasks.yml +121 -0
- data/config/locales/de.yml +81 -70
- data/config/locales/en.yml +83 -74
- data/config/locales/es.yml +82 -73
- data/config/locales/fr.yml +86 -75
- data/config/locales/hu.yml +81 -70
- data/config/locales/ja.yml +71 -60
- data/config/locales/ru.yml +85 -74
- data/lib/active_scaffold.rb +3 -0
- data/lib/active_scaffold/actions/common_search.rb +11 -7
- data/lib/active_scaffold/actions/core.rb +119 -47
- data/lib/active_scaffold/actions/create.rb +1 -1
- data/lib/active_scaffold/actions/delete.rb +11 -8
- data/lib/active_scaffold/actions/field_search.rb +104 -6
- data/lib/active_scaffold/actions/list.rb +25 -21
- data/lib/active_scaffold/actions/mark.rb +12 -4
- data/lib/active_scaffold/actions/nested.rb +26 -26
- data/lib/active_scaffold/actions/search.rb +2 -2
- data/lib/active_scaffold/actions/show.rb +4 -5
- data/lib/active_scaffold/actions/subform.rb +9 -7
- data/lib/active_scaffold/actions/update.rb +20 -13
- data/lib/active_scaffold/active_record_permissions.rb +24 -5
- data/lib/active_scaffold/attribute_params.rb +68 -49
- data/lib/active_scaffold/bridges.rb +1 -1
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +15 -19
- data/lib/active_scaffold/bridges/bitfields.rb +1 -1
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +10 -14
- data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -7
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +19 -22
- data/lib/active_scaffold/bridges/cancan.rb +4 -3
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +11 -21
- data/lib/active_scaffold/bridges/carrierwave.rb +2 -1
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -6
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +6 -39
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen.rb +4 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +3 -2
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -2
- data/lib/active_scaffold/bridges/date_picker.rb +3 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +43 -38
- data/lib/active_scaffold/bridges/date_picker/helper.rb +24 -23
- data/lib/active_scaffold/bridges/dragonfly.rb +1 -1
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -25
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -2
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +6 -8
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +0 -2
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -1
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/helper.rb +1 -2
- data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/paperclip.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -28
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/record_select.rb +2 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +14 -18
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +4 -8
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -20
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +7 -22
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +14 -14
- data/lib/active_scaffold/config/base.rb +9 -6
- data/lib/active_scaffold/config/core.rb +30 -21
- data/lib/active_scaffold/config/create.rb +2 -1
- data/lib/active_scaffold/config/delete.rb +2 -2
- data/lib/active_scaffold/config/field_search.rb +9 -3
- data/lib/active_scaffold/config/form.rb +4 -4
- data/lib/active_scaffold/config/list.rb +27 -23
- data/lib/active_scaffold/config/nested.rb +4 -4
- data/lib/active_scaffold/config/search.rb +6 -6
- data/lib/active_scaffold/config/show.rb +11 -1
- data/lib/active_scaffold/config/subform.rb +1 -1
- data/lib/active_scaffold/config/update.rb +4 -2
- data/lib/active_scaffold/constraints.rb +39 -36
- data/lib/active_scaffold/core.rb +36 -15
- data/lib/active_scaffold/data_structures/action_columns.rb +14 -9
- data/lib/active_scaffold/data_structures/action_link.rb +4 -5
- data/lib/active_scaffold/data_structures/action_links.rb +5 -4
- data/lib/active_scaffold/data_structures/actions.rb +2 -2
- data/lib/active_scaffold/data_structures/association.rb +8 -0
- data/lib/active_scaffold/data_structures/association/abstract.rb +147 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +42 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +94 -0
- data/lib/active_scaffold/data_structures/association/mongoid.rb +45 -0
- data/lib/active_scaffold/data_structures/bridge.rb +3 -6
- data/lib/active_scaffold/data_structures/column.rb +100 -82
- data/lib/active_scaffold/data_structures/columns.rb +21 -3
- data/lib/active_scaffold/data_structures/nested_info.rb +22 -37
- data/lib/active_scaffold/data_structures/set.rb +4 -4
- data/lib/active_scaffold/data_structures/sorting.rb +29 -15
- data/lib/active_scaffold/engine.rb +3 -1
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +10 -5
- data/lib/active_scaffold/extensions/action_view_rendering.rb +65 -59
- data/lib/active_scaffold/extensions/left_outer_joins.rb +48 -53
- data/lib/active_scaffold/extensions/localize.rb +3 -4
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +7 -11
- data/lib/active_scaffold/extensions/paginator_extensions.rb +20 -18
- data/lib/active_scaffold/extensions/routing_mapper.rb +104 -40
- data/lib/active_scaffold/extensions/to_label.rb +1 -1
- data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -13
- data/lib/active_scaffold/extensions/unsaved_record.rb +12 -1
- data/lib/active_scaffold/finder.rb +200 -134
- data/lib/active_scaffold/helpers/action_link_helpers.rb +398 -0
- data/lib/active_scaffold/helpers/association_helpers.rb +12 -30
- data/lib/active_scaffold/helpers/controller_helpers.rb +74 -24
- data/lib/active_scaffold/helpers/form_column_helpers.rb +205 -112
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +21 -11
- data/lib/active_scaffold/helpers/id_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/list_column_helpers.rb +117 -39
- data/lib/active_scaffold/helpers/pagination_helpers.rb +11 -14
- data/lib/active_scaffold/helpers/search_column_helpers.rb +69 -32
- data/lib/active_scaffold/helpers/show_column_helpers.rb +9 -3
- data/lib/active_scaffold/helpers/view_helpers.rb +41 -426
- data/lib/active_scaffold/orm_checks.rb +109 -0
- data/lib/active_scaffold/paginator.rb +1 -1
- data/lib/active_scaffold/responds_to_parent.rb +12 -10
- data/lib/active_scaffold/tableless.rb +81 -43
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold/controller_generator.rb +49 -0
- data/lib/generators/active_scaffold/install_generator.rb +45 -0
- data/lib/generators/active_scaffold/resource_generator.rb +56 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/controller.rb +0 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/helper.rb +0 -0
- data/shoulda_macros/macros.rb +3 -3
- data/test/active_scaffold_config_mock.rb +33 -0
- data/test/bridges/bridge_test.rb +9 -9
- data/test/bridges/date_picker_test.rb +3 -1
- data/test/bridges/paper_trail_test.rb +2 -3
- data/test/bridges/paperclip_test.rb +21 -10
- data/test/bridges/tiny_mce_test.rb +20 -21
- data/test/class_with_finder.rb +42 -0
- data/test/company.rb +6 -4
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/list_test.rb +3 -3
- data/test/config/update_test.rb +3 -3
- data/test/data_structures/action_columns_test.rb +3 -3
- data/test/data_structures/association_column_test.rb +5 -5
- data/test/data_structures/column_test.rb +14 -14
- data/test/data_structures/columns_test.rb +2 -2
- data/test/data_structures/set_test.rb +2 -2
- data/test/data_structures/sorting_test.rb +6 -4
- data/test/extensions/active_record_test.rb +1 -1
- data/test/extensions/routing_mapper_test.rb +64 -13
- data/test/helpers/form_column_helpers_test.rb +6 -6
- data/test/helpers/list_column_helpers_test.rb +9 -5
- data/test/helpers/pagination_helpers_test.rb +1 -0
- data/test/misc/active_record_permissions_test.rb +18 -1
- data/test/misc/attribute_params_test.rb +26 -17
- data/test/misc/calculation_test.rb +8 -31
- data/test/misc/configurable_test.rb +3 -2
- data/test/misc/constraints_test.rb +33 -22
- data/test/misc/convert_numbers_format_test.rb +28 -10
- data/test/misc/finder_test.rb +6 -29
- data/test/misc/parse_datetime_test.rb +160 -0
- data/test/misc/render_test.rb +1 -1
- data/test/misc/tableless_test.rb +24 -0
- data/test/mock_app/app/models/building.rb +2 -1
- data/test/mock_app/config.ru +1 -1
- data/test/mock_app/config/environments/test.rb +1 -1
- data/test/mock_app/config/routes.rb +11 -3
- data/test/model_stub.rb +11 -6
- data/test/run_all.rb +1 -1
- data/test/test_helper.rb +19 -4
- metadata +42 -23
- data/lib/active_scaffold/data_structures/error_message.rb +0 -22
- data/lib/active_scaffold/extensions/reverse_associations.rb +0 -119
- data/lib/generators/active_scaffold/USAGE +0 -29
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +0 -21
- data/lib/generators/active_scaffold_controller/USAGE +0 -19
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +0 -29
- data/test/data_structures/error_message_test.rb +0 -25
@@ -15,9 +15,17 @@ module ActiveScaffold
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
def active_scaffold_grouped_by_label
|
19
|
+
text, = active_scaffold_config.field_search.group_options.find do |text, value|
|
20
|
+
(value || text).to_s == field_search_params['active_scaffold_group']
|
21
|
+
end
|
22
|
+
active_scaffold_translated_option(active_scaffold_group_column, text).first if text
|
23
|
+
end
|
24
|
+
|
18
25
|
def format_human_condition(column, opt, from = nil, to = nil)
|
19
26
|
attribute = column.active_record_class.human_attribute_name(column.name)
|
20
|
-
opt ||=
|
27
|
+
opt ||= :between if from && to
|
28
|
+
opt ||= from ? '>=' : '<='
|
21
29
|
"#{attribute} #{as_(opt).downcase} #{from} #{to}"
|
22
30
|
end
|
23
31
|
|
@@ -26,8 +34,8 @@ module ActiveScaffold
|
|
26
34
|
to = "- #{format_number_value(controller.class.condition_value_for_numeric(column, value['to']), column.options)}" if value['opt'] == 'BETWEEN'
|
27
35
|
format_human_condition column, value['opt'].downcase, from, to
|
28
36
|
end
|
29
|
-
|
30
|
-
|
37
|
+
alias active_scaffold_human_condition_decimal active_scaffold_human_condition_integer
|
38
|
+
alias active_scaffold_human_condition_float active_scaffold_human_condition_integer
|
31
39
|
|
32
40
|
def active_scaffold_human_condition_string(column, value)
|
33
41
|
opt = ActiveScaffold::Finder::STRING_COMPARATORS.key(value['opt']) || value['opt']
|
@@ -43,16 +51,16 @@ module ActiveScaffold
|
|
43
51
|
to = "- #{I18n.l to}" if to
|
44
52
|
format_human_condition column, value['opt'], from, to
|
45
53
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
alias active_scaffold_human_condition_time active_scaffold_human_condition_date
|
55
|
+
alias active_scaffold_human_condition_datetime active_scaffold_human_condition_date
|
56
|
+
alias active_scaffold_human_condition_timestamp active_scaffold_human_condition_date
|
49
57
|
|
50
58
|
def active_scaffold_human_condition_boolean(column, value)
|
51
59
|
attribute = column.active_record_class.human_attribute_name(column.name)
|
52
60
|
label = as_(ActiveScaffold::Core.column_type_cast(value, column.column) ? :true : :false)
|
53
61
|
as_(:boolean, :scope => :human_conditions, :column => attribute, :value => label)
|
54
62
|
end
|
55
|
-
|
63
|
+
alias active_scaffold_human_condition_checkbox active_scaffold_human_condition_boolean
|
56
64
|
|
57
65
|
def active_scaffold_human_condition_null(column, value)
|
58
66
|
format_human_condition column, value.to_sym
|
@@ -66,21 +74,23 @@ module ActiveScaffold
|
|
66
74
|
associated = column.association.klass.where(:id => associated.map(&:to_i)).map(&method)
|
67
75
|
elsif column.options[:options]
|
68
76
|
associated = associated.collect do |value|
|
69
|
-
text, val = column.options[:options].find { |
|
77
|
+
text, val = column.options[:options].find { |t, v| (v.nil? ? t : v).to_s == value.to_s }
|
70
78
|
value = active_scaffold_translated_option(column, text, val).first if text
|
71
79
|
value
|
72
80
|
end
|
73
81
|
end
|
74
82
|
as_(:association, :scope => :human_conditions, :column => attribute, :value => associated.join(', '))
|
75
83
|
end
|
76
|
-
|
77
|
-
|
84
|
+
alias active_scaffold_human_condition_multi_select active_scaffold_human_condition_select
|
85
|
+
alias active_scaffold_human_condition_record_select active_scaffold_human_condition_select
|
86
|
+
alias active_scaffold_human_condition_chosen active_scaffold_human_condition_select
|
87
|
+
alias active_scaffold_human_condition_multi_chosen active_scaffold_human_condition_select
|
78
88
|
|
79
89
|
# the naming convention for overriding form fields with helpers
|
80
90
|
def override_human_condition_column(column)
|
81
91
|
override_helper column, 'human_condition_column'
|
82
92
|
end
|
83
|
-
|
93
|
+
alias override_human_condition_column? override_human_condition_column
|
84
94
|
|
85
95
|
def override_human_condition?(search_ui)
|
86
96
|
respond_to?(override_human_condition(search_ui))
|
@@ -1,11 +1,15 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
module ActiveScaffold
|
3
2
|
module Helpers
|
4
3
|
# Helpers that assist with the rendering of a List Column
|
5
4
|
module ListColumnHelpers
|
6
5
|
def get_column_value(record, column)
|
7
|
-
|
8
|
-
|
6
|
+
record = record.send(column.delegated_association.name) if column.delegated_association
|
7
|
+
if record
|
8
|
+
method = get_column_method(record, column)
|
9
|
+
value = send(method, record, column)
|
10
|
+
else
|
11
|
+
value = nil
|
12
|
+
end
|
9
13
|
value = ' '.html_safe if value.nil? || value.blank? # fix for IE 6
|
10
14
|
return value
|
11
15
|
rescue StandardError => e
|
@@ -38,7 +42,9 @@ module ActiveScaffold
|
|
38
42
|
if column.link && !skip_action_link?(column.link, record)
|
39
43
|
link = column.link
|
40
44
|
associated = record.send(column.association.name) if column.association
|
41
|
-
|
45
|
+
authorized = link.action.nil?
|
46
|
+
authorized, reason = column_link_authorized?(link, column, record, associated) unless authorized
|
47
|
+
render_action_link(link, record, :link => text, :authorized => authorized, :not_authorized_reason => reason)
|
42
48
|
elsif inplace_edit?(record, column)
|
43
49
|
active_scaffold_inplace_edit(record, column, :formatted_column => text)
|
44
50
|
elsif active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.wrap_tag
|
@@ -84,7 +90,7 @@ module ActiveScaffold
|
|
84
90
|
options.delete(:disabled) if inplace_edit?(record, column)
|
85
91
|
check_box(:record, column.name, options)
|
86
92
|
end
|
87
|
-
|
93
|
+
|
88
94
|
def active_scaffold_column_percentage(record, column)
|
89
95
|
options = column.options[:slider] || {}
|
90
96
|
options = options.merge(min: record.send(options[:min_method])) if options[:min_method]
|
@@ -93,10 +99,31 @@ module ActiveScaffold
|
|
93
99
|
as_slider options.merge(value: value || record.send(column.name))
|
94
100
|
end
|
95
101
|
|
102
|
+
def active_scaffold_column_month(record, column)
|
103
|
+
l record.send(column.name), format: :year_month
|
104
|
+
end
|
105
|
+
|
106
|
+
def active_scaffold_column_week(record, column)
|
107
|
+
l record.send(column.name), format: :week
|
108
|
+
end
|
109
|
+
|
110
|
+
def tel_to(text)
|
111
|
+
groups = text.to_s.scan(/(?:^\+)?\d+/)
|
112
|
+
extension = groups.pop if text.to_s =~ /\s*[^\d\s]+\s*\d+$/
|
113
|
+
link_to text, "tel:#{[groups.join('-'), extension].compact.join(',')}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def active_scaffold_column_telephone(record, column)
|
117
|
+
phone = record.send column.name
|
118
|
+
return if phone.blank?
|
119
|
+
phone = number_to_phone(phone) unless column.options[:format] == false
|
120
|
+
tel_to phone
|
121
|
+
end
|
122
|
+
|
96
123
|
def column_override(column)
|
97
124
|
override_helper column, 'column'
|
98
125
|
end
|
99
|
-
|
126
|
+
alias column_override? column_override
|
100
127
|
|
101
128
|
# the naming convention for overriding column types with helpers
|
102
129
|
def override_column_ui(list_ui)
|
@@ -105,7 +132,7 @@ module ActiveScaffold
|
|
105
132
|
method = "active_scaffold_column_#{list_ui}"
|
106
133
|
@_column_ui_overrides[list_ui] = (method if respond_to? method)
|
107
134
|
end
|
108
|
-
|
135
|
+
alias override_column_ui? override_column_ui
|
109
136
|
|
110
137
|
##
|
111
138
|
## Formatting
|
@@ -113,19 +140,23 @@ module ActiveScaffold
|
|
113
140
|
def format_column_value(record, column, value = nil)
|
114
141
|
value ||= record.send(column.name) unless record.nil?
|
115
142
|
if column.association.nil?
|
116
|
-
if [
|
117
|
-
text, val = column.options[:options].find { |
|
143
|
+
if %i[select radio].include?(column.form_ui) && column.options[:options]
|
144
|
+
text, val = column.options[:options].find { |t, v| (v.nil? ? t : v).to_s == value.to_s }
|
118
145
|
value = active_scaffold_translated_option(column, text, val).first if text
|
119
146
|
end
|
120
|
-
if
|
147
|
+
if grouped_search? && column == search_group_column && search_group_function
|
148
|
+
format_grouped_search_column(value, column.options)
|
149
|
+
elsif value.is_a? Numeric
|
121
150
|
format_number_value(value, column.options)
|
122
151
|
else
|
123
152
|
format_value(value, column.options)
|
124
153
|
end
|
125
154
|
else
|
126
|
-
if column.
|
155
|
+
if column.association.collection?
|
127
156
|
associated_size = value.size if column.associated_number? # get count before cache association
|
128
|
-
|
157
|
+
if column.association.respond_to_target? && !value.loaded?
|
158
|
+
cache_association(record.association(column.name), column, associated_size)
|
159
|
+
end
|
129
160
|
end
|
130
161
|
format_association_value(value, column, associated_size)
|
131
162
|
end
|
@@ -134,38 +165,55 @@ module ActiveScaffold
|
|
134
165
|
def format_number_value(value, options = {})
|
135
166
|
if value
|
136
167
|
value = case options[:format]
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
168
|
+
when :size
|
169
|
+
number_to_human_size(value, options[:i18n_options] || {})
|
170
|
+
when :percentage
|
171
|
+
number_to_percentage(value, options[:i18n_options] || {})
|
172
|
+
when :currency
|
173
|
+
number_to_currency(value, options[:i18n_options] || {})
|
174
|
+
when :i18n_number
|
175
|
+
send("number_with_#{value.is_a?(Integer) ? 'delimiter' : 'precision'}", value, options[:i18n_options] || {})
|
176
|
+
else
|
177
|
+
value
|
147
178
|
end
|
148
179
|
end
|
149
180
|
clean_column_value(value)
|
150
181
|
end
|
151
182
|
|
183
|
+
def format_grouped_search_column(value, options = {})
|
184
|
+
case search_group_function
|
185
|
+
when 'year_month'
|
186
|
+
year, month = value.to_s.scan(/(\d*)(\d{2})/)[0]
|
187
|
+
I18n.l(Date.new(year.to_i, month.to_i, 1), format: options[:group_format] || search_group_function.to_sym)
|
188
|
+
when 'year_quarter'
|
189
|
+
year, quarter = value.to_s.scan(/(\d*)(\d)/)[0]
|
190
|
+
I18n.t(options[:group_format] || search_group_function, scope: 'date.formats', year: year, quarter: quarter)
|
191
|
+
when 'quarter'
|
192
|
+
I18n.t(options[:group_format] || search_group_function, scope: 'date.formats', num: value)
|
193
|
+
when 'month'
|
194
|
+
I18n.l(Date.new(Time.zone.today.year, value, 1), format: options[:group_format] || search_group_function.to_sym)
|
195
|
+
else value
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
152
199
|
def format_collection_association_value(value, column, label_method, size)
|
153
200
|
if column.associated_limit.nil?
|
154
201
|
firsts = value.collect(&label_method)
|
155
|
-
|
202
|
+
safe_join firsts, active_scaffold_config.list.association_join_text
|
203
|
+
elsif column.associated_limit.zero?
|
156
204
|
size if column.associated_number?
|
157
205
|
else
|
158
|
-
firsts = value.
|
159
|
-
firsts.
|
206
|
+
firsts = value.loaded? ? value[0, column.associated_limit] : value.limit(column.associated_limit)
|
207
|
+
firsts = firsts.map(&label_method)
|
160
208
|
firsts << '…' if value.size > column.associated_limit
|
161
|
-
text = firsts
|
209
|
+
text = safe_join firsts, active_scaffold_config.list.association_join_text
|
162
210
|
text << " (#{size})" if column.associated_number? && column.associated_limit && value.size > column.associated_limit
|
163
211
|
text
|
164
212
|
end
|
165
213
|
end
|
166
214
|
|
167
215
|
def format_singular_association_value(value, column, label_method)
|
168
|
-
if column.
|
216
|
+
if column.association.polymorphic?
|
169
217
|
"#{value.class.model_name.human}: #{value.send(label_method)}"
|
170
218
|
else
|
171
219
|
value.send(label_method)
|
@@ -215,7 +263,14 @@ module ActiveScaffold
|
|
215
263
|
|
216
264
|
def inplace_edit?(record, column)
|
217
265
|
return unless column.inplace_edit
|
218
|
-
|
266
|
+
if controller.respond_to?(:update_authorized?, true)
|
267
|
+
if controller.method(:update_authorized?).parameters.size == 2
|
268
|
+
return Array(controller.send(:update_authorized?, record, column.name))[0]
|
269
|
+
else
|
270
|
+
ActiveSupport::Deprecation.warn 'add column = nil parameter to update_authorized? on your controller'
|
271
|
+
editable = Array(controller.send(:update_authorized?, record))[0]
|
272
|
+
end
|
273
|
+
end
|
219
274
|
editable || record.authorized_for?(:crud_type => :update, :column => column.name)
|
220
275
|
end
|
221
276
|
|
@@ -239,17 +294,14 @@ module ActiveScaffold
|
|
239
294
|
|
240
295
|
def inplace_edit_control(column)
|
241
296
|
return unless inplace_edit?(active_scaffold_config.model, column) && inplace_edit_cloning?(column)
|
242
|
-
old_record, @record = @record, active_scaffold_config.model.new # TODO: remove when relying on @record is removed
|
243
297
|
column = column.clone
|
244
298
|
column.options = column.options.clone
|
245
299
|
column.form_ui = :select if column.association && column.form_ui.nil?
|
246
|
-
options = active_scaffold_input_options(column).merge(:object =>
|
300
|
+
options = active_scaffold_input_options(column).merge(:object => column.active_record_class.new)
|
247
301
|
options[:class] = "#{options[:class]} inplace_field"
|
248
302
|
options[:"data-id"] = options[:id]
|
249
303
|
options[:id] = nil
|
250
|
-
content_tag(:div, active_scaffold_input_for(column, nil, options), :style => 'display:none;', :class => inplace_edit_control_css_class)
|
251
|
-
@record = old_record # TODO: remove when relying on @record is removed
|
252
|
-
end
|
304
|
+
content_tag(:div, active_scaffold_input_for(column, nil, options), :style => 'display:none;', :class => inplace_edit_control_css_class)
|
253
305
|
end
|
254
306
|
|
255
307
|
def inplace_edit_control_css_class
|
@@ -273,8 +325,8 @@ module ActiveScaffold
|
|
273
325
|
elsif inplace_edit_cloning?(column)
|
274
326
|
data[:ie_mode] = :clone
|
275
327
|
elsif column.inplace_edit == :ajax
|
276
|
-
url = url_for(:controller => params_for[:controller], :action => 'render_field', :id => '__id__', :update_column => column.name)
|
277
|
-
plural = column.
|
328
|
+
url = url_for(params_for(:controller => params_for[:controller], :action => 'render_field', :id => '__id__', :update_column => column.name))
|
329
|
+
plural = column.association.try(:collection?) && !override_form_field?(column) && %i[select record_select].include?(column.form_ui)
|
278
330
|
data[:ie_render_url] = url
|
279
331
|
data[:ie_mode] = :ajax
|
280
332
|
data[:ie_plural] = plural
|
@@ -282,6 +334,8 @@ module ActiveScaffold
|
|
282
334
|
data
|
283
335
|
end
|
284
336
|
|
337
|
+
# MARK
|
338
|
+
|
285
339
|
def all_marked?
|
286
340
|
if active_scaffold_config.mark.mark_all_mode == :page
|
287
341
|
@page.items.detect { |record| !marked_records.include?(record.id) }.nil?
|
@@ -298,6 +352,8 @@ module ActiveScaffold
|
|
298
352
|
content_tag(:span, check_box_tag("#{controller_id}_mark_heading_span_input", '1', all_marked?), tag_options)
|
299
353
|
end
|
300
354
|
|
355
|
+
# COLUMN HEADINGS
|
356
|
+
|
301
357
|
def column_heading_attributes(column, sorting, sort_direction)
|
302
358
|
{:id => active_scaffold_column_header_id(column), :class => column_heading_class(column, sorting), :title => strip_tags(column.description).presence}
|
303
359
|
end
|
@@ -322,11 +378,12 @@ module ActiveScaffold
|
|
322
378
|
options = {:id => nil, :class => 'as_sort',
|
323
379
|
'data-page-history' => controller_id,
|
324
380
|
:remote => true, :method => :get}
|
325
|
-
|
326
|
-
|
327
|
-
|
381
|
+
url_options = {action: :index, page: 1, sort: column.name, sort_direction: sort_direction}
|
382
|
+
# :id needed because rails reuse it even if it was deleted from params (like do_refresh_list does)
|
383
|
+
url_options[:id] = nil if @remove_id_from_list_links
|
384
|
+
url_options = params_for(url_options)
|
328
385
|
unless active_scaffold_config.store_user_settings
|
329
|
-
url_options
|
386
|
+
url_options[:search] = search_params if respond_to?(:search_params) && search_params.present?
|
330
387
|
end
|
331
388
|
link_to column_heading_label(column), url_options, options
|
332
389
|
else
|
@@ -337,6 +394,27 @@ module ActiveScaffold
|
|
337
394
|
def column_heading_label(column)
|
338
395
|
column.label
|
339
396
|
end
|
397
|
+
|
398
|
+
# CALCULATIONS
|
399
|
+
|
400
|
+
def column_calculation(column)
|
401
|
+
if column.calculate.instance_of? Proc
|
402
|
+
column.calculate.call(@records)
|
403
|
+
else
|
404
|
+
calculate_query.calculate(column.calculate, column.name)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def render_column_calculation(column)
|
409
|
+
calculation = column_calculation(column)
|
410
|
+
override_formatter = "render_#{column.name}_#{column.calculate.is_a?(Proc) ? :calculate : column.calculate}"
|
411
|
+
calculation = send(override_formatter, calculation) if respond_to? override_formatter
|
412
|
+
format_column_calculation(column, calculation)
|
413
|
+
end
|
414
|
+
|
415
|
+
def format_column_calculation(column, calculation)
|
416
|
+
"#{"#{as_(column.calculate)}: " unless column.calculate.is_a? Proc}#{format_column_value nil, column, calculation}"
|
417
|
+
end
|
340
418
|
end
|
341
419
|
end
|
342
420
|
end
|
@@ -6,14 +6,11 @@ module ActiveScaffold
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def pagination_url_options(url_options = nil)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
url_options
|
13
|
-
|
14
|
-
column, direction = active_scaffold_config.list.user.sorting.first
|
15
|
-
url_options.merge!(:sort => column.name, :sort_direction => direction)
|
16
|
-
end
|
9
|
+
if url_options.nil?
|
10
|
+
url_options = {action: @pagination_action || :index}
|
11
|
+
# :id needed because rails reuse it even if it was deleted from params (like do_refresh_list does)
|
12
|
+
url_options[:id] = nil if @remove_id_from_list_links
|
13
|
+
url_options = params_for(url_options)
|
17
14
|
end
|
18
15
|
url_options
|
19
16
|
end
|
@@ -51,11 +48,11 @@ module ActiveScaffold
|
|
51
48
|
html << '..' if start_number > last_page + 1
|
52
49
|
|
53
50
|
[start_number, last_page + 1].max.upto(end_number) do |num|
|
54
|
-
if current_page.number == num
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
html << if current_page.number == num
|
52
|
+
content_tag(:span, num.to_s, :class => 'as_paginate current')
|
53
|
+
else
|
54
|
+
pagination_ajax_link(num, url_options, options)
|
55
|
+
end
|
59
56
|
end
|
60
57
|
|
61
58
|
if current_page.pager.infinite?
|
@@ -68,7 +65,7 @@ module ActiveScaffold
|
|
68
65
|
html << pagination_ajax_link(num, url_options, options)
|
69
66
|
end
|
70
67
|
end
|
71
|
-
html
|
68
|
+
safe_join html, ' '
|
72
69
|
end
|
73
70
|
end
|
74
71
|
end
|
@@ -7,8 +7,10 @@ module ActiveScaffold
|
|
7
7
|
def active_scaffold_search_for(column, options = nil)
|
8
8
|
options ||= active_scaffold_search_options(column)
|
9
9
|
record = options[:object]
|
10
|
-
|
11
|
-
|
10
|
+
if column.delegated_association
|
11
|
+
record = record.send(column.delegated_association.name) || column.active_record_class.new
|
12
|
+
options[:object] = record
|
13
|
+
end
|
12
14
|
|
13
15
|
# first, check if the dev has created an override for this specific field for search
|
14
16
|
if (method = override_search_field(column))
|
@@ -41,7 +43,7 @@ module ActiveScaffold
|
|
41
43
|
# final ultimate fallback: use rails' generic input method
|
42
44
|
else
|
43
45
|
# for textual fields we pass different options
|
44
|
-
text_types = [
|
46
|
+
text_types = %i[text string integer float decimal]
|
45
47
|
options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
|
46
48
|
text_field(:record, column.name, options.merge(column.options))
|
47
49
|
end
|
@@ -64,7 +66,7 @@ module ActiveScaffold
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def search_label_for(column, options)
|
67
|
-
options[:id] unless [
|
69
|
+
options[:id] unless %i[range integer decimal float string date_picker datetime_picker calendar_date_select].include? column.search_ui
|
68
70
|
end
|
69
71
|
|
70
72
|
##
|
@@ -73,8 +75,6 @@ module ActiveScaffold
|
|
73
75
|
|
74
76
|
def active_scaffold_search_multi_select(column, options)
|
75
77
|
record = options.delete(:object)
|
76
|
-
ActiveSupport::Deprecation.warn 'Relying on @record is deprecated, include :object in options with record.', caller if record.nil? # TODO: Remove when relying on @record is removed
|
77
|
-
record ||= @record # TODO: Remove when relying on @record is removed
|
78
78
|
associated = options.delete :value
|
79
79
|
associated = [associated].compact unless associated.is_a? Array
|
80
80
|
|
@@ -96,12 +96,10 @@ module ActiveScaffold
|
|
96
96
|
|
97
97
|
def active_scaffold_search_select(column, html_options, options = {})
|
98
98
|
record = html_options.delete(:object)
|
99
|
-
ActiveSupport::Deprecation.warn 'Relying on @record is deprecated, include :object in html_options with record.', caller if record.nil? # TODO: Remove when relying on @record is removed
|
100
|
-
record ||= @record # TODO: Remove when relying on @record is removed
|
101
99
|
associated = html_options.delete :value
|
102
100
|
if column.association
|
103
101
|
associated = associated.is_a?(Array) ? associated.map(&:to_i) : associated.to_i unless associated.nil?
|
104
|
-
method = column.association.
|
102
|
+
method = column.association.belongs_to? ? column.association.foreign_key : column.name
|
105
103
|
select_options = sorted_association_options_find(column.association, false, record)
|
106
104
|
else
|
107
105
|
method = column.name
|
@@ -113,7 +111,7 @@ module ActiveScaffold
|
|
113
111
|
options = options.merge(:selected => associated).merge column.options
|
114
112
|
html_options.merge! column.options[:html_options] || {}
|
115
113
|
if html_options[:multiple]
|
116
|
-
html_options
|
114
|
+
active_scaffold_select_name_with_multiple html_options
|
117
115
|
else
|
118
116
|
options[:include_blank] ||= as_(:_select_)
|
119
117
|
active_scaffold_translate_select_options(options)
|
@@ -143,7 +141,27 @@ module ActiveScaffold
|
|
143
141
|
select_tag(options[:name], options_for_select(select_options, ActiveScaffold::Core.column_type_cast(options[:value], column.column)), :id => options[:id])
|
144
142
|
end
|
145
143
|
# we can't use checkbox ui because it's not possible to decide whether search for this field or not
|
146
|
-
|
144
|
+
alias active_scaffold_search_checkbox active_scaffold_search_boolean
|
145
|
+
|
146
|
+
def active_scaffold_group_search_column(record, options)
|
147
|
+
select_tag 'search[active_scaffold_group]', options_for_select(active_scaffold_group_search_options, selected: field_search_params['active_scaffold_group'])
|
148
|
+
end
|
149
|
+
|
150
|
+
def active_scaffold_group_search_options
|
151
|
+
options = active_scaffold_config.field_search.group_options.collect do |text, value|
|
152
|
+
active_scaffold_translated_option(active_scaffold_group_column, text, value)
|
153
|
+
end
|
154
|
+
[[as_(:no_group), '']].concat options
|
155
|
+
end
|
156
|
+
|
157
|
+
def active_scaffold_group_column
|
158
|
+
return if active_scaffold_config.field_search.group_options.blank?
|
159
|
+
@_active_scaffold_group_column ||= begin
|
160
|
+
column = ActiveScaffold::DataStructures::Column.new(:active_scaffold_group, active_scaffold_config.model)
|
161
|
+
column.label = :group_by
|
162
|
+
column
|
163
|
+
end
|
164
|
+
end
|
147
165
|
|
148
166
|
def active_scaffold_search_null(column, options)
|
149
167
|
select_options = []
|
@@ -165,10 +183,11 @@ module ActiveScaffold
|
|
165
183
|
def active_scaffold_search_range_comparator_options(column)
|
166
184
|
select_options = ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
167
185
|
if active_scaffold_search_range_string?(column)
|
168
|
-
|
186
|
+
comparators = ActiveScaffold::Finder::STRING_COMPARATORS.collect { |title, comp| [as_(title), comp] }
|
187
|
+
select_options.unshift(*comparators)
|
169
188
|
end
|
170
189
|
if include_null_comparators? column
|
171
|
-
select_options
|
190
|
+
select_options.concat ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] }
|
172
191
|
end
|
173
192
|
select_options
|
174
193
|
end
|
@@ -176,13 +195,13 @@ module ActiveScaffold
|
|
176
195
|
def include_null_comparators?(column)
|
177
196
|
return column.options[:null_comparators] if column.options.key? :null_comparators
|
178
197
|
if column.association
|
179
|
-
column.association.
|
198
|
+
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].column.try(:null)
|
180
199
|
else
|
181
200
|
column.column.try(:null)
|
182
201
|
end
|
183
202
|
end
|
184
203
|
|
185
|
-
def active_scaffold_search_range(column, options)
|
204
|
+
def active_scaffold_search_range(column, options, input_method = :text_field_tag, input_options = {})
|
186
205
|
opt_value, from_value, to_value = field_search_params_range_values(column)
|
187
206
|
|
188
207
|
select_options = active_scaffold_search_range_comparator_options(column)
|
@@ -199,34 +218,48 @@ module ActiveScaffold
|
|
199
218
|
to_value = format_number_value(to_value, column.options) if to_value.is_a?(Numeric)
|
200
219
|
html = select_tag("#{options[:name]}[opt]", options_for_select(select_options, opt_value),
|
201
220
|
:id => "#{options[:id]}_opt", :class => 'as_search_range_option')
|
221
|
+
from_options = active_scaffold_input_text_options(input_options.merge(:id => options[:id], :size => text_field_size))
|
222
|
+
to_options = from_options.merge(:id => "#{options[:id]}_to")
|
202
223
|
html << content_tag('span', :id => "#{options[:id]}_numeric", :style => ActiveScaffold::Finder::NULL_COMPARATORS.include?(opt_value) ? 'display: none' : nil) do
|
203
|
-
|
224
|
+
send(input_method, "#{options[:name]}[from]", from_value, input_options) <<
|
204
225
|
content_tag(
|
205
|
-
:span,
|
206
|
-
|
207
|
-
active_scaffold_input_text_options(:id => "#{options[:id]}_to", :size => text_field_size))
|
208
|
-
).html_safe,
|
226
|
+
:span,
|
227
|
+
safe_join([' - ', send(input_method, "#{options[:name]}[to]", to_value, to_options)]),
|
209
228
|
:id => "#{options[:id]}_between", :class => 'as_search_range_between', :style => (opt_value == 'BETWEEN') ? nil : 'display: none'
|
210
229
|
)
|
211
230
|
end
|
212
231
|
content_tag :span, html, :class => 'search_range'
|
213
232
|
end
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
233
|
+
alias active_scaffold_search_string active_scaffold_search_range
|
234
|
+
|
235
|
+
def active_scaffold_search_integer(column, options)
|
236
|
+
active_scaffold_search_range(column, options, :number_field_tag, step: '1')
|
237
|
+
end
|
238
|
+
|
239
|
+
def active_scaffold_search_decimal(column, options)
|
240
|
+
active_scaffold_search_range(column, options, :number_field_tag, step: :any)
|
241
|
+
end
|
242
|
+
alias active_scaffold_search_float active_scaffold_search_decimal
|
218
243
|
|
219
244
|
def field_search_datetime_value(value)
|
220
|
-
|
245
|
+
Time.zone.local(value[:year].to_i, value[:month].to_i, value[:day].to_i, value[:hour].to_i, value[:minute].to_i, value[:second].to_i) unless value.nil? || value[:year].blank?
|
221
246
|
end
|
222
247
|
|
223
248
|
def active_scaffold_search_datetime(column, options)
|
224
249
|
_, from_value, to_value = field_search_params_range_values(column)
|
225
250
|
options = column.options.merge(options)
|
226
|
-
|
251
|
+
type = "#{'date' unless options[:discard_date]}#{'time' unless options[:discard_time]}"
|
252
|
+
use_select = options.delete(:use_select)
|
253
|
+
helper = use_select ? "select_#{type}" : "#{type}#{'_local' if type == 'datetime'}_field"
|
254
|
+
if use_select
|
255
|
+
default_from_options = {include_blank: true, prefix: "#{options[:name]}[from]"}
|
256
|
+
default_to_options = {include_blank: true, prefix: "#{options[:name]}[to]"}
|
257
|
+
end
|
227
258
|
|
228
|
-
|
229
|
-
|
259
|
+
safe_join [
|
260
|
+
send(helper, field_search_datetime_value(from_value), options.reverse_merge(default_from_options || {})),
|
261
|
+
send(helper, field_search_datetime_value(to_value), options.reverse_merge(default_to_options || {}))
|
262
|
+
], ' - '
|
230
263
|
end
|
231
264
|
|
232
265
|
def active_scaffold_search_date(column, options)
|
@@ -236,7 +269,7 @@ module ActiveScaffold
|
|
236
269
|
def active_scaffold_search_time(column, options)
|
237
270
|
active_scaffold_search_datetime(column, options.merge!(:discard_date => true))
|
238
271
|
end
|
239
|
-
|
272
|
+
alias active_scaffold_search_timestamp active_scaffold_search_datetime
|
240
273
|
|
241
274
|
##
|
242
275
|
## Search column override signatures
|
@@ -267,16 +300,20 @@ module ActiveScaffold
|
|
267
300
|
visibles << column
|
268
301
|
end
|
269
302
|
end
|
303
|
+
if active_scaffold_group_column
|
304
|
+
columns = grouped_search? || search_config.optional_columns.empty? ? visibles : hiddens
|
305
|
+
columns << active_scaffold_group_column
|
306
|
+
end
|
270
307
|
[visibles, hiddens]
|
271
308
|
end
|
272
309
|
|
273
310
|
def searched_by?(column)
|
274
|
-
value = field_search_params[column.name]
|
311
|
+
value = field_search_params[column.name.to_s]
|
275
312
|
case value
|
276
313
|
when Hash
|
277
|
-
|
314
|
+
value['from'].present?
|
278
315
|
when String
|
279
|
-
|
316
|
+
value.present?
|
280
317
|
else
|
281
318
|
false
|
282
319
|
end
|