active_scaffold 3.6.8 → 3.6.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +15 -0
- data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +1 -1
- data/app/assets/javascripts/jquery/jquery.editinplace.js +21 -7
- data/app/views/active_scaffold_overrides/_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_form_association.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_search.html.erb +1 -1
- data/lib/active_scaffold/actions/list.rb +13 -13
- data/lib/active_scaffold/actions/update.rb +1 -1
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +2 -2
- data/lib/active_scaffold/data_structures/column.rb +19 -8
- data/lib/active_scaffold/finder.rb +3 -3
- data/lib/active_scaffold/helpers/form_column_helpers.rb +10 -4
- data/lib/active_scaffold/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97d6ca8d1bfe05ad56e32d006caecb46e96ce220023490c816942f18a77c57d2
|
4
|
+
data.tar.gz: 605328d07d556bad95298f038cb33fb7a91903200b87974d1c36747ba9c2f8bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 305ce148588f05c5a00858ef82e235575434c2760e9d2abf99f6d3be213b875195a81921da1f6590dceab7010d64646245000333982a974c58656bce99364b96
|
7
|
+
data.tar.gz: 350c358fdf5a3187170ab73ac8ccb831662e3edc041cf6adce85db3023888e6c2336a2141a6f6ff79be1db952fd1d5c46d9acb12026d248b433443690d92137a
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
= 3.6.11
|
2
|
+
- Fix inplace edit cloning with jquery >= 1.9, when more than one child is cloned
|
3
|
+
- Support inplace edit cloning for :radio form_ui
|
4
|
+
- Add records parameter to cache_columns_count and related methods (count_query_for_column, mongoid_count_for_column)
|
5
|
+
- Fix required attribute when validator uses :on option, so on: :update only set required on update form, and :create only set required on create form
|
6
|
+
|
7
|
+
= 3.6.10
|
8
|
+
- Don't add numerical constraints based on conditional validation
|
9
|
+
- Fix typo in cache key for numerical constraints
|
10
|
+
- Fix duplicated params in search form, e.g. embedded constraints
|
11
|
+
|
12
|
+
= 3.6.9
|
13
|
+
- Support depend on .rb or .json locale files for date picker bridge
|
14
|
+
- Fix search with dates entered with timezone in datepicker
|
15
|
+
|
1
16
|
= 3.6.8
|
2
17
|
- Add depend_on available translations in app to data picker bridge JS
|
3
18
|
- Fix live search with rails-ujs
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%# encoding: utf-8 %>
|
2
|
-
<% I18n.available_locales.
|
2
|
+
<% I18n.available_locales.each { |locale| Dir[Rails.root.join("config/locales/#{locale}.*")].each { |path| depend_on path } } %>
|
3
3
|
<%= ActiveScaffold::Bridges[:date_picker].localization %>
|
4
4
|
Object.getPrototypeOf(jQuery.datepicker)._attachDatepicker_without_inlineSettings = Object.getPrototypeOf(jQuery.datepicker)._attachDatepicker;
|
5
5
|
jQuery.extend(Object.getPrototypeOf(jQuery.datepicker), {
|
@@ -317,7 +317,6 @@ $.extend(InlineEditor.prototype, {
|
|
317
317
|
if (editorNode.data('id')) editorNode.attr('id', editorNode.data('id') + this.settings.clone_id_suffix);
|
318
318
|
editorNode.attr('name', 'inplace_value');
|
319
319
|
editorNode.addClass('editor_field');
|
320
|
-
this.setValue(editorNode, this.originalValue);
|
321
320
|
clonedNodes = editorNode;
|
322
321
|
|
323
322
|
if (patternNodes.additionalNodes) {
|
@@ -326,9 +325,10 @@ $.extend(InlineEditor.prototype, {
|
|
326
325
|
if (patternNode.data('id')) {
|
327
326
|
patternNode.attr('id', patternNode.data('id') + this.settings.clone_id_suffix);
|
328
327
|
}
|
329
|
-
clonedNodes
|
328
|
+
clonedNodes.push(patternNode[0]);
|
330
329
|
});
|
331
330
|
}
|
331
|
+
this.setValue(clonedNodes, this.originalValue);
|
332
332
|
return clonedNodes;
|
333
333
|
},
|
334
334
|
|
@@ -349,23 +349,37 @@ $.extend(InlineEditor.prototype, {
|
|
349
349
|
return nodes;
|
350
350
|
},
|
351
351
|
|
352
|
-
setValue: function(
|
353
|
-
var
|
352
|
+
setValue: function(editFields, textValue) {
|
353
|
+
var editField = editFields.find(':input').addBack(':input'),
|
354
|
+
type = editField.get(0).nodeName.toLowerCase();
|
355
|
+
if (type === 'input') type = editField.attr('type').toLowerCase();
|
356
|
+
var function_name = 'setValueFor' + type;
|
354
357
|
if (typeof(this[function_name]) == 'function') {
|
355
|
-
this[function_name](
|
358
|
+
this[function_name](editFields, textValue);
|
356
359
|
} else {
|
357
360
|
editField.val(textValue);
|
358
361
|
}
|
359
362
|
},
|
360
363
|
|
361
|
-
setValueForselect: function(
|
362
|
-
var
|
364
|
+
setValueForselect: function(editFields, textValue) {
|
365
|
+
var editField = editFields.find('select').addBack('select').first(),
|
366
|
+
option_value = editField.children("option:contains('" + textValue + "')").val();
|
363
367
|
|
364
368
|
if (typeof(option_value) !== 'undefined') {
|
365
369
|
editField.val(option_value);
|
366
370
|
}
|
367
371
|
},
|
368
372
|
|
373
|
+
setValueForradio: function(editFields, textValue) {
|
374
|
+
var editField = editFields.find('input[type=radio]').addBack('input[type=radio]').filter(function() {
|
375
|
+
var contains = ':contains("' + textValue + '")';
|
376
|
+
return editFields.find('label[for="' + $(this).attr('id') + '"]' + contains).length ||
|
377
|
+
$(this).closest('label' + contains).length;
|
378
|
+
}).first();
|
379
|
+
|
380
|
+
if (editField.length) editField.prop('checked', true);
|
381
|
+
},
|
382
|
+
|
369
383
|
inputNameAndClass: function() {
|
370
384
|
return ' name="inplace_value" class="inplace_field" ';
|
371
385
|
},
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<%= render_column(column, @record, renders_as, scope) %>
|
25
25
|
<% end %>
|
26
26
|
<% else -%>
|
27
|
-
<li class="form-element <%= 'required' if column.required? %> <%= column.form_ui %> <%= column_css_class %>">
|
27
|
+
<li class="form-element <%= 'required' if column.required?(action_for_validation?(@record)) %> <%= column.form_ui %> <%= column_css_class %>">
|
28
28
|
<%= render_column(column, @record, renders_as, scope, !authorized) %>
|
29
29
|
</li>
|
30
30
|
<% end -%>
|
@@ -4,7 +4,7 @@ if column.show_blank_record?(associated)
|
|
4
4
|
show_blank_record = build_associated(column.association, parent_record)
|
5
5
|
end
|
6
6
|
disable_required_for_new = @disable_required_for_new
|
7
|
-
@disable_required_for_new = !!show_blank_record unless (column.association.singular? && column.required?)
|
7
|
+
@disable_required_for_new = !!show_blank_record unless (column.association.singular? && column.required?(action_for_validation?(parent_record)))
|
8
8
|
subform_div_id = "#{sub_form_id(:association => column.name, :id => parent_record.id || generated_id(parent_record) || 99999999999)}-div"
|
9
9
|
|
10
10
|
# render footer before rendering associated records, fixes create new on self-associations
|
@@ -58,7 +58,7 @@
|
|
58
58
|
end
|
59
59
|
|
60
60
|
col_class = default_col_class.clone
|
61
|
-
col_class << 'required' if column.required?
|
61
|
+
col_class << 'required' if column.required?(action_for_validation?(record))
|
62
62
|
col_class << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
|
63
63
|
col_class << 'hidden' if column_renders_as(column) == :hidden
|
64
64
|
-%>
|
@@ -88,7 +88,7 @@
|
|
88
88
|
<% columns_group.each_column(for: record.class, crud_type: :read, flatten: true) do |col| %>
|
89
89
|
<%
|
90
90
|
col_class = default_col_class.clone
|
91
|
-
col_class << 'required' if col.required?
|
91
|
+
col_class << 'required' if col.required?(action_for_validation?(record))
|
92
92
|
col_class << col.css_class unless col.css_class.nil? || col.css_class.is_a?(Proc)
|
93
93
|
col_class << 'hidden' if column_renders_as(col) == :hidden
|
94
94
|
%>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
hidden_params = url_options.except(:controller, :action, :id, :search).to_query.split(Rack::Utils::DEFAULT_SEP)
|
15
15
|
-%>
|
16
16
|
|
17
|
-
<%= form_tag url_options, options do %>
|
17
|
+
<%= form_tag url_options.slice(:controller, :action, :id, :search), options do %>
|
18
18
|
<% hidden_params.each do |pair| -%>
|
19
19
|
<% key, value = pair.split('=', 2).map { |str| Rack::Utils.unescape(str) } -%>
|
20
20
|
<%= hidden_field_tag(key, value) %>
|
@@ -125,7 +125,7 @@ module ActiveScaffold::Actions
|
|
125
125
|
@remove_id_from_list_links = params[:id].blank?
|
126
126
|
@page = current_page
|
127
127
|
@records = @page.items
|
128
|
-
cache_column_counts
|
128
|
+
cache_column_counts @records
|
129
129
|
end
|
130
130
|
|
131
131
|
def columns_to_cache_counts
|
@@ -136,12 +136,12 @@ module ActiveScaffold::Actions
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
-
def cache_column_counts
|
139
|
+
def cache_column_counts(records)
|
140
140
|
@counts = columns_to_cache_counts.each_with_object({}) do |column, counts|
|
141
141
|
if ActiveScaffold::OrmChecks.active_record?(column.association.klass)
|
142
|
-
counts[column.name] = count_query_for_column(column).count
|
142
|
+
counts[column.name] = count_query_for_column(column, records).count
|
143
143
|
elsif ActiveScaffold::OrmChecks.mongoid?(column.association.klass)
|
144
|
-
counts[column.name] = mongoid_count_for_column(column)
|
144
|
+
counts[column.name] = mongoid_count_for_column(column, records)
|
145
145
|
end
|
146
146
|
end
|
147
147
|
end
|
@@ -151,17 +151,17 @@ module ActiveScaffold::Actions
|
|
151
151
|
(!column.association.as || column.association.reverse_association)
|
152
152
|
end
|
153
153
|
|
154
|
-
def count_query_for_column(column)
|
154
|
+
def count_query_for_column(column, records)
|
155
155
|
if count_on_association_class?(column)
|
156
|
-
count_query_on_association_class(column)
|
156
|
+
count_query_on_association_class(column, records)
|
157
157
|
else
|
158
|
-
count_query_with_join(column)
|
158
|
+
count_query_with_join(column, records)
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
-
def count_query_on_association_class(column)
|
162
|
+
def count_query_on_association_class(column, records)
|
163
163
|
key = column.association.primary_key || :id
|
164
|
-
query = column.association.klass.where(column.association.foreign_key =>
|
164
|
+
query = column.association.klass.where(column.association.foreign_key => records.map(&key.to_sym))
|
165
165
|
if column.association.as
|
166
166
|
query.where!(column.association.reverse_association.foreign_type => active_scaffold_config.model.name)
|
167
167
|
end
|
@@ -171,17 +171,17 @@ module ActiveScaffold::Actions
|
|
171
171
|
query.group(column.association.foreign_key)
|
172
172
|
end
|
173
173
|
|
174
|
-
def count_query_with_join(column)
|
174
|
+
def count_query_with_join(column, records)
|
175
175
|
klass = column.association.klass
|
176
|
-
query = active_scaffold_config.model.where(active_scaffold_config.primary_key =>
|
176
|
+
query = active_scaffold_config.model.where(active_scaffold_config.primary_key => records.map(&:id))
|
177
177
|
.joins(column.name).group(active_scaffold_config.primary_key)
|
178
178
|
.select("#{klass.quoted_table_name}.#{klass.quoted_primary_key}")
|
179
179
|
query = query.uniq if column.association.scope && klass.instance_exec(&column.association.scope).values[:distinct]
|
180
180
|
query
|
181
181
|
end
|
182
182
|
|
183
|
-
def mongoid_count_for_column(column)
|
184
|
-
matches = {column.association.foreign_key => {'$in':
|
183
|
+
def mongoid_count_for_column(column, records)
|
184
|
+
matches = {column.association.foreign_key => {'$in': records.map(&:id)}}
|
185
185
|
if column.association.as
|
186
186
|
matches[column.association.reverse_association.foreign_type] = {'$eq': active_scaffold_config.model.name}
|
187
187
|
end
|
@@ -69,7 +69,7 @@ module ActiveScaffold::Actions
|
|
69
69
|
@updated_record = @record
|
70
70
|
# get_row so associations are cached like in list action
|
71
71
|
# if record doesn't fullfil current conditions remove it from list
|
72
|
-
|
72
|
+
get_row
|
73
73
|
rescue ActiveRecord::RecordNotFound
|
74
74
|
nil
|
75
75
|
end
|
@@ -122,9 +122,9 @@ module ActiveScaffold
|
|
122
122
|
if column.search_sql.is_a? Proc
|
123
123
|
column.search_sql.call(from_value, to_value, operator)
|
124
124
|
elsif operator.nil?
|
125
|
-
['%<search_sql>s BETWEEN ? AND ?', from_value
|
125
|
+
['%<search_sql>s BETWEEN ? AND ?', from_value, to_value] unless from_value.nil? || to_value.nil?
|
126
126
|
else
|
127
|
-
["%<search_sql>s #{value['opt']} ?", from_value
|
127
|
+
["%<search_sql>s #{value['opt']} ?", from_value] unless from_value.nil?
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
@@ -66,8 +66,12 @@ module ActiveScaffold::DataStructures
|
|
66
66
|
# whether the field is required or not. used on the form for visually indicating the fact to the user.
|
67
67
|
# TODO: move into predicate
|
68
68
|
attr_writer :required
|
69
|
-
def required?
|
70
|
-
@required
|
69
|
+
def required?(action = nil)
|
70
|
+
if action && @required
|
71
|
+
@required == true || @required.include?(action)
|
72
|
+
else
|
73
|
+
@required
|
74
|
+
end
|
71
75
|
end
|
72
76
|
|
73
77
|
attr_reader :update_columns
|
@@ -353,9 +357,11 @@ module ActiveScaffold::DataStructures
|
|
353
357
|
|
354
358
|
# default all the configurable variables
|
355
359
|
self.css_class = ''
|
356
|
-
|
357
|
-
|
358
|
-
|
360
|
+
validators_force_require_on = active_record_class.validators_on(name)
|
361
|
+
.map { |val| validator_force_required?(val) }
|
362
|
+
.select(&:present?)
|
363
|
+
self.required = validators_force_require_on.any? { |opt| opt == true } ||
|
364
|
+
validators_force_require_on.reject { |opt| opt == true }.flatten
|
359
365
|
self.sort = true
|
360
366
|
self.search_sql = true
|
361
367
|
|
@@ -436,13 +442,18 @@ module ActiveScaffold::DataStructures
|
|
436
442
|
return false if val.options[:if] || val.options[:unless]
|
437
443
|
case val
|
438
444
|
when ActiveModel::Validations::PresenceValidator
|
439
|
-
|
445
|
+
validator_required_on(val)
|
440
446
|
when ActiveModel::Validations::InclusionValidator
|
441
|
-
!val.options[:allow_nil] && !val.options[:allow_blank] &&
|
442
|
-
|
447
|
+
if !val.options[:allow_nil] && !val.options[:allow_blank] && !inclusion_validator_for_checkbox?(val)
|
448
|
+
validator_required_on(val)
|
449
|
+
end
|
443
450
|
end
|
444
451
|
end
|
445
452
|
|
453
|
+
def validator_required_on(val)
|
454
|
+
val.options[:on] ? Array(val.options[:on]) : true
|
455
|
+
end
|
456
|
+
|
446
457
|
def inclusion_validator_for_checkbox?(val)
|
447
458
|
@form_ui == :checkbox &&
|
448
459
|
[[true, false], [false, true]].include?(val.options[:with] || val.options[:within] || val.options[:in])
|
@@ -319,11 +319,11 @@ module ActiveScaffold
|
|
319
319
|
if from_value.nil? && to_value.nil?
|
320
320
|
nil
|
321
321
|
elsif !from_value
|
322
|
-
['%<search_sql>s <= ?', to_value
|
322
|
+
['%<search_sql>s <= ?', to_value]
|
323
323
|
elsif !to_value
|
324
|
-
['%<search_sql>s >= ?', from_value
|
324
|
+
['%<search_sql>s >= ?', from_value]
|
325
325
|
else
|
326
|
-
['%<search_sql>s BETWEEN ? AND ?', from_value
|
326
|
+
['%<search_sql>s BETWEEN ? AND ?', from_value, to_value]
|
327
327
|
end
|
328
328
|
end
|
329
329
|
|
@@ -55,7 +55,7 @@ module ActiveScaffold
|
|
55
55
|
def active_scaffold_render_subform_column(column, scope, crud_type, readonly, add_class = false, record = nil) # rubocop:disable Metrics/ParameterLists
|
56
56
|
if add_class
|
57
57
|
col_class = []
|
58
|
-
col_class << 'required' if column.required?
|
58
|
+
col_class << 'required' if column.required?(action_for_validation?(record))
|
59
59
|
col_class << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
|
60
60
|
col_class << 'hidden' if column_renders_as(column) == :hidden
|
61
61
|
col_class << 'checkbox' if column.form_ui == :checkbox
|
@@ -85,13 +85,17 @@ module ActiveScaffold
|
|
85
85
|
options
|
86
86
|
end
|
87
87
|
|
88
|
+
def action_for_validation?(record)
|
89
|
+
record&.persisted? ? :update : :create
|
90
|
+
end
|
91
|
+
|
88
92
|
# the standard active scaffold options used for class, name and scope
|
89
93
|
def active_scaffold_input_options(column, scope = nil, options = {})
|
90
94
|
name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]"
|
91
95
|
record = options[:object]
|
92
96
|
|
93
97
|
# Add some HTML5 attributes for in-browser validation and better user experience
|
94
|
-
if column.required? && (!@disable_required_for_new || scope.nil? || record&.persisted?)
|
98
|
+
if column.required?(action_for_validation?(record)) && (!@disable_required_for_new || scope.nil? || record&.persisted?)
|
95
99
|
options[:required] = true
|
96
100
|
end
|
97
101
|
options[:placeholder] = column.placeholder if column.placeholder.present?
|
@@ -720,7 +724,9 @@ module ActiveScaffold
|
|
720
724
|
# Try to get numerical constraints from model's validators
|
721
725
|
def column_numerical_constraints(column, options)
|
722
726
|
validators = column.active_record_class.validators.select do |v|
|
723
|
-
v.is_a?(ActiveModel::Validations::NumericalityValidator) &&
|
727
|
+
v.is_a?(ActiveModel::Validations::NumericalityValidator) &&
|
728
|
+
v.attributes.include?(column.name) &&
|
729
|
+
!v.options[:if] && !v.options[:unless]
|
724
730
|
end
|
725
731
|
|
726
732
|
equal_validator = validators.find { |v| v.options[:equal_to] }
|
@@ -770,7 +776,7 @@ module ActiveScaffold
|
|
770
776
|
end
|
771
777
|
|
772
778
|
def numerical_constraints_for_column(column, options)
|
773
|
-
constraints = Rails.cache.fetch("#{column.cache_key}#
|
779
|
+
constraints = Rails.cache.fetch("#{column.cache_key}#numerical_constraints") do
|
774
780
|
column_numerical_constraints(column, options)
|
775
781
|
end
|
776
782
|
constraints.merge(options)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Many, see README
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|