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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d63c8ce5c055421403fdf35bce2cc09fa4797ad8ccf282fd0ab96b80a254b56
4
- data.tar.gz: af6eea7aa4e45b55bfafcdc1c2cedbd2e3880bf71af800fd2720a291fde329a8
3
+ metadata.gz: 97d6ca8d1bfe05ad56e32d006caecb46e96ce220023490c816942f18a77c57d2
4
+ data.tar.gz: 605328d07d556bad95298f038cb33fb7a91903200b87974d1c36747ba9c2f8bc
5
5
  SHA512:
6
- metadata.gz: edd5caa3ba54351a67da98599a5bf684eb1e6cdc573c951a5318d25cbb6f36fceabfb963f0a6e4c64a21320c75aecfcefb07c6f4f049fd4f49a585ff3e74c09c
7
- data.tar.gz: 7a1a1ed5fb94ded3584468ccec6ec7321d781f0ae90efd767a6723c8ff5cd29b11a5f67620599e32a44becd5c6ec322835056c5f1baf1430802c132db16f42c9
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.map { |locale| Rails.root.join("config/locales/#{locale}.yml") }.select(&:exist?).each { |path| depend_on path.to_s } %>
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 = clonedNodes.after(patternNode);
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(editField, textValue) {
353
- var function_name = 'setValueFor' + editField.get(0).nodeName.toLowerCase();
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](editField, textValue);
358
+ this[function_name](editFields, textValue);
356
359
  } else {
357
360
  editField.val(textValue);
358
361
  }
359
362
  },
360
363
 
361
- setValueForselect: function(editField, textValue) {
362
- var option_value = editField.children("option:contains('" + textValue + "')").val();
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 => @records.map(&key.to_sym))
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 => @records.map(&:id))
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': @records.map(&:id)}}
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
- @record = get_row
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.to_s(:db), to_value.to_s(:db)] unless from_value.nil? || to_value.nil?
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.to_s(:db)] unless from_value.nil?
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
- self.required = active_record_class.validators_on(name).any? do |val|
357
- validator_force_required?(val)
358
- end
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
- true
445
+ validator_required_on(val)
440
446
  when ActiveModel::Validations::InclusionValidator
441
- !val.options[:allow_nil] && !val.options[:allow_blank] &&
442
- !inclusion_validator_for_checkbox?(val)
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.to_s(:db)]
322
+ ['%<search_sql>s <= ?', to_value]
323
323
  elsif !to_value
324
- ['%<search_sql>s >= ?', from_value.to_s(:db)]
324
+ ['%<search_sql>s >= ?', from_value]
325
325
  else
326
- ['%<search_sql>s BETWEEN ? AND ?', from_value.to_s(:db), to_value.to_s(:db)]
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) && v.attributes.include?(column.name)
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}#numerical_constarints") do
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)
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 6
5
- PATCH = 8
5
+ PATCH = 11
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
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.8
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-03-30 00:00:00.000000000 Z
11
+ date: 2022-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails