active_scaffold 3.6.20 → 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 +47 -0
- data/README.md +29 -16
- data/app/assets/javascripts/jquery/active_scaffold.js +106 -68
- data/app/assets/javascripts/jquery/active_scaffold_chosen.js +6 -5
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +18 -4
- data/app/assets/stylesheets/active_scaffold_layout.css +13 -2
- data/app/views/active_scaffold_overrides/_base_form.html.erb +5 -1
- data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +24 -13
- 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 +83 -80
- data/config/locales/ru.yml +17 -14
- data/lib/active_scaffold/actions/common_search.rb +2 -2
- data/lib/active_scaffold/actions/core.rb +30 -10
- data/lib/active_scaffold/actions/field_search.rb +9 -6
- data/lib/active_scaffold/actions/nested.rb +7 -7
- data/lib/active_scaffold/actions/update.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +22 -70
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +0 -3
- 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/active_storage.rb +3 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/bitfields/bitfields_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 +9 -9
- 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/paper_trail/actions.rb +4 -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 +17 -17
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
- data/lib/active_scaffold/bridges/tiny_mce.rb +1 -1
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +6 -11
- data/lib/active_scaffold/bridges.rb +0 -3
- data/lib/active_scaffold/config/core.rb +1 -1
- data/lib/active_scaffold/config/field_search.rb +9 -1
- data/lib/active_scaffold/config/form.rb +9 -1
- data/lib/active_scaffold/constraints.rb +22 -7
- data/lib/active_scaffold/core.rb +6 -10
- data/lib/active_scaffold/data_structures/action_columns.rb +0 -25
- data/lib/active_scaffold/data_structures/action_links.rb +1 -1
- data/lib/active_scaffold/data_structures/association/abstract.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +1 -13
- data/lib/active_scaffold/data_structures/association/mongoid.rb +21 -8
- data/lib/active_scaffold/data_structures/column.rb +139 -28
- data/lib/active_scaffold/data_structures/columns.rb +12 -12
- data/lib/active_scaffold/data_structures/nested_info.rb +12 -0
- data/lib/active_scaffold/data_structures/sorting.rb +1 -1
- data/lib/active_scaffold/engine.rb +15 -1
- data/lib/active_scaffold/extensions/action_view_rendering.rb +13 -5
- data/lib/active_scaffold/extensions/cow_proxy.rb +1 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
- data/lib/active_scaffold/extensions/unsaved_record.rb +9 -3
- data/lib/active_scaffold/finder.rb +147 -28
- data/lib/active_scaffold/helpers/action_link_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
- data/lib/active_scaffold/helpers/form_column_helpers.rb +153 -107
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
- data/lib/active_scaffold/helpers/list_column_helpers.rb +37 -20
- data/lib/active_scaffold/helpers/search_column_helpers.rb +137 -55
- data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/orm_checks.rb +21 -1
- data/lib/active_scaffold/registry.rb +10 -15
- data/lib/active_scaffold/tableless.rb +10 -79
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/active_scaffold.rb +3 -9
- data/lib/generators/active_scaffold/install_generator.rb +2 -2
- data/test/bridges/bridge_test.rb +1 -1
- data/test/bridges/date_picker_test.rb +3 -2
- data/test/bridges/paperclip_test.rb +18 -14
- data/test/bridges/tiny_mce_test.rb +5 -3
- data/test/config/base_test.rb +1 -1
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/delete_test.rb +1 -1
- data/test/config/field_search_test.rb +1 -1
- data/test/config/list_test.rb +1 -1
- data/test/config/nested_test.rb +1 -1
- data/test/config/search_test.rb +1 -1
- data/test/config/show_test.rb +1 -1
- data/test/config/subform_test.rb +1 -1
- data/test/config/update_test.rb +1 -1
- data/test/data_structures/action_columns_test.rb +1 -1
- data/test/data_structures/action_link_test.rb +1 -1
- data/test/data_structures/action_links_test.rb +1 -1
- data/test/data_structures/actions_test.rb +1 -1
- data/test/data_structures/association_column_test.rb +1 -1
- data/test/data_structures/column_test.rb +1 -1
- data/test/data_structures/columns_test.rb +1 -1
- data/test/data_structures/set_test.rb +1 -1
- data/test/data_structures/sorting_test.rb +1 -1
- data/test/data_structures/standard_column_test.rb +1 -1
- data/test/data_structures/validation_reflection_test.rb +1 -1
- data/test/data_structures/virtual_column_test.rb +1 -1
- data/test/extensions/active_record_test.rb +1 -1
- data/test/helpers/form_column_helpers_test.rb +7 -5
- data/test/helpers/pagination_helpers_test.rb +1 -1
- data/test/helpers/search_column_helpers_test.rb +2 -1
- data/test/misc/active_record_permissions_test.rb +1 -1
- data/test/misc/attribute_params_test.rb +1 -1
- data/test/misc/calculation_test.rb +1 -1
- data/test/misc/configurable_test.rb +1 -1
- data/test/misc/constraints_test.rb +2 -1
- data/test/misc/convert_numbers_format_test.rb +1 -1
- data/test/misc/finder_test.rb +39 -1
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/parse_datetime_test.rb +1 -1
- data/test/misc/tableless_test.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +5 -17
- 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
- data/lib/active_scaffold/delayed_setup.rb +0 -41
- data/lib/active_scaffold/extensions/left_outer_joins.rb +0 -43
@@ -19,7 +19,7 @@ module ActiveScaffold
|
|
19
19
|
|
20
20
|
# second, check if the dev has specified a valid form_ui for this column
|
21
21
|
elsif column.form_ui && (method = override_input(column.form_ui))
|
22
|
-
send(method, column, options)
|
22
|
+
send(method, column, options, ui_options: (column.form_ui_options || column.options).except(:collapsible))
|
23
23
|
|
24
24
|
elsif column.association
|
25
25
|
# if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about.
|
@@ -32,16 +32,15 @@ module ActiveScaffold
|
|
32
32
|
options[:value] = format_number_value(record.send(column.name), column.options) if column.number?
|
33
33
|
active_scaffold_input_virtual(column, options)
|
34
34
|
|
35
|
-
elsif (method = override_input(column.
|
35
|
+
elsif (method = override_input(column.column_type)) # regular model attribute column
|
36
36
|
# if we (or someone else) have created a custom render option for the column type, use that
|
37
37
|
send(method, column, options)
|
38
38
|
|
39
39
|
else # final ultimate fallback: use rails' generic input method
|
40
40
|
# for textual fields we pass different options
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
options[:maxlength] = column.column.limit
|
41
|
+
options = active_scaffold_input_text_options(options) if column.text? || column.number?
|
42
|
+
if column.column_type == :string && options[:maxlength].blank?
|
43
|
+
options[:maxlength] = column.type_for_attribute.limit
|
45
44
|
options[:size] ||= options[:maxlength].to_i > 30 ? 30 : options[:maxlength]
|
46
45
|
end
|
47
46
|
options[:value] = format_number_value(record.send(column.name), column.options) if column.number?
|
@@ -107,7 +106,11 @@ module ActiveScaffold
|
|
107
106
|
classes = "#{column.name}-input"
|
108
107
|
classes += ' numeric-input' if column.number?
|
109
108
|
|
110
|
-
|
109
|
+
if (column.form_ui_options || column.options)[:collapsible]
|
110
|
+
collapsible_id = "container_#{id_control}"
|
111
|
+
end
|
112
|
+
|
113
|
+
{name: name, class: classes, id: id_control, collapsible_id: collapsible_id}.merge(options)
|
111
114
|
end
|
112
115
|
|
113
116
|
def current_form_columns(record, scope, subform_controller = nil)
|
@@ -120,15 +123,15 @@ module ActiveScaffold
|
|
120
123
|
end
|
121
124
|
end
|
122
125
|
|
123
|
-
def update_columns_options(column, scope, options, force = false)
|
126
|
+
def update_columns_options(column, scope, options, force = false, form_columns: nil, url_params: {})
|
124
127
|
record = options[:object]
|
125
128
|
subform_controller = controller.class.active_scaffold_controller_for(record.class) if scope
|
126
129
|
if @main_columns && (scope.nil? || subform_controller == controller.class)
|
127
|
-
form_columns
|
130
|
+
form_columns ||= @main_columns.visible_columns_names
|
128
131
|
end
|
129
132
|
form_columns ||= current_form_columns(record, scope, subform_controller)
|
130
133
|
if force || (form_columns && column.update_columns && (column.update_columns & form_columns).present?)
|
131
|
-
url_params
|
134
|
+
url_params.reverse_merge! params_for(action: 'render_field', column: column.name, id: record.to_param)
|
132
135
|
if nested? && scope
|
133
136
|
url_params[:nested] = url_params.slice(:parent_scaffold, :association, nested.param_name)
|
134
137
|
url_params = url_params.except(:parent_scaffold, :association, nested.param_name)
|
@@ -153,7 +156,14 @@ module ActiveScaffold
|
|
153
156
|
end
|
154
157
|
|
155
158
|
def render_column(column, record, renders_as, scope = nil, only_value = false, col_class = nil) # rubocop:disable Metrics/ParameterLists
|
156
|
-
if (
|
159
|
+
if form_column_is_hidden?(column, record, scope)
|
160
|
+
# creates an element that can be replaced by the update_columns routine,
|
161
|
+
# but will not affect the value of the submitted form in this state:
|
162
|
+
# <dl><input type="hidden" class="<%= column.name %>-input"></dl>
|
163
|
+
content_tag :dl, style: 'display: none' do
|
164
|
+
hidden_field_tag(nil, nil, :class => "#{column.name}-input")
|
165
|
+
end
|
166
|
+
elsif (partial = override_form_field_partial(column))
|
157
167
|
render :partial => partial, :locals => {:column => column, :only_value => only_value, :scope => scope, :col_class => col_class, :record => record}
|
158
168
|
elsif renders_as == :field || override_form_field?(column)
|
159
169
|
form_attribute(column, record, scope, only_value, col_class)
|
@@ -164,8 +174,19 @@ module ActiveScaffold
|
|
164
174
|
end
|
165
175
|
end
|
166
176
|
|
177
|
+
def form_column_is_hidden?(column, record, scope = nil)
|
178
|
+
if column.hide_form_column_if&.respond_to?(:call)
|
179
|
+
column.hide_form_column_if.call(record, column, scope)
|
180
|
+
elsif column.hide_form_column_if&.is_a?(Symbol)
|
181
|
+
record.send(column.hide_form_column_if)
|
182
|
+
else
|
183
|
+
column.hide_form_column_if
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
167
187
|
def form_attribute(column, record, scope = nil, only_value = false, col_class = nil)
|
168
188
|
column_options = active_scaffold_input_options(column, scope, :object => record)
|
189
|
+
collapsible_id = column_options.delete :collapsible_id
|
169
190
|
attributes = field_attributes(column, record)
|
170
191
|
attributes[:class] = "#{attributes[:class]} #{col_class}" if col_class.present?
|
171
192
|
if only_value
|
@@ -181,12 +202,14 @@ module ActiveScaffold
|
|
181
202
|
end
|
182
203
|
if field
|
183
204
|
field << loading_indicator_tag(:action => :render_field, :id => params[:id]) if column.update_columns
|
184
|
-
|
205
|
+
desc = column.description(record, scope)
|
206
|
+
field << content_tag(:span, desc, :class => 'description') if desc.present?
|
185
207
|
end
|
186
208
|
|
209
|
+
label = label_tag(label_for(column, column_options), form_column_label(column, record, scope))
|
210
|
+
label << h(' ') << link_to_visibility_toggle(collapsible_id) if collapsible_id
|
187
211
|
content_tag :dl, attributes do
|
188
|
-
content_tag(:dt,
|
189
|
-
content_tag(:dd, field)
|
212
|
+
content_tag(:dt, label) << content_tag(:dd, field, id: collapsible_id)
|
190
213
|
end
|
191
214
|
end
|
192
215
|
|
@@ -194,8 +217,8 @@ module ActiveScaffold
|
|
194
217
|
options[:id] unless column.form_ui == :select && column.association&.collection?
|
195
218
|
end
|
196
219
|
|
197
|
-
def form_column_label(column)
|
198
|
-
column.label
|
220
|
+
def form_column_label(column, record = nil, scope = nil)
|
221
|
+
column.label(record, scope)
|
199
222
|
end
|
200
223
|
|
201
224
|
def subform_label(column, hidden)
|
@@ -286,7 +309,7 @@ module ActiveScaffold
|
|
286
309
|
options[:name] = "#{options[:name]}[]"
|
287
310
|
end
|
288
311
|
|
289
|
-
def active_scaffold_input_singular_association(column, html_options, options = {})
|
312
|
+
def active_scaffold_input_singular_association(column, html_options, options = {}, ui_options: column.options)
|
290
313
|
record = html_options.delete(:object)
|
291
314
|
associated = record.send(column.association.name)
|
292
315
|
|
@@ -296,27 +319,27 @@ module ActiveScaffold
|
|
296
319
|
method = column.name
|
297
320
|
options.merge! :selected => associated&.id, :include_blank => as_(:_select_), :object => record
|
298
321
|
|
299
|
-
html_options.merge!(
|
300
|
-
options.merge!(
|
301
|
-
|
322
|
+
html_options.merge!(ui_options[:html_options] || {})
|
323
|
+
options.merge!(ui_options)
|
324
|
+
html_options.delete(:multiple) # no point using multiple in a form for singular assoc, but may be set for field search
|
302
325
|
active_scaffold_translate_select_options(options)
|
303
326
|
|
304
327
|
html =
|
305
328
|
if (optgroup = options.delete(:optgroup))
|
306
329
|
select(:record, method, active_scaffold_grouped_options(column, select_options, optgroup), options, html_options)
|
307
330
|
else
|
308
|
-
collection_select(:record, method, select_options, :id,
|
331
|
+
collection_select(:record, method, select_options, :id, ui_options[:label_method] || :to_label, options, html_options)
|
309
332
|
end
|
310
|
-
html << active_scaffold_refresh_link(column, html_options, record) if
|
311
|
-
html << active_scaffold_new_record_subform(column, record, html_options) if
|
333
|
+
html << active_scaffold_refresh_link(column, html_options, record, ui_options) if ui_options[:refresh_link]
|
334
|
+
html << active_scaffold_new_record_subform(column, record, html_options, ui_options: ui_options) if ui_options[:add_new]
|
312
335
|
html
|
313
336
|
end
|
314
337
|
|
315
|
-
def active_scaffold_new_record_subform(column, record, html_options, new_record_attributes: nil, locals: {}, skip_link: false)
|
338
|
+
def active_scaffold_new_record_subform(column, record, html_options, ui_options: column.options, new_record_attributes: nil, locals: {}, skip_link: false)
|
316
339
|
klass =
|
317
340
|
if column.association.polymorphic? && column.association.belongs_to?
|
318
341
|
type = record.send(column.association.foreign_type)
|
319
|
-
column.association.klass(record) if type.present? && (
|
342
|
+
column.association.klass(record) if type.present? && (ui_options[:add_new] == true || type.in?(ui_options[:add_new]))
|
320
343
|
else
|
321
344
|
column.association.klass
|
322
345
|
end
|
@@ -331,8 +354,8 @@ module ActiveScaffold
|
|
331
354
|
scope = html_options[:name].scan(/record(.*)\[#{column.name}\]/).dig(0, 0)
|
332
355
|
new_record ||= klass.new(new_record_attributes)
|
333
356
|
locals = locals.reverse_merge(column: column, parent_record: record, associated: [], show_blank_record: new_record, scope: scope)
|
334
|
-
subform = render(partial: subform_partial_for_column(column, klass), locals: locals)
|
335
|
-
if
|
357
|
+
subform = render(partial: subform_partial_for_column(column, klass, ui_options: ui_options), locals: locals)
|
358
|
+
if ui_options[:hide_subgroups]
|
336
359
|
toggable_id = "#{sub_form_id(association: column.name, id: record.id || generated_id(record) || 99_999_999_999)}-div"
|
337
360
|
subform << link_to_visibility_toggle(toggable_id, default_visible: false)
|
338
361
|
end
|
@@ -347,8 +370,8 @@ module ActiveScaffold
|
|
347
370
|
link_to(label, '#', data: data, class: 'show-new-subform')
|
348
371
|
end
|
349
372
|
|
350
|
-
def active_scaffold_file_with_remove_link(column, options, content, remove_file_prefix, controls_class, &block) # rubocop:disable Metrics/ParameterLists
|
351
|
-
options = active_scaffold_input_text_options(options.merge(
|
373
|
+
def active_scaffold_file_with_remove_link(column, options, content, remove_file_prefix, controls_class, ui_options: column.options, &block) # rubocop:disable Metrics/ParameterLists
|
374
|
+
options = active_scaffold_input_text_options(options.merge(ui_options))
|
352
375
|
if content
|
353
376
|
active_scaffold_file_with_content(column, content, options, remove_file_prefix, controls_class, &block)
|
354
377
|
else
|
@@ -381,7 +404,7 @@ module ActiveScaffold
|
|
381
404
|
end
|
382
405
|
end
|
383
406
|
|
384
|
-
def active_scaffold_refresh_link(column, html_options, record)
|
407
|
+
def active_scaffold_refresh_link(column, html_options, record, ui_options = {})
|
385
408
|
link_options = {:object => record}
|
386
409
|
if html_options['data-update_url']
|
387
410
|
link_options['data-update_send_form'] = html_options['data-update_send_form']
|
@@ -391,7 +414,12 @@ module ActiveScaffold
|
|
391
414
|
link_options = update_columns_options(column, scope.presence, link_options, true)
|
392
415
|
end
|
393
416
|
link_options[:class] = 'refresh-link'
|
394
|
-
|
417
|
+
if ui_options[:refresh_link].is_a?(Hash)
|
418
|
+
text = ui_options.dig(:refresh_link, :text)
|
419
|
+
text = as_(text) if text.is_a?(Symbol)
|
420
|
+
link_options.merge! ui_options[:refresh_link].except(:text)
|
421
|
+
end
|
422
|
+
link_to(text || as_(:refresh), link_options.delete('data-update_url') || html_options['data-update_url'], link_options.except(:object))
|
395
423
|
end
|
396
424
|
|
397
425
|
def active_scaffold_plural_association_options(column, record = nil)
|
@@ -399,21 +427,29 @@ module ActiveScaffold
|
|
399
427
|
[associated_options, associated_options | sorted_association_options_find(column.association, nil, record)]
|
400
428
|
end
|
401
429
|
|
402
|
-
def active_scaffold_input_plural_association(column, options)
|
430
|
+
def active_scaffold_input_plural_association(column, options, ui_options: column.options)
|
403
431
|
record = options.delete(:object)
|
404
432
|
associated_options, select_options = active_scaffold_plural_association_options(column, record)
|
405
433
|
|
406
434
|
html =
|
407
|
-
if
|
435
|
+
if options[:multiple] || ui_options.dig(:html_options, :multiple)
|
436
|
+
html_options = options.merge(ui_options[:html_options] || {})
|
437
|
+
active_scaffold_select_name_with_multiple html_options
|
438
|
+
collection_select(:record, column.name, select_options, :id, ui_options[:label_method] || :to_label, ui_options.merge(object: record), html_options)
|
439
|
+
elsif select_options.empty?
|
408
440
|
content_tag(:span, as_(:no_options), :class => "#{options[:class]} no-options", :id => options[:id]) <<
|
409
441
|
hidden_field_tag("#{options[:name]}[]", '', :id => nil)
|
410
442
|
else
|
411
|
-
active_scaffold_checkbox_list(column, select_options, associated_options.collect(&:id), options)
|
443
|
+
active_scaffold_checkbox_list(column, select_options, associated_options.collect(&:id), options, ui_options: ui_options)
|
412
444
|
end
|
413
|
-
html << active_scaffold_refresh_link(column, options, record) if
|
445
|
+
html << active_scaffold_refresh_link(column, options, record, ui_options) if ui_options[:refresh_link]
|
414
446
|
html
|
415
447
|
end
|
416
448
|
|
449
|
+
def active_scaffold_input_draggable(column, options, ui_options: column.options)
|
450
|
+
active_scaffold_input_plural_association(column, options.merge(draggable_lists: true), ui_options: ui_options)
|
451
|
+
end
|
452
|
+
|
417
453
|
def active_scaffold_checkbox_option(option, label_method, associated_ids, checkbox_options, li_options = {})
|
418
454
|
content_tag(:li, li_options) do
|
419
455
|
option_id = option.is_a?(Array) ? option[1] : option.id
|
@@ -423,10 +459,11 @@ module ActiveScaffold
|
|
423
459
|
end
|
424
460
|
end
|
425
461
|
|
426
|
-
def active_scaffold_checkbox_list(column, select_options, associated_ids, options)
|
427
|
-
label_method =
|
462
|
+
def active_scaffold_checkbox_list(column, select_options, associated_ids, options, ui_options: column.options)
|
463
|
+
label_method = ui_options[:label_method] || :to_label
|
428
464
|
html = hidden_field_tag("#{options[:name]}[]", '', :id => nil)
|
429
|
-
|
465
|
+
draggable = options.delete(:draggable_lists) || ui_options[:draggable_lists]
|
466
|
+
html << content_tag(:ul, options.merge(:class => "#{options[:class]} checkbox-list#{' draggable-lists' if draggable}")) do
|
430
467
|
content = []
|
431
468
|
select_options.each_with_index do |option, i|
|
432
469
|
content << active_scaffold_checkbox_option(option, label_method, associated_ids, :name => "#{options[:name]}[]", :id => "#{options[:id]}_#{i}_id")
|
@@ -441,37 +478,43 @@ module ActiveScaffold
|
|
441
478
|
[(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value]
|
442
479
|
end
|
443
480
|
|
444
|
-
def active_scaffold_enum_options(column, record = nil)
|
445
|
-
|
481
|
+
def active_scaffold_enum_options(column, record = nil, ui_options: column.options)
|
482
|
+
ui_options[:options]
|
446
483
|
end
|
447
484
|
|
448
|
-
def active_scaffold_input_enum(column, html_options, options = {})
|
485
|
+
def active_scaffold_input_enum(column, html_options, options = {}, ui_options: column.options)
|
449
486
|
record = html_options.delete(:object)
|
450
487
|
options[:selected] = record.send(column.name)
|
451
488
|
options[:object] = record
|
452
|
-
options_for_select = active_scaffold_enum_options(column, record).collect do |text, value|
|
489
|
+
options_for_select = active_scaffold_enum_options(column, record, ui_options: ui_options).collect do |text, value|
|
453
490
|
active_scaffold_translated_option(column, text, value)
|
454
491
|
end
|
455
|
-
html_options.merge!(
|
456
|
-
options.merge!(
|
492
|
+
html_options.merge!(ui_options[:html_options] || {})
|
493
|
+
options.merge!(ui_options)
|
457
494
|
active_scaffold_select_name_with_multiple html_options
|
458
495
|
active_scaffold_translate_select_options(options)
|
459
|
-
select(:record, column.name, options_for_select, options, html_options)
|
496
|
+
html = select(:record, column.name, options_for_select, options, html_options)
|
497
|
+
html << active_scaffold_refresh_link(column, html_options, record, ui_options) if ui_options[:refresh_link]
|
498
|
+
html
|
460
499
|
end
|
461
500
|
|
462
|
-
def active_scaffold_input_select(column, html_options)
|
501
|
+
def active_scaffold_input_select(column, html_options, ui_options: column.options)
|
463
502
|
if column.association&.singular?
|
464
|
-
active_scaffold_input_singular_association(column, html_options)
|
503
|
+
active_scaffold_input_singular_association(column, html_options, ui_options: ui_options)
|
465
504
|
elsif column.association&.collection?
|
466
|
-
active_scaffold_input_plural_association(column, html_options)
|
505
|
+
active_scaffold_input_plural_association(column, html_options, ui_options: ui_options)
|
467
506
|
else
|
468
|
-
active_scaffold_input_enum(column, html_options)
|
507
|
+
active_scaffold_input_enum(column, html_options, ui_options: ui_options)
|
469
508
|
end
|
470
509
|
end
|
471
510
|
|
472
|
-
def
|
511
|
+
def active_scaffold_input_select_multiple(column, options, ui_options: column.options)
|
512
|
+
active_scaffold_input_select(column, options.merge(multiple: true), ui_options: ui_options)
|
513
|
+
end
|
514
|
+
|
515
|
+
def active_scaffold_radio_option(option, selected, column, radio_options, ui_options: column.options)
|
473
516
|
if column.association
|
474
|
-
label_method =
|
517
|
+
label_method = ui_options[:label_method] || :to_label
|
475
518
|
text = option.send(label_method)
|
476
519
|
value = option.id
|
477
520
|
checked = {:checked => selected == value}
|
@@ -485,20 +528,20 @@ module ActiveScaffold
|
|
485
528
|
content_tag(:label, radio_button(:record, column.name, value, radio_options) + text)
|
486
529
|
end
|
487
530
|
|
488
|
-
def active_scaffold_input_radio(column, html_options)
|
531
|
+
def active_scaffold_input_radio(column, html_options, ui_options: column.options)
|
489
532
|
record = html_options[:object]
|
490
|
-
html_options.merge!(
|
533
|
+
html_options.merge!(ui_options[:html_options] || {})
|
491
534
|
options =
|
492
535
|
if column.association
|
493
536
|
sorted_association_options_find(column.association, nil, record)
|
494
537
|
else
|
495
|
-
active_scaffold_enum_options(column, record)
|
538
|
+
active_scaffold_enum_options(column, record, ui_options: ui_options)
|
496
539
|
end
|
497
540
|
|
498
541
|
selected = record.send(column.association.name) if column.association
|
499
542
|
selected_id = selected&.id
|
500
543
|
if options.present?
|
501
|
-
if
|
544
|
+
if ui_options[:add_new]
|
502
545
|
html_options[:data] ||= {}
|
503
546
|
html_options[:data][:subform_id] = active_scaffold_subform_attributes(column)[:id]
|
504
547
|
radio_html_options = html_options.merge(class: html_options[:class] + ' hide-new-subform')
|
@@ -506,37 +549,37 @@ module ActiveScaffold
|
|
506
549
|
radio_html_options = html_options
|
507
550
|
end
|
508
551
|
radios = options.map do |option|
|
509
|
-
active_scaffold_radio_option(option, selected_id, column, radio_html_options)
|
552
|
+
active_scaffold_radio_option(option, selected_id, column, radio_html_options, ui_options: ui_options)
|
510
553
|
end
|
511
|
-
if
|
512
|
-
label =
|
513
|
-
label = as_(
|
554
|
+
if ui_options[:include_blank]
|
555
|
+
label = ui_options[:include_blank]
|
556
|
+
label = as_(ui_options[:include_blank]) if ui_options[:include_blank].is_a?(Symbol)
|
514
557
|
radios.prepend content_tag(:label, radio_button(:record, column.name, '', html_options.merge(id: nil)) + label)
|
515
558
|
end
|
516
|
-
if
|
517
|
-
create_new_button = radio_button_tag(html_options[:name], '', selected&.new_record?, html_options.merge(id: nil, class: html_options[:class] + ' show-new-subform'))
|
559
|
+
if ui_options[:add_new]
|
560
|
+
create_new_button = radio_button_tag(html_options[:name], '', selected&.new_record?, html_options.merge(id: nil, class: html_options[:class] + ' show-new-subform').except(:object))
|
518
561
|
radios << content_tag(:label, create_new_button << as_(:create_new)) <<
|
519
|
-
active_scaffold_new_record_subform(column, record, html_options, skip_link: true)
|
562
|
+
active_scaffold_new_record_subform(column, record, html_options, ui_options: ui_options, skip_link: true)
|
520
563
|
end
|
521
564
|
safe_join radios
|
522
565
|
else
|
523
566
|
html = content_tag(:span, as_(:no_options), :class => "#{html_options[:class]} no-options", :id => html_options[:id])
|
524
567
|
html << hidden_field_tag(html_options[:name], '', :id => nil)
|
525
|
-
html << active_scaffold_new_record_subform(column, record, html_options) if
|
568
|
+
html << active_scaffold_new_record_subform(column, record, html_options, ui_options: ui_options) if ui_options[:add_new]
|
526
569
|
html
|
527
570
|
end
|
528
571
|
end
|
529
572
|
|
530
|
-
def active_scaffold_input_checkbox(column, options)
|
531
|
-
check_box(:record, column.name, options.merge(
|
573
|
+
def active_scaffold_input_checkbox(column, options, ui_options: column.options)
|
574
|
+
check_box(:record, column.name, options.merge(ui_options))
|
532
575
|
end
|
533
576
|
|
534
|
-
def active_scaffold_input_password(column, options)
|
535
|
-
active_scaffold_text_input :password_field, column, options.reverse_merge(autocomplete: 'new-password')
|
577
|
+
def active_scaffold_input_password(column, options, ui_options: column.options)
|
578
|
+
active_scaffold_text_input :password_field, column, options.reverse_merge(autocomplete: 'new-password'), ui_options: ui_options
|
536
579
|
end
|
537
580
|
|
538
|
-
def active_scaffold_input_textarea(column, options)
|
539
|
-
text_area(:record, column.name, options.merge(:
|
581
|
+
def active_scaffold_input_textarea(column, options, ui_options: column.options)
|
582
|
+
text_area(:record, column.name, options.merge(cols: ui_options[:cols], rows: ui_options[:rows], size: ui_options[:size]))
|
540
583
|
end
|
541
584
|
|
542
585
|
def active_scaffold_input_virtual(column, options)
|
@@ -547,55 +590,55 @@ module ActiveScaffold
|
|
547
590
|
# Sadly, many of them lacks browser support
|
548
591
|
|
549
592
|
# A text box, that accepts only valid email address (in-browser validation)
|
550
|
-
def active_scaffold_input_email(column, options)
|
551
|
-
active_scaffold_text_input :email_field, column, options
|
593
|
+
def active_scaffold_input_email(column, options, ui_options: column.options)
|
594
|
+
active_scaffold_text_input :email_field, column, options, ui_options: ui_options
|
552
595
|
end
|
553
596
|
|
554
597
|
# A text box, that accepts only valid URI (in-browser validation)
|
555
|
-
def active_scaffold_input_url(column, options)
|
556
|
-
active_scaffold_text_input :url_field, column, options
|
598
|
+
def active_scaffold_input_url(column, options, ui_options: column.options)
|
599
|
+
active_scaffold_text_input :url_field, column, options, ui_options: ui_options
|
557
600
|
end
|
558
601
|
|
559
602
|
# A text box, that accepts only valid phone-number (in-browser validation)
|
560
|
-
def active_scaffold_input_telephone(column, options)
|
561
|
-
active_scaffold_text_input :telephone_field, column, options, :format
|
603
|
+
def active_scaffold_input_telephone(column, options, ui_options: column.options)
|
604
|
+
active_scaffold_text_input :telephone_field, column, options, :format, ui_options: ui_options
|
562
605
|
end
|
563
606
|
|
564
607
|
# A spinbox control for number values (in-browser validation)
|
565
|
-
def active_scaffold_input_number(column, options)
|
566
|
-
active_scaffold_number_input :number_field, column, options, :format
|
608
|
+
def active_scaffold_input_number(column, options, ui_options: column.options)
|
609
|
+
active_scaffold_number_input :number_field, column, options, :format, ui_options: ui_options
|
567
610
|
end
|
568
611
|
|
569
612
|
# A slider control for number values (in-browser validation)
|
570
|
-
def active_scaffold_input_range(column, options)
|
571
|
-
active_scaffold_number_input :range_field, column, options, :format
|
613
|
+
def active_scaffold_input_range(column, options, ui_options: column.options)
|
614
|
+
active_scaffold_number_input :range_field, column, options, :format, ui_options: ui_options
|
572
615
|
end
|
573
616
|
|
574
617
|
# A slider control for number values (in-browser validation)
|
575
|
-
def active_scaffold_number_input(method, column, options, remove_options = nil)
|
618
|
+
def active_scaffold_number_input(method, column, options, remove_options = nil, ui_options: column.options)
|
576
619
|
options = numerical_constraints_for_column(column, options)
|
577
|
-
active_scaffold_text_input method, column, options, remove_options
|
620
|
+
active_scaffold_text_input method, column, options, remove_options, ui_options: ui_options
|
578
621
|
end
|
579
622
|
|
580
|
-
def active_scaffold_text_input(method, column, options, remove_options = nil)
|
623
|
+
def active_scaffold_text_input(method, column, options, remove_options = nil, ui_options: column.options)
|
581
624
|
options = active_scaffold_input_text_options(options)
|
582
|
-
options = options.merge(
|
625
|
+
options = options.merge(ui_options)
|
583
626
|
options = options.except(*remove_options) if remove_options.present?
|
584
627
|
send method, :record, column.name, options
|
585
628
|
end
|
586
629
|
|
587
630
|
# A color picker
|
588
|
-
def active_scaffold_input_color(column, options)
|
631
|
+
def active_scaffold_input_color(column, options, ui_options: column.options)
|
589
632
|
html = []
|
590
633
|
options = active_scaffold_input_text_options(options)
|
591
|
-
if column.
|
634
|
+
if column.null?
|
592
635
|
no_color = options[:object].send(column.name).nil?
|
593
636
|
method = no_color ? :hidden_field : :color_field
|
594
|
-
html << content_tag(:label, check_box_tag('disable', '1', no_color, id: nil, name: nil, class: 'no-color') << " #{as_
|
637
|
+
html << content_tag(:label, check_box_tag('disable', '1', no_color, id: nil, name: nil, class: 'no-color') << " #{as_ ui_options[:no_color] || :no_color}")
|
595
638
|
else
|
596
639
|
method = :color_field
|
597
640
|
end
|
598
|
-
html << send(method, :record, column.name, options.merge(
|
641
|
+
html << send(method, :record, column.name, options.merge(ui_options).except(:format, :no_color))
|
599
642
|
safe_join html
|
600
643
|
end
|
601
644
|
|
@@ -603,34 +646,37 @@ module ActiveScaffold
|
|
603
646
|
# Column.type-based inputs
|
604
647
|
#
|
605
648
|
|
606
|
-
def active_scaffold_input_boolean(column, options)
|
607
|
-
record =
|
608
|
-
|
609
|
-
select_options << [as_(:_select_), nil] if !column.virtual? && column.column.null
|
610
|
-
select_options << [as_(:true), true] # rubocop:disable Lint/BooleanSymbol
|
611
|
-
select_options << [as_(:false), false] # rubocop:disable Lint/BooleanSymbol
|
649
|
+
def active_scaffold_input_boolean(column, html_options, ui_options: column.options)
|
650
|
+
record = html_options.delete(:object)
|
651
|
+
html_options.merge!(ui_options[:html_options] || {})
|
612
652
|
|
613
|
-
|
653
|
+
options = {selected: record.send(column.name), object: record}
|
654
|
+
options[:include_blank] = :_select_ if column.null?
|
655
|
+
options.merge!(ui_options)
|
656
|
+
active_scaffold_translate_select_options(options)
|
657
|
+
|
658
|
+
options_for_select = [[as_(:true), true], [as_(:false), false]] # rubocop:disable Lint/BooleanSymbol
|
659
|
+
select(:record, column.name, options_for_select, options, html_options)
|
614
660
|
end
|
615
661
|
|
616
|
-
def active_scaffold_input_date(column, options)
|
617
|
-
active_scaffold_text_input :date_field, column, options
|
662
|
+
def active_scaffold_input_date(column, options, ui_options: column.options)
|
663
|
+
active_scaffold_text_input :date_field, column, options, ui_options: ui_options
|
618
664
|
end
|
619
665
|
|
620
|
-
def active_scaffold_input_time(column, options)
|
621
|
-
active_scaffold_text_input :time_field, column, options
|
666
|
+
def active_scaffold_input_time(column, options, ui_options: column.options)
|
667
|
+
active_scaffold_text_input :time_field, column, options, ui_options: ui_options
|
622
668
|
end
|
623
669
|
|
624
|
-
def active_scaffold_input_datetime(column, options)
|
625
|
-
active_scaffold_text_input :datetime_local_field, column, options
|
670
|
+
def active_scaffold_input_datetime(column, options, ui_options: column.options)
|
671
|
+
active_scaffold_text_input :datetime_local_field, column, options, ui_options: ui_options
|
626
672
|
end
|
627
673
|
|
628
|
-
def active_scaffold_input_month(column, options)
|
629
|
-
active_scaffold_text_input :month_field, column, options
|
674
|
+
def active_scaffold_input_month(column, options, ui_options: column.options)
|
675
|
+
active_scaffold_text_input :month_field, column, options, ui_options: ui_options
|
630
676
|
end
|
631
677
|
|
632
|
-
def active_scaffold_input_week(column, options)
|
633
|
-
active_scaffold_text_input :week_field, column, options
|
678
|
+
def active_scaffold_input_week(column, options, ui_options: column.options)
|
679
|
+
active_scaffold_text_input :week_field, column, options, ui_options: ui_options
|
634
680
|
end
|
635
681
|
|
636
682
|
##
|
@@ -669,8 +715,8 @@ module ActiveScaffold
|
|
669
715
|
end
|
670
716
|
alias override_input? override_input
|
671
717
|
|
672
|
-
def subform_partial_for_column(column, klass = nil)
|
673
|
-
subform_partial = "#{
|
718
|
+
def subform_partial_for_column(column, klass = nil, ui_options: column.options)
|
719
|
+
subform_partial = "#{ui_options[:layout] || active_scaffold_config_for(klass || column.association.klass).subform.layout}_subform"
|
674
720
|
override_subform_partial(column, subform_partial) || subform_partial
|
675
721
|
end
|
676
722
|
|
@@ -740,7 +786,7 @@ module ActiveScaffold
|
|
740
786
|
|
741
787
|
# find minimum and maximum from validators
|
742
788
|
# we can safely modify :min and :max by 1 for :greater_tnan or :less_than value only for integer values
|
743
|
-
only_integer = column.
|
789
|
+
only_integer = column.column_type == :integer if column.column
|
744
790
|
only_integer ||= validators.find { |v| v.options[:only_integer] }.present?
|
745
791
|
margin = only_integer ? 1 : 0
|
746
792
|
|
@@ -5,7 +5,7 @@ module ActiveScaffold
|
|
5
5
|
def active_scaffold_human_condition_for(column)
|
6
6
|
return if (value = field_search_params[column.name.to_s]).nil?
|
7
7
|
search_ui = column.search_ui
|
8
|
-
search_ui ||= column.
|
8
|
+
search_ui ||= column.column_type if column.column
|
9
9
|
if override_human_condition_column?(column)
|
10
10
|
send(override_human_condition_column(column), value, {})
|
11
11
|
elsif search_ui && override_human_condition?(search_ui)
|
@@ -26,6 +26,7 @@ module ActiveScaffold
|
|
26
26
|
attribute = column.active_record_class.human_attribute_name(column.name)
|
27
27
|
opt ||= :between if from && to
|
28
28
|
opt ||= from ? '>=' : '<='
|
29
|
+
from = to = nil if opt&.in? %w[null not_null]
|
29
30
|
"#{attribute} #{as_(opt).downcase} #{from} #{to}"
|
30
31
|
end
|
31
32
|
|
@@ -37,28 +38,61 @@ module ActiveScaffold
|
|
37
38
|
alias active_scaffold_human_condition_decimal active_scaffold_human_condition_integer
|
38
39
|
alias active_scaffold_human_condition_float active_scaffold_human_condition_integer
|
39
40
|
|
40
|
-
def
|
41
|
+
def active_scaffold_human_condition_range(column, value)
|
41
42
|
opt = ActiveScaffold::Finder::STRING_COMPARATORS.key(value['opt']) || value['opt']
|
42
43
|
to = "- #{value['to']}" if opt == 'BETWEEN'
|
43
44
|
format_human_condition column, opt, "'#{value['from']}'", to
|
44
45
|
end
|
46
|
+
alias active_scaffold_human_condition_string active_scaffold_human_condition_range
|
45
47
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
def active_scaffold_human_condition_datetime(column, value)
|
49
|
+
case value['opt']
|
50
|
+
when 'RANGE'
|
51
|
+
range_type, range = value['range'].downcase.split('_')
|
52
|
+
format = active_scaffold_human_condition_datetime_range_format(range_type, range)
|
53
|
+
from, = controller.class.datetime_from_to(column, value)
|
54
|
+
"#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value['range'].downcase).downcase} (#{I18n.l(from, :format => format)})"
|
55
|
+
when 'PAST', 'FUTURE'
|
56
|
+
from, to = controller.class.datetime_from_to(column, value)
|
57
|
+
"#{column.active_record_class.human_attribute_name(column.name)} #{as_('BETWEEN'.downcase).downcase} #{I18n.l(from)} - #{I18n.l(to)}"
|
58
|
+
else
|
59
|
+
from, to = controller.class.datetime_from_to(column, value)
|
60
|
+
"#{column.active_record_class.human_attribute_name(column.name)} #{as_(value['opt'].downcase).downcase} #{I18n.l(from)} #{value['opt'] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
alias active_scaffold_human_condition_time active_scaffold_human_condition_datetime
|
64
|
+
alias active_scaffold_human_condition_date active_scaffold_human_condition_datetime
|
65
|
+
alias active_scaffold_human_condition_timestamp active_scaffold_human_condition_datetime
|
66
|
+
|
67
|
+
def active_scaffold_human_condition_datetime_range_format(range_type, range)
|
68
|
+
case range
|
69
|
+
when 'week'
|
70
|
+
first_day_of_week = I18n.translate 'active_scaffold.date_picker_options.firstDay'
|
71
|
+
if first_day_of_week == 1
|
72
|
+
'%W %Y'
|
73
|
+
else
|
74
|
+
'%U %Y'
|
75
|
+
end
|
76
|
+
when 'month'
|
77
|
+
'%b %Y'
|
78
|
+
when 'year'
|
79
|
+
'%Y'
|
80
|
+
else
|
81
|
+
I18n.translate 'date.formats.default'
|
82
|
+
end
|
53
83
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
84
|
+
# def active_scaffold_human_condition_date(column, value)
|
85
|
+
# conversion = column.column_type == :date ? :to_date : :to_time
|
86
|
+
# from = controller.class.condition_value_for_datetime(column, value['from'], conversion)
|
87
|
+
# from = I18n.l from if from
|
88
|
+
# to = controller.class.condition_value_for_datetime(column, value['to'], conversion) if value['opt'] == 'BETWEEN' || (value['opt'].nil? && value['to'])
|
89
|
+
# to = "- #{I18n.l to}" if to
|
90
|
+
# format_human_condition column, value['opt'], from, to
|
91
|
+
# end
|
57
92
|
|
58
93
|
def active_scaffold_human_condition_boolean(column, value)
|
59
94
|
attribute = column.active_record_class.human_attribute_name(column.name)
|
60
|
-
|
61
|
-
as_(:boolean, :scope => :human_conditions, :column => attribute, :value => label)
|
95
|
+
as_(:boolean, :scope => :human_conditions, :column => attribute, :value => as_(value))
|
62
96
|
end
|
63
97
|
alias active_scaffold_human_condition_checkbox active_scaffold_human_condition_boolean
|
64
98
|
|