active_scaffold 3.7.0 → 3.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +20 -0
- data/README.md +2 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +68 -62
- data/app/assets/stylesheets/active_scaffold_layout.css +1 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +9 -6
- data/config/locales/de.yml +6 -3
- data/config/locales/en.yml +3 -0
- data/config/locales/es.yml +3 -0
- data/config/locales/fr.yml +9 -6
- data/config/locales/hu.yml +20 -17
- data/config/locales/ja.yml +25 -22
- data/config/locales/ru.yml +17 -14
- data/lib/active_scaffold/actions/update.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +7 -17
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +6 -6
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +7 -7
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +12 -14
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +10 -10
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +7 -7
- data/lib/active_scaffold/bridges/date_picker/ext.rb +20 -9
- data/lib/active_scaffold/bridges/date_picker/helper.rb +5 -5
- data/lib/active_scaffold/bridges/date_picker.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +5 -5
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -15
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +5 -5
- data/lib/active_scaffold/bridges.rb +0 -3
- data/lib/active_scaffold/constraints.rb +22 -7
- data/lib/active_scaffold/core.rb +5 -3
- data/lib/active_scaffold/data_structures/column.rb +108 -23
- data/lib/active_scaffold/engine.rb +15 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
- data/lib/active_scaffold/finder.rb +142 -27
- data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
- data/lib/active_scaffold/helpers/form_column_helpers.rb +114 -94
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
- data/lib/active_scaffold/helpers/list_column_helpers.rb +34 -18
- data/lib/active_scaffold/helpers/search_column_helpers.rb +131 -55
- data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
- data/lib/active_scaffold/orm_checks.rb +21 -1
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold.rb +3 -2
- data/test/bridges/date_picker_test.rb +3 -2
- data/test/bridges/paperclip_test.rb +3 -2
- data/test/bridges/tiny_mce_test.rb +4 -2
- data/test/helpers/form_column_helpers_test.rb +7 -5
- data/test/helpers/search_column_helpers_test.rb +2 -1
- data/test/misc/constraints_test.rb +1 -0
- data/test/misc/finder_test.rb +38 -0
- metadata +2 -6
- data/config/brakeman.ignore +0 -26
- data/config/brakeman.yml +0 -3
- data/config/i18n-tasks.yml +0 -121
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +0 -221
@@ -5,8 +5,13 @@ module ActiveScaffold
|
|
5
5
|
def get_column_value(record, column)
|
6
6
|
record = record.send(column.delegated_association.name) if column.delegated_association
|
7
7
|
if record
|
8
|
-
method = get_column_method(record, column)
|
9
|
-
value =
|
8
|
+
method, list_ui = get_column_method(record, column)
|
9
|
+
value =
|
10
|
+
if list_ui
|
11
|
+
send(method, record, column, ui_options: column.list_ui_options || column.options)
|
12
|
+
else
|
13
|
+
send(method, record, column)
|
14
|
+
end
|
10
15
|
else
|
11
16
|
value = nil
|
12
17
|
end
|
@@ -27,8 +32,8 @@ module ActiveScaffold
|
|
27
32
|
method
|
28
33
|
# second, check if the dev has specified a valid list_ui for this column
|
29
34
|
elsif column.list_ui && (method = override_column_ui(column.list_ui))
|
30
|
-
method
|
31
|
-
elsif column.column && (method = override_column_ui(column.
|
35
|
+
[method, true]
|
36
|
+
elsif column.column && (method = override_column_ui(column.column_type))
|
32
37
|
method
|
33
38
|
else
|
34
39
|
:format_column_value
|
@@ -76,39 +81,49 @@ module ActiveScaffold
|
|
76
81
|
##
|
77
82
|
## Overrides
|
78
83
|
##
|
79
|
-
def active_scaffold_column_text(record, column)
|
84
|
+
def active_scaffold_column_text(record, column, ui_options: column.options)
|
80
85
|
# `to_s` is necessary to convert objects in serialized columns to string before truncation.
|
81
|
-
clean_column_value(truncate(record.send(column.name).to_s, :
|
86
|
+
clean_column_value(truncate(record.send(column.name).to_s, length: ui_options[:truncate] || 50))
|
82
87
|
end
|
83
88
|
|
84
|
-
def active_scaffold_column_fulltext(record, column)
|
89
|
+
def active_scaffold_column_fulltext(record, column, ui_options: column.options)
|
85
90
|
clean_column_value(record.send(column.name))
|
86
91
|
end
|
87
92
|
|
88
|
-
def active_scaffold_column_marked(record, column)
|
93
|
+
def active_scaffold_column_marked(record, column, ui_options: column.options)
|
89
94
|
options = {:id => nil, :object => record}
|
90
95
|
content_tag(:span, check_box(:record, column.name, options), :class => 'in_place_editor_field', :data => {:ie_id => record.to_param})
|
91
96
|
end
|
92
97
|
|
93
|
-
def active_scaffold_column_checkbox(record, column)
|
98
|
+
def active_scaffold_column_checkbox(record, column, ui_options: column.options)
|
94
99
|
options = {:disabled => true, :id => nil, :object => record}
|
95
100
|
options.delete(:disabled) if inplace_edit?(record, column)
|
96
101
|
check_box(:record, column.name, options)
|
97
102
|
end
|
98
103
|
|
99
|
-
def
|
100
|
-
|
104
|
+
def active_scaffold_column_boolean(record, column, ui_options: column.options)
|
105
|
+
value = record.send(column.name)
|
106
|
+
if value.nil? && ui_options[:include_blank]
|
107
|
+
value = ui_options[:include_blank]
|
108
|
+
value.is_a?(Symbol) ? as_(value) : value
|
109
|
+
else
|
110
|
+
format_column_value(record, column, value)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def active_scaffold_column_percentage(record, column, ui_options: column.options)
|
115
|
+
options = ui_options[:slider] || {}
|
101
116
|
options = options.merge(min: record.send(options[:min_method])) if options[:min_method]
|
102
117
|
options = options.merge(max: record.send(options[:max_method])) if options[:max_method]
|
103
118
|
value = record.send(options[:value_method]) if options[:value_method]
|
104
119
|
as_slider options.merge(value: value || record.send(column.name))
|
105
120
|
end
|
106
121
|
|
107
|
-
def active_scaffold_column_month(record, column)
|
122
|
+
def active_scaffold_column_month(record, column, ui_options: column.options)
|
108
123
|
l record.send(column.name), format: :year_month
|
109
124
|
end
|
110
125
|
|
111
|
-
def active_scaffold_column_week(record, column)
|
126
|
+
def active_scaffold_column_week(record, column, ui_options: column.options)
|
112
127
|
l record.send(column.name), format: :week
|
113
128
|
end
|
114
129
|
|
@@ -119,10 +134,10 @@ module ActiveScaffold
|
|
119
134
|
link_to text, "tel:#{[groups.join('-'), extension].compact.join(',')}"
|
120
135
|
end
|
121
136
|
|
122
|
-
def active_scaffold_column_telephone(record, column)
|
137
|
+
def active_scaffold_column_telephone(record, column, ui_options: column.options)
|
123
138
|
phone = record.send column.name
|
124
139
|
return if phone.blank?
|
125
|
-
phone = number_to_phone(phone) unless
|
140
|
+
phone = number_to_phone(phone) unless ui_options[:format] == false
|
126
141
|
tel_to phone
|
127
142
|
end
|
128
143
|
|
@@ -147,8 +162,9 @@ module ActiveScaffold
|
|
147
162
|
def format_column_value(record, column, value = nil)
|
148
163
|
value ||= record.send(column.name) unless record.nil?
|
149
164
|
if column.association.nil?
|
150
|
-
if FORM_UI_WITH_OPTIONS.include?(column.form_ui)
|
151
|
-
|
165
|
+
form_ui_options = column.form_ui_options || column.options if FORM_UI_WITH_OPTIONS.include?(column.form_ui)
|
166
|
+
if form_ui_options&.dig(:options)
|
167
|
+
text, val = form_ui_options[:options].find { |t, v| (v.nil? ? t : v).to_s == value.to_s }
|
152
168
|
value = active_scaffold_translated_option(column, text, val).first if text
|
153
169
|
end
|
154
170
|
if grouped_search? && column == search_group_column && search_group_function
|
@@ -303,7 +319,7 @@ module ActiveScaffold
|
|
303
319
|
end
|
304
320
|
|
305
321
|
def inplace_edit_cloning?(column)
|
306
|
-
column.inplace_edit != :ajax && (override_form_field?(column) || column.form_ui || (column.column && override_input?(column.
|
322
|
+
column.inplace_edit != :ajax && (override_form_field?(column) || column.form_ui || (column.column && override_input?(column.column_type)))
|
307
323
|
end
|
308
324
|
|
309
325
|
def active_scaffold_inplace_edit_tag_options(record, column)
|
@@ -20,11 +20,11 @@ module ActiveScaffold
|
|
20
20
|
|
21
21
|
# second, check if the dev has specified a valid search_ui for this column, using specific ui for searches
|
22
22
|
elsif column.search_ui && (method = override_search(column.search_ui))
|
23
|
-
send(method, column, options)
|
23
|
+
send(method, column, options, ui_options: column.search_ui_options || column.options)
|
24
24
|
|
25
25
|
# third, check if the dev has specified a valid search_ui for this column, using generic ui for forms
|
26
26
|
elsif column.search_ui && (method = override_input(column.search_ui))
|
27
|
-
send(method, column, options)
|
27
|
+
send(method, column, options, ui_options: column.search_ui_options || column.options)
|
28
28
|
|
29
29
|
# fourth, check if the dev has created an override for this specific field
|
30
30
|
elsif (method = override_form_field(column))
|
@@ -34,11 +34,11 @@ module ActiveScaffold
|
|
34
34
|
elsif column.association || column.virtual?
|
35
35
|
active_scaffold_search_text(column, options)
|
36
36
|
|
37
|
-
elsif (method = override_search(column.
|
37
|
+
elsif (method = override_search(column.column_type))
|
38
38
|
# if we (or someone else) have created a custom render option for the column type, use that
|
39
39
|
send(method, column, options)
|
40
40
|
|
41
|
-
elsif (method = override_input(column.
|
41
|
+
elsif (method = override_input(column.column_type))
|
42
42
|
# if we (or someone else) have created a custom render option for the column type, use that
|
43
43
|
send(method, column, options)
|
44
44
|
|
@@ -73,28 +73,28 @@ module ActiveScaffold
|
|
73
73
|
## Search input methods
|
74
74
|
##
|
75
75
|
|
76
|
-
def active_scaffold_search_multi_select(column, options)
|
76
|
+
def active_scaffold_search_multi_select(column, options, ui_options: column.options)
|
77
77
|
record = options.delete(:object)
|
78
78
|
associated = options.delete :value
|
79
79
|
associated = [associated].compact unless associated.is_a? Array
|
80
80
|
|
81
81
|
if column.association
|
82
82
|
associated.collect!(&:to_i)
|
83
|
-
method =
|
83
|
+
method = ui_options[:label_method] || :to_label
|
84
84
|
select_options = sorted_association_options_find(column.association, nil, record).collect do |r|
|
85
85
|
[r.send(method), r.id]
|
86
86
|
end
|
87
87
|
else
|
88
|
-
select_options = column
|
88
|
+
select_options = active_scaffold_enum_options(column, record, ui_options: ui_options).collect do |text, value|
|
89
89
|
active_scaffold_translated_option(column, text, value)
|
90
90
|
end
|
91
91
|
end
|
92
92
|
return as_(:no_options) if select_options.empty?
|
93
93
|
|
94
|
-
active_scaffold_checkbox_list(column, select_options, associated, options)
|
94
|
+
active_scaffold_checkbox_list(column, select_options, associated, options, ui_options: ui_options)
|
95
95
|
end
|
96
96
|
|
97
|
-
def active_scaffold_search_select(column, html_options, options = {})
|
97
|
+
def active_scaffold_search_select(column, html_options, options = {}, ui_options: column.options)
|
98
98
|
record = html_options.delete(:object)
|
99
99
|
associated = html_options.delete :value
|
100
100
|
if column.association
|
@@ -103,13 +103,13 @@ module ActiveScaffold
|
|
103
103
|
select_options = sorted_association_options_find(column.association, false, record)
|
104
104
|
else
|
105
105
|
method = column.name
|
106
|
-
select_options = active_scaffold_enum_options(column, record).collect do |text, value|
|
106
|
+
select_options = active_scaffold_enum_options(column, record, ui_options: ui_options).collect do |text, value|
|
107
107
|
active_scaffold_translated_option(column, text, value)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
options = options.merge(:
|
112
|
-
html_options.merge!
|
111
|
+
options = options.merge(selected: associated).merge ui_options
|
112
|
+
html_options.merge! ui_options[:html_options] || {}
|
113
113
|
if html_options[:multiple]
|
114
114
|
active_scaffold_select_name_with_multiple html_options
|
115
115
|
else
|
@@ -120,23 +120,31 @@ module ActiveScaffold
|
|
120
120
|
if (optgroup = options.delete(:optgroup))
|
121
121
|
select(:record, method, active_scaffold_grouped_options(column, select_options, optgroup), options, html_options)
|
122
122
|
elsif column.association
|
123
|
-
collection_select(:record, method, select_options, :id,
|
123
|
+
collection_select(:record, method, select_options, :id, ui_options[:label_method] || :to_label, options, html_options)
|
124
124
|
else
|
125
125
|
select(:record, method, select_options, options, html_options)
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
def
|
129
|
+
def active_scaffold_search_select_multiple(column, options, ui_options: column.options)
|
130
|
+
active_scaffold_search_select(column, options.merge(multiple: true), ui_options: ui_options)
|
131
|
+
end
|
132
|
+
|
133
|
+
def active_scaffold_search_draggable(column, options, ui_options: column.options)
|
134
|
+
active_scaffold_search_multi_select(column, options.merge(draggable_lists: true), ui_options: ui_options)
|
135
|
+
end
|
136
|
+
|
137
|
+
def active_scaffold_search_text(column, options, ui_options: column.options)
|
130
138
|
text_field :record, column.name, active_scaffold_input_text_options(options)
|
131
139
|
end
|
132
140
|
|
133
141
|
# we can't use active_scaffold_input_boolean because we need to have a nil value even when column can't be null
|
134
142
|
# to decide whether search for this field or not
|
135
|
-
def active_scaffold_search_boolean(column, options)
|
143
|
+
def active_scaffold_search_boolean(column, options, ui_options: column.options)
|
136
144
|
select_options = []
|
137
145
|
select_options << [as_(:_select_), nil]
|
138
|
-
if column.
|
139
|
-
null_label =
|
146
|
+
if column.null?
|
147
|
+
null_label = ui_options[:include_blank] || :null
|
140
148
|
null_label = as_(null_label) if null_label.is_a?(Symbol)
|
141
149
|
select_options << [null_label, 'null']
|
142
150
|
end
|
@@ -168,7 +176,7 @@ module ActiveScaffold
|
|
168
176
|
end
|
169
177
|
end
|
170
178
|
|
171
|
-
def active_scaffold_search_null(column, options)
|
179
|
+
def active_scaffold_search_null(column, options, ui_options: column.options)
|
172
180
|
select_options = []
|
173
181
|
select_options << [as_(:_select_), nil]
|
174
182
|
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
@@ -185,38 +193,38 @@ module ActiveScaffold
|
|
185
193
|
column.text? || column.search_ui == :string
|
186
194
|
end
|
187
195
|
|
188
|
-
def active_scaffold_search_range_comparator_options(column)
|
196
|
+
def active_scaffold_search_range_comparator_options(column, ui_options: column.options)
|
189
197
|
select_options = ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
190
198
|
if active_scaffold_search_range_string?(column)
|
191
199
|
comparators = ActiveScaffold::Finder::STRING_COMPARATORS.collect { |title, comp| [as_(title), comp] }
|
192
200
|
select_options.unshift(*comparators)
|
193
201
|
end
|
194
|
-
if include_null_comparators? column
|
202
|
+
if include_null_comparators? column, ui_options: ui_options
|
195
203
|
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
196
204
|
end
|
197
205
|
select_options
|
198
206
|
end
|
199
207
|
|
200
|
-
def include_null_comparators?(column)
|
201
|
-
return
|
208
|
+
def include_null_comparators?(column, ui_options: column.options)
|
209
|
+
return ui_options[:null_comparators] if ui_options.key? :null_comparators
|
202
210
|
if column.association
|
203
|
-
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].
|
211
|
+
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].null?
|
204
212
|
else
|
205
|
-
column.
|
213
|
+
column.null?
|
206
214
|
end
|
207
215
|
end
|
208
216
|
|
209
|
-
def active_scaffold_search_range(column, options, input_method = :text_field_tag, input_options = {})
|
217
|
+
def active_scaffold_search_range(column, options, input_method = :text_field_tag, input_options = {}, ui_options: column.options)
|
210
218
|
opt_value, from_value, to_value = field_search_params_range_values(column)
|
211
219
|
|
212
|
-
select_options = active_scaffold_search_range_comparator_options(column)
|
220
|
+
select_options = active_scaffold_search_range_comparator_options(column, ui_options: ui_options)
|
213
221
|
text_field_size = active_scaffold_search_range_string?(column) ? 15 : 10
|
214
222
|
opt_value ||= select_options[0][1]
|
215
223
|
|
216
224
|
from_value = controller.class.condition_value_for_numeric(column, from_value)
|
217
225
|
to_value = controller.class.condition_value_for_numeric(column, to_value)
|
218
|
-
from_value = format_number_value(from_value,
|
219
|
-
to_value = format_number_value(to_value,
|
226
|
+
from_value = format_number_value(from_value, ui_options) if from_value.is_a?(Numeric)
|
227
|
+
to_value = format_number_value(to_value, ui_options) if to_value.is_a?(Numeric)
|
220
228
|
html = select_tag("#{options[:name]}[opt]", options_for_select(select_options, opt_value),
|
221
229
|
:id => "#{options[:id]}_opt", :class => 'as_search_range_option')
|
222
230
|
from_options = active_scaffold_input_text_options(input_options.merge(:id => options[:id], :size => text_field_size))
|
@@ -233,51 +241,119 @@ module ActiveScaffold
|
|
233
241
|
end
|
234
242
|
alias active_scaffold_search_string active_scaffold_search_range
|
235
243
|
|
236
|
-
def active_scaffold_search_integer(column, options)
|
237
|
-
active_scaffold_search_range(column, options, :number_field_tag, step: '1')
|
244
|
+
def active_scaffold_search_integer(column, options, ui_options: column.options)
|
245
|
+
active_scaffold_search_range(column, options, :number_field_tag, {step: '1'}, ui_options: ui_options) # rubocop:disable Style/BracesAroundHashParameters
|
238
246
|
end
|
239
247
|
|
240
|
-
def active_scaffold_search_decimal(column, options)
|
241
|
-
active_scaffold_search_range(column, options, :number_field_tag, step: :any)
|
248
|
+
def active_scaffold_search_decimal(column, options, ui_options: column.options)
|
249
|
+
active_scaffold_search_range(column, options, :number_field_tag, {step: :any}, ui_options: ui_options) # rubocop:disable Style/BracesAroundHashParameters
|
242
250
|
end
|
243
251
|
alias active_scaffold_search_float active_scaffold_search_decimal
|
244
252
|
|
253
|
+
def active_scaffold_search_datetime(column, options, ui_options: column.options, field_ui: column.search_ui || :datetime)
|
254
|
+
current_search = {'from' => nil, 'to' => nil, 'opt' => 'BETWEEN',
|
255
|
+
'number' => 1, 'unit' => 'DAYS', 'range' => nil}
|
256
|
+
current_search.merge!(options[:value]) unless options[:value].nil?
|
257
|
+
tags = [
|
258
|
+
active_scaffold_search_datetime_comparator_tag(column, options, current_search),
|
259
|
+
active_scaffold_search_datetime_trend_tag(column, options, current_search),
|
260
|
+
active_scaffold_search_datetime_numeric_tag(column, options, current_search, ui_options: ui_options, field_ui: field_ui),
|
261
|
+
active_scaffold_search_datetime_range_tag(column, options, current_search)
|
262
|
+
]
|
263
|
+
safe_join tags, ' '.html_safe # rubocop:disable Rails/OutputSafety
|
264
|
+
end
|
265
|
+
|
266
|
+
def active_scaffold_search_timestamp(column, options, ui_options: column.options)
|
267
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :datetime)
|
268
|
+
end
|
269
|
+
|
270
|
+
def active_scaffold_search_time(column, options, ui_options: column.options)
|
271
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :time)
|
272
|
+
end
|
273
|
+
|
274
|
+
def active_scaffold_search_date(column, options, ui_options: column.options)
|
275
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :date)
|
276
|
+
end
|
277
|
+
|
278
|
+
def active_scaffold_search_datetime_comparator_options(column)
|
279
|
+
select_options = ActiveScaffold::Finder::DATE_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
280
|
+
select_options + ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
281
|
+
end
|
282
|
+
|
283
|
+
def active_scaffold_search_datetime_comparator_tag(column, options, current_search)
|
284
|
+
choices = options_for_select(active_scaffold_search_datetime_comparator_options(column), current_search['opt'])
|
285
|
+
select_tag("#{options[:name]}[opt]", choices, id: "#{options[:id]}_opt", class: 'as_search_range_option as_search_date_time_option')
|
286
|
+
end
|
287
|
+
|
288
|
+
def active_scaffold_search_datetime_numeric_tag(column, options, current_search, ui_options: column.options, field_ui: column.search_ui)
|
289
|
+
helper = "active_scaffold_search_#{field_ui}_field"
|
290
|
+
numeric_controls = [
|
291
|
+
send(helper, column, options, current_search, 'from', ui_options: ui_options),
|
292
|
+
content_tag(:span, id: "#{options[:id]}_between", class: 'as_search_range_between',
|
293
|
+
style: ('display: none' unless current_search['opt'] == 'BETWEEN')) do
|
294
|
+
safe_join([' - ', send(helper, column, options, current_search, 'to', ui_options: ui_options)])
|
295
|
+
end
|
296
|
+
]
|
297
|
+
content_tag('span', safe_join(numeric_controls),
|
298
|
+
:id => "#{options[:id]}_numeric", :class => 'search-date-numeric',
|
299
|
+
:style => ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(current_search['opt']) ? nil : 'display: none')
|
300
|
+
end
|
301
|
+
|
302
|
+
def active_scaffold_search_datetime_trend_tag(column, options, current_search)
|
303
|
+
trend_controls = [
|
304
|
+
text_field_tag("#{options[:name]}[number]", current_search['number'], class: 'text-input', size: 10, autocomplete: 'off'),
|
305
|
+
select_tag("#{options[:name]}[unit]",
|
306
|
+
options_for_select(active_scaffold_search_datetime_trend_units(column), current_search['unit']),
|
307
|
+
class: 'text-input')
|
308
|
+
]
|
309
|
+
content_tag('span', safe_join(trend_controls, ' '),
|
310
|
+
id: "#{options[:id]}_trend", class: 'search-date-trend',
|
311
|
+
style: ('display: none' unless current_search['opt'] == 'PAST' || current_search['opt'] == 'FUTURE'))
|
312
|
+
end
|
313
|
+
|
314
|
+
def active_scaffold_search_datetime_trend_units(column)
|
315
|
+
options = ActiveScaffold::Finder::DATE_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] }
|
316
|
+
options = ActiveScaffold::Finder::TIME_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] } + options if column_datetime?(column)
|
317
|
+
options
|
318
|
+
end
|
319
|
+
|
320
|
+
def active_scaffold_search_datetime_range_tag(column, options, current_search)
|
321
|
+
values = ActiveScaffold::Finder::DATE_RANGES.collect { |range| [as_(range.downcase.to_sym), range] }
|
322
|
+
range_controls = select_tag("#{options[:name]}[range]",
|
323
|
+
options_for_select(values, current_search['range']),
|
324
|
+
class: 'text-input', id: nil)
|
325
|
+
content_tag('span', range_controls,
|
326
|
+
id: "#{options[:id]}_range", class: 'search-date-range',
|
327
|
+
style: ('display: none' unless current_search['opt'] == 'RANGE'))
|
328
|
+
end
|
329
|
+
|
330
|
+
def column_datetime?(column)
|
331
|
+
(!column.column.nil? && %i[datetime time].include?(column.column_type))
|
332
|
+
end
|
333
|
+
|
245
334
|
def field_search_datetime_value(value)
|
246
335
|
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?
|
247
336
|
end
|
248
337
|
|
249
|
-
def
|
250
|
-
|
251
|
-
options = column.options.merge(options)
|
338
|
+
def active_scaffold_search_datetime_field(column, options, current_search, name, ui_options: column.options)
|
339
|
+
options = ui_options.merge(options)
|
252
340
|
type = "#{'date' unless options[:discard_date]}#{'time' unless options[:discard_time]}"
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
if use_select
|
257
|
-
helper = "select_#{type}"
|
258
|
-
fields = [
|
259
|
-
send(helper, field_search_datetime_value(from_value), options.reverse_merge(include_blank: true, prefix: from_name)),
|
260
|
-
send(helper, field_search_datetime_value(to_value), options.reverse_merge(include_blank: true, prefix: to_name))
|
261
|
-
]
|
341
|
+
field_name = "#{options[:name]}[#{name}]"
|
342
|
+
if options[:use_select]
|
343
|
+
send("select_#{type}", current_search[name], options.reverse_merge(include_blank: true, prefix: field_name))
|
262
344
|
else
|
263
345
|
helper = "#{type}#{'_local' if type == 'datetime'}_field_tag"
|
264
|
-
|
265
|
-
send(helper, from_name, field_search_datetime_value(from_value), options.except(:name, :object).merge(id: "#{options[:id]}_from")),
|
266
|
-
send(helper, to_name, field_search_datetime_value(to_value), options.except(:name, :object).merge(id: "#{options[:id]}_to"))
|
267
|
-
]
|
346
|
+
send(helper, field_name, current_search[name], options.except(:name, :object, :use_select).merge(id: "#{options[:id]}_#{name}"))
|
268
347
|
end
|
269
|
-
|
270
|
-
safe_join fields, ' - '
|
271
348
|
end
|
272
349
|
|
273
|
-
def
|
274
|
-
|
350
|
+
def active_scaffold_search_date_field(column, options, current_search, name, ui_options: column.options)
|
351
|
+
active_scaffold_search_datetime_field(column, options.merge!(:discard_time => true), current_search, name, ui_options: ui_options)
|
275
352
|
end
|
276
353
|
|
277
|
-
def
|
278
|
-
|
354
|
+
def active_scaffold_search_time_field(column, options, current_search, name, ui_options: column.options)
|
355
|
+
active_scaffold_search_datetime_field(column, options.merge!(:discard_date => true), current_search, name, ui_options: ui_options)
|
279
356
|
end
|
280
|
-
alias active_scaffold_search_timestamp active_scaffold_search_datetime
|
281
357
|
|
282
358
|
##
|
283
359
|
## Search column override signatures
|
@@ -13,24 +13,24 @@ module ActiveScaffold
|
|
13
13
|
send(method, value_record, column)
|
14
14
|
# second, check if the dev has specified a valid list_ui for this column
|
15
15
|
elsif column.show_ui && (method = override_show_column_ui(column.show_ui))
|
16
|
-
send(method, value_record, column)
|
17
|
-
elsif column.column && (method = override_show_column_ui(column.
|
16
|
+
send(method, value_record, column, ui_options: column.show_ui_options || column.options)
|
17
|
+
elsif column.column && (method = override_show_column_ui(column.column_type))
|
18
18
|
send(method, value_record, column)
|
19
19
|
else
|
20
20
|
get_column_value(record, column)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def active_scaffold_show_text(record, column)
|
25
|
-
simple_format(clean_column_value(record.send(column.name)))
|
24
|
+
def active_scaffold_show_text(record, column, ui_options: column.options)
|
25
|
+
simple_format(clean_column_value(record.send(column.name)), ui_options[:html_options], ui_options)
|
26
26
|
end
|
27
27
|
|
28
|
-
def active_scaffold_show_horizontal(record, column)
|
28
|
+
def active_scaffold_show_horizontal(record, column, ui_options: column.options)
|
29
29
|
raise ':horizontal show_ui must be used on association column' unless column.association
|
30
30
|
render :partial => 'show_association', :locals => {:column => column, :parent_record => record, :show_partial => :horizontal}
|
31
31
|
end
|
32
32
|
|
33
|
-
def active_scaffold_show_vertical(record, column)
|
33
|
+
def active_scaffold_show_vertical(record, column, ui_options: column.options)
|
34
34
|
raise ':vertical show_ui must be used on association column' unless column.association
|
35
35
|
render :partial => 'show_association', :locals => {:column => column, :parent_record => record, :show_partial => :vertical}
|
36
36
|
end
|
@@ -82,6 +82,22 @@ module ActiveScaffold
|
|
82
82
|
type_for_attribute(klass, column_name)
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
def default_value(klass, column_name)
|
87
|
+
if ActiveScaffold::OrmChecks.mongoid? klass
|
88
|
+
columns_hash(klass)[column_name]&.default_val
|
89
|
+
elsif ActiveScaffold::OrmChecks.active_record? klass
|
90
|
+
klass._default_attributes[column_name]&.value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def cast(klass, column_name, value)
|
95
|
+
if active_record? klass
|
96
|
+
type_for_attribute(klass, column_name).cast value
|
97
|
+
elsif mongoid? klass
|
98
|
+
type_for_attribute(klass, column_name)&.evolve value
|
99
|
+
end
|
100
|
+
end
|
85
101
|
end
|
86
102
|
|
87
103
|
%i[active_record? mongoid? tableless?].each do |method|
|
@@ -96,10 +112,14 @@ module ActiveScaffold
|
|
96
112
|
end
|
97
113
|
end
|
98
114
|
|
99
|
-
%i[type_for_attribute column_type].each do |method|
|
115
|
+
%i[type_for_attribute column_type default_value].each do |method|
|
100
116
|
define_method method do |column_name|
|
101
117
|
ActiveScaffold::OrmChecks.send method, active_record_class, column_name
|
102
118
|
end
|
103
119
|
end
|
120
|
+
|
121
|
+
def cast(column_name, value)
|
122
|
+
ActiveScaffold::OrmChecks.cast active_record_class, column_name, value
|
123
|
+
end
|
104
124
|
end
|
105
125
|
end
|
data/lib/active_scaffold.rb
CHANGED
@@ -3,6 +3,7 @@ module ActiveScaffold
|
|
3
3
|
autoload :AttributeParams, 'active_scaffold/attribute_params'
|
4
4
|
autoload :Bridges, 'active_scaffold/bridges'
|
5
5
|
autoload :Configurable, 'active_scaffold/configurable'
|
6
|
+
autoload :ConnectionAdapters, 'active_scaffold/extensions/connection_adapter.rb'
|
6
7
|
autoload :Constraints, 'active_scaffold/constraints'
|
7
8
|
autoload :Core, 'active_scaffold/core'
|
8
9
|
autoload :Finder, 'active_scaffold/finder'
|
@@ -78,6 +79,8 @@ module ActiveScaffold
|
|
78
79
|
@@exclude_bridges ||= []
|
79
80
|
end
|
80
81
|
|
82
|
+
mattr_accessor :nested_subforms, instance_writer: false
|
83
|
+
|
81
84
|
def self.root
|
82
85
|
File.dirname(__FILE__) + '/..'
|
83
86
|
end
|
@@ -90,5 +93,3 @@ require 'active_scaffold/engine'
|
|
90
93
|
require 'ice_nine'
|
91
94
|
require 'ice_nine/core_ext/object'
|
92
95
|
require 'request_store'
|
93
|
-
# TODO: clean up extensions. some could be organized for autoloading, and others could be removed entirely.
|
94
|
-
Dir["#{File.dirname __FILE__}/active_scaffold/extensions/*.rb"].each { |file| require file }
|
@@ -24,7 +24,8 @@ class DatePickerTest < ActionView::TestCase
|
|
24
24
|
def test_form_ui
|
25
25
|
config = ActiveScaffold::Config::Core.new(:company)
|
26
26
|
@record = Company.new
|
27
|
-
|
28
|
-
assert active_scaffold_input_date_picker(config.columns[:
|
27
|
+
opts = {object: @record}
|
28
|
+
assert active_scaffold_input_date_picker(config.columns[:date], opts.merge(id: 'record_date', name: 'record[date]'))
|
29
|
+
assert active_scaffold_input_date_picker(config.columns[:datetime], opts.merge(id: 'record_date', name: 'record[datetime]'))
|
29
30
|
end
|
30
31
|
end
|
@@ -58,11 +58,12 @@ class PaperclipTest < ActionView::TestCase
|
|
58
58
|
with_js_framework :jquery do
|
59
59
|
config = PaperclipCore.new(:company)
|
60
60
|
@record = Company.new
|
61
|
+
opts = {name: 'record[logo]', id: 'record_logo', object: @record}
|
61
62
|
|
62
63
|
@record.stubs(:logo).returns(stub(:file? => true, :original_filename => 'file', :url => '/system/file', :styles => Company.attachment_definitions[:logo]))
|
63
64
|
click_js = "jQuery(this).prev().val('true'); jQuery(this).parent().hide().next().show(); return false;"
|
64
65
|
change_js = "jQuery(this).parents('div.paperclip_controls').find('input.remove_file').val('false'); return false;"
|
65
|
-
@document = Nokogiri::HTML::Document.parse(active_scaffold_input_paperclip(config.columns[:logo],
|
66
|
+
@document = Nokogiri::HTML::Document.parse(active_scaffold_input_paperclip(config.columns[:logo], opts))
|
66
67
|
assert_select 'div.paperclip_controls input[type=file]' do |match|
|
67
68
|
assert_equal match[0]['onchange'], change_js
|
68
69
|
end
|
@@ -72,7 +73,7 @@ class PaperclipTest < ActionView::TestCase
|
|
72
73
|
assert_select 'div.paperclip_controls input.remove_file[type=hidden][value=false]'
|
73
74
|
|
74
75
|
@record.stubs(:logo).returns(stub(:file? => false))
|
75
|
-
assert_dom_equal '<input name="record[logo]" class="text-input" autocomplete="off" type="file" id="record_logo" />', active_scaffold_input_paperclip(config.columns[:logo],
|
76
|
+
assert_dom_equal '<input name="record[logo]" class="text-input" autocomplete="off" type="file" id="record_logo" />', active_scaffold_input_paperclip(config.columns[:logo], opts)
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
@@ -35,16 +35,18 @@ class TinyMceTest < ActionView::TestCase
|
|
35
35
|
def test_form_ui
|
36
36
|
config = ActiveScaffold::Config::Core.new(:company)
|
37
37
|
record = Company.new
|
38
|
+
opts = {name: 'record[name]', id: 'record_name', class: 'name-input', object: record}
|
38
39
|
|
39
|
-
assert_dom_equal %(<textarea name=\"record[name]\" class=\"name-input mceEditor\" id=\"record_name\" data-tinymce=\"{"theme":"modern"}\">\n</textarea>), active_scaffold_input_text_editor(config.columns[:name],
|
40
|
+
assert_dom_equal %(<textarea name=\"record[name]\" class=\"name-input mceEditor\" id=\"record_name\" data-tinymce=\"{"theme":"modern"}\">\n</textarea>), active_scaffold_input_text_editor(config.columns[:name], opts)
|
40
41
|
end
|
41
42
|
|
42
43
|
def test_form_ui_alternate
|
43
44
|
config = ActiveScaffold::Config::Core.new(:company)
|
44
45
|
record = Company.new
|
45
46
|
config.columns[:name].options[:tinymce_config] = :alternate
|
47
|
+
opts = {name: 'record[name]', id: 'record_name', class: 'name-input', object: record}
|
46
48
|
|
47
|
-
assert_dom_equal %(<textarea name=\"record[name]\" class=\"name-input mceEditor\" id=\"record_name\" data-tinymce=\"{"theme":"alternate","toolbar":"undo redo | format"}\">\n</textarea>), active_scaffold_input_tinymce(config.columns[:name],
|
49
|
+
assert_dom_equal %(<textarea name=\"record[name]\" class=\"name-input mceEditor\" id=\"record_name\" data-tinymce=\"{"theme":"alternate","toolbar":"undo redo | format"}\">\n</textarea>), active_scaffold_input_tinymce(config.columns[:name], opts)
|
48
50
|
end
|
49
51
|
|
50
52
|
protected
|
@@ -9,23 +9,25 @@ class FormColumnHelpersTest < ActionView::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_choices_for_select_form_ui_for_simple_column
|
12
|
+
opts = {object: @record}
|
12
13
|
@column.options[:options] = %i[value_1 value_2 value_3]
|
13
|
-
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">Value 1</option>\n<option value=\"value_2\">Value 2</option>\n<option value=\"value_3\">Value 3</option></select>", active_scaffold_input_select(@column,
|
14
|
+
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">Value 1</option>\n<option value=\"value_2\">Value 2</option>\n<option value=\"value_3\">Value 3</option></select>", active_scaffold_input_select(@column, opts.dup)
|
14
15
|
|
15
16
|
@column.options[:options] = %w[value_1 value_2 value_3]
|
16
|
-
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">value_1</option>\n<option value=\"value_2\">value_2</option>\n<option value=\"value_3\">value_3</option></select>", active_scaffold_input_select(@column,
|
17
|
+
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">value_1</option>\n<option value=\"value_2\">value_2</option>\n<option value=\"value_3\">value_3</option></select>", active_scaffold_input_select(@column, opts.dup)
|
17
18
|
|
18
19
|
@column.options[:options] = [%w[text_1 value_1], %w[text_2 value_2], %w[text_3 value_3]]
|
19
|
-
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">text_1</option>\n<option value=\"value_2\">text_2</option>\n<option value=\"value_3\">text_3</option></select>", active_scaffold_input_select(@column,
|
20
|
+
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">text_1</option>\n<option value=\"value_2\">text_2</option>\n<option value=\"value_3\">text_3</option></select>", active_scaffold_input_select(@column, opts.dup)
|
20
21
|
|
21
22
|
@column.options[:options] = [%i[text_1 value_1], %i[text_2 value_2], %i[text_3 value_3]]
|
22
|
-
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">Text 1</option>\n<option value=\"value_2\">Text 2</option>\n<option value=\"value_3\">Text 3</option></select>", active_scaffold_input_select(@column,
|
23
|
+
assert_dom_equal "<select name=\"record[a]\" id=\"record_a\"><option value=\"value_1\">Text 1</option>\n<option value=\"value_2\">Text 2</option>\n<option value=\"value_3\">Text 3</option></select>", active_scaffold_input_select(@column, opts.dup)
|
23
24
|
end
|
24
25
|
|
25
26
|
def test_options_for_select_form_ui_for_simple_column
|
27
|
+
opts = {object: @record}
|
26
28
|
@column.options = {:include_blank => 'None', :selected => 'value_2', :disabled => %w[value_1 value_3]}
|
27
29
|
@column.options[:options] = %w[value_1 value_2 value_3]
|
28
30
|
@column.options[:html_options] = {:class => 'big'}
|
29
|
-
assert_dom_equal "<select name=\"record[a]\" class=\"big\" id=\"record_a\"><option value=\"\">None</option>\n<option disabled=\"disabled\" value=\"value_1\">value_1</option>\n<option selected=\"selected\" value=\"value_2\">value_2</option>\n<option disabled=\"disabled\" value=\"value_3\">value_3</option></select>", active_scaffold_input_select(@column,
|
31
|
+
assert_dom_equal "<select name=\"record[a]\" class=\"big\" id=\"record_a\"><option value=\"\">None</option>\n<option disabled=\"disabled\" value=\"value_1\">value_1</option>\n<option selected=\"selected\" value=\"value_2\">value_2</option>\n<option disabled=\"disabled\" value=\"value_3\">value_3</option></select>", active_scaffold_input_select(@column, opts)
|
30
32
|
end
|
31
33
|
end
|