active_scaffold 3.4.43 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|