active_scaffold 3.0.12 → 3.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. data/README +21 -11
  2. data/frontends/default/images/close_touch.png +0 -0
  3. data/frontends/default/javascripts/jquery/active_scaffold.js +187 -99
  4. data/frontends/default/javascripts/prototype/active_scaffold.js +105 -33
  5. data/frontends/default/javascripts/prototype/dhtml_history.js +80 -77
  6. data/frontends/default/stylesheets/stylesheet.css +121 -2
  7. data/frontends/default/views/_action_group.html.erb +6 -2
  8. data/frontends/default/views/_base_form.html.erb +11 -5
  9. data/frontends/default/views/_base_form.html.erb~ +42 -0
  10. data/frontends/default/views/_field_search.html.erb +1 -1
  11. data/frontends/default/views/_form.html.erb +9 -7
  12. data/frontends/default/views/_form_association.html.erb +8 -3
  13. data/frontends/default/views/_form_association_footer.html.erb +10 -3
  14. data/frontends/default/views/_form_attribute.html.erb +8 -3
  15. data/frontends/default/views/_horizontal_subform.html.erb +12 -2
  16. data/frontends/default/views/_horizontal_subform_header.html.erb +1 -1
  17. data/frontends/default/views/_horizontal_subform_record.html.erb +5 -4
  18. data/frontends/default/views/_list_messages.html.erb +1 -1
  19. data/frontends/default/views/_list_with_header.html.erb +1 -1
  20. data/frontends/default/views/_render_field.js.rjs +4 -6
  21. data/frontends/default/views/_vertical_subform.html.erb +1 -1
  22. data/frontends/default/views/_vertical_subform_record.html.erb +2 -2
  23. data/frontends/default/views/on_action_update.js.rjs +3 -1
  24. data/frontends/default/views/on_mark_all.js.rjs +12 -0
  25. data/frontends/default/views/on_update.js.rjs +1 -1
  26. data/frontends/default/views/render_field.js.rjs +1 -0
  27. data/frontends/default/views/update_column.js.rjs +1 -1
  28. data/lib/active_scaffold.rb +60 -21
  29. data/lib/active_scaffold/actions/common_search.rb +2 -2
  30. data/lib/active_scaffold/actions/core.rb +30 -9
  31. data/lib/active_scaffold/actions/create.rb +14 -10
  32. data/lib/active_scaffold/actions/field_search.rb +6 -6
  33. data/lib/active_scaffold/actions/list.rb +22 -12
  34. data/lib/active_scaffold/actions/mark.rb +34 -9
  35. data/lib/active_scaffold/actions/nested.rb +12 -16
  36. data/lib/active_scaffold/actions/show.rb +2 -2
  37. data/lib/active_scaffold/actions/subform.rb +15 -8
  38. data/lib/active_scaffold/actions/update.rb +14 -4
  39. data/lib/active_scaffold/attribute_params.rb +15 -10
  40. data/lib/active_scaffold/bridges/bridge.rb +21 -12
  41. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +3 -3
  42. data/lib/active_scaffold/bridges/cancan/bridge.rb +12 -0
  43. data/lib/active_scaffold/bridges/cancan/lib/cancan_bridge.rb +107 -0
  44. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +1 -1
  45. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +3 -8
  46. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +1 -15
  47. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +23 -13
  48. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +1 -1
  49. data/lib/active_scaffold/bridges/country_helper/bridge.rb +9 -0
  50. data/lib/active_scaffold/bridges/country_helper/lib/country_helper_bridge.rb +358 -0
  51. data/lib/active_scaffold/bridges/date_picker/bridge.rb +5 -3
  52. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +9 -0
  53. data/lib/active_scaffold/bridges/dragonfly/bridge.rb +9 -0
  54. data/lib/active_scaffold/bridges/dragonfly/bridge.rb~ +12 -0
  55. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb +36 -0
  56. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb~ +36 -0
  57. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb +12 -0
  58. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb~ +12 -0
  59. data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb +27 -0
  60. data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb~ +27 -0
  61. data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb +16 -0
  62. data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb~ +16 -0
  63. data/lib/active_scaffold/bridges/paperclip/bridge.rb +1 -1
  64. data/lib/active_scaffold/bridges/record_select/bridge.rb +5 -0
  65. data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb +87 -0
  66. data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb~ +84 -0
  67. data/lib/active_scaffold/bridges/shared/date_bridge.rb +56 -34
  68. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +19 -3
  69. data/lib/active_scaffold/config/base.rb +4 -4
  70. data/lib/active_scaffold/config/core.rb +4 -0
  71. data/lib/active_scaffold/config/create.rb +1 -1
  72. data/lib/active_scaffold/config/field_search.rb +7 -7
  73. data/lib/active_scaffold/config/form.rb +8 -2
  74. data/lib/active_scaffold/config/list.rb +22 -8
  75. data/lib/active_scaffold/config/mark.rb +18 -5
  76. data/lib/active_scaffold/config/nested.rb +3 -3
  77. data/lib/active_scaffold/config/search.rb +1 -1
  78. data/lib/active_scaffold/config/show.rb +1 -1
  79. data/lib/active_scaffold/data_structures/action_columns.rb +10 -6
  80. data/lib/active_scaffold/data_structures/action_link.rb +14 -10
  81. data/lib/active_scaffold/data_structures/action_links.rb +2 -2
  82. data/lib/active_scaffold/data_structures/column.rb +25 -11
  83. data/lib/active_scaffold/data_structures/nested_info.rb +21 -21
  84. data/lib/active_scaffold/data_structures/set.rb +2 -3
  85. data/lib/active_scaffold/data_structures/sorting.rb +8 -8
  86. data/lib/{extensions → active_scaffold/extensions}/action_controller_rendering.rb +3 -1
  87. data/lib/{extensions → active_scaffold/extensions}/action_view_rendering.rb +31 -33
  88. data/lib/{extensions → active_scaffold/extensions}/action_view_resolver.rb +0 -0
  89. data/lib/{extensions → active_scaffold/extensions}/active_association_reflection.rb +0 -0
  90. data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
  91. data/lib/{extensions → active_scaffold/extensions}/array.rb +0 -0
  92. data/lib/{extensions → active_scaffold/extensions}/localize.rb +1 -1
  93. data/lib/{extensions → active_scaffold/extensions}/name_option_for_datetime.rb +1 -1
  94. data/lib/{extensions → active_scaffold/extensions}/nil_id_in_url_params.rb +0 -0
  95. data/lib/{extensions → active_scaffold/extensions}/paginator_extensions.rb +2 -2
  96. data/lib/{extensions → active_scaffold/extensions}/reverse_associations.rb +1 -1
  97. data/lib/{extensions → active_scaffold/extensions}/routing_mapper.rb +2 -2
  98. data/lib/{extensions → active_scaffold/extensions}/to_label.rb +0 -0
  99. data/lib/{extensions → active_scaffold/extensions}/unsaved_associated.rb +0 -0
  100. data/lib/{extensions → active_scaffold/extensions}/unsaved_record.rb +0 -0
  101. data/lib/active_scaffold/extensions/usa_state.rb +46 -0
  102. data/lib/active_scaffold/finder.rb +30 -19
  103. data/lib/active_scaffold/helpers/controller_helpers.rb +3 -5
  104. data/lib/active_scaffold/helpers/form_column_helpers.rb +19 -45
  105. data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
  106. data/lib/active_scaffold/helpers/id_helpers.rb +2 -2
  107. data/lib/active_scaffold/helpers/list_column_helpers.rb +28 -17
  108. data/lib/active_scaffold/helpers/search_column_helpers.rb +51 -40
  109. data/lib/active_scaffold/helpers/search_column_helpers.rb~ +215 -0
  110. data/lib/active_scaffold/helpers/show_column_helpers.rb +8 -4
  111. data/lib/active_scaffold/helpers/view_helpers.rb +50 -27
  112. data/lib/active_scaffold/locale/de.yml +111 -0
  113. data/lib/active_scaffold/locale/en.yml +115 -0
  114. data/lib/active_scaffold/locale/es.yml +32 -32
  115. data/lib/active_scaffold/locale/fr.yml +118 -0
  116. data/lib/active_scaffold/marked_model.rb +6 -6
  117. data/lib/active_scaffold/version.rb +1 -1
  118. data/lib/active_scaffold_assets.rb +1 -3
  119. data/lib/active_scaffold_env.rb +1 -2
  120. data/lib/generators/active_scaffold/active_scaffold_generator.rb +5 -5
  121. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +3 -2
  122. data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
  123. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +17 -19
  124. data/shoulda_macros/macros.rb +4 -4
  125. data/test/misc/finder_test.rb +2 -2
  126. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +4 -1
  127. metadata +144 -126
  128. data/.autotest +0 -27
  129. data/.document +0 -5
  130. data/Gemfile +0 -13
  131. data/Gemfile.lock +0 -20
  132. data/Rakefile +0 -53
  133. data/active_scaffold.gemspec +0 -385
  134. data/init.rb +0 -2
  135. data/lib/active_scaffold/helpers/country_helpers.rb +0 -358
  136. data/lib/active_scaffold/locale/de.rb +0 -120
  137. data/lib/active_scaffold/locale/en.rb +0 -119
  138. data/lib/active_scaffold/locale/fr.rb +0 -116
  139. data/lib/extensions/active_record_offset.rb +0 -12
  140. data/lib/extensions/usa_state.rb +0 -50
  141. data/test/mock_app/.gitignore +0 -2
  142. data/uninstall.rb +0 -13
@@ -0,0 +1,12 @@
1
+ # Bugfix: Team.offset(1).limit(1) throws an error
2
+ ActiveRecord::Base.instance_eval do
3
+ def offset(*args, &block)
4
+ scoped.__send__(:offset, *args, &block)
5
+ rescue NoMethodError
6
+ if scoped.nil?
7
+ 'depends on :allow_nil'
8
+ else
9
+ raise
10
+ end
11
+ end
12
+ end
@@ -4,7 +4,7 @@ class Object
4
4
  text = I18n.translate "#{key}", {:scope => [:active_scaffold], :default => key.is_a?(String) ? key : key.to_s.titleize}.merge(options)
5
5
  # text = nil if text.include?('translation missing:')
6
6
  end
7
- text ||= key
7
+ text ||= key
8
8
  text
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module ActionView
4
4
  private
5
5
  def datetime_selector_with_name(options, html_options)
6
6
  options.merge!(:prefix => options[:name].gsub(/\[[^\[]*\]$/,'')) if options[:name]
7
- datetime_selector_without_name(options, html_options)
7
+ datetime_selector_without_name(options, html_options)
8
8
  end
9
9
  alias_method_chain :datetime_selector, :name
10
10
  end
@@ -7,12 +7,12 @@ class Paginator
7
7
  number_of_pages_without_infinite unless infinite?
8
8
  end
9
9
  alias_method_chain :number_of_pages, :infinite
10
-
10
+
11
11
  # Is this an "infinite" paginator
12
12
  def infinite?
13
13
  @count.nil?
14
14
  end
15
-
15
+
16
16
  class Page
17
17
  # Checks to see if there's a page after this one
18
18
  def next_with_infinite?
@@ -2,7 +2,7 @@ module ActiveRecord
2
2
  module Reflection
3
3
  class AssociationReflection #:nodoc:
4
4
  def reverse_for?(klass)
5
- ! reverse_matches_for(klass).empty?
5
+ reverse_matches_for(klass).empty? ? false : true
6
6
  end
7
7
 
8
8
  attr_writer :reverse
@@ -19,9 +19,9 @@ module ActionDispatch
19
19
  end
20
20
  as_association_routes if options[:association]
21
21
  end
22
-
22
+
23
23
  def as_association_routes
24
- collection do
24
+ collection do
25
25
  ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:collection].each {|name, type| send(type, name)}
26
26
  end
27
27
  member do
@@ -0,0 +1,46 @@
1
+ module ActionView
2
+ module Helpers
3
+ module FormOptionsHelper
4
+
5
+ # Return a full select and option tags for the given object and method, using usa_state_options_for_select to generate the list of option <tags>.
6
+ def usa_state_select(object, method, priority_states = nil, options = {}, html_options = {})
7
+ InstanceTag.new(object, method, self, options.delete(:object)).to_usa_state_select_tag(priority_states, options, html_options)
8
+ end
9
+
10
+
11
+ # Returns a string of option tags for the states in the United States. Supply a state name as +selected to
12
+ # have it marked as the selected option tag. Included also is the option to set a couple of +priority_states+
13
+ # in case you want to highligh a local area
14
+ # NOTE: Only the option tags are returned from this method, wrap it in a <select>
15
+ def usa_state_options_for_select(selected = nil, priority_states = nil)
16
+ state_options = ""
17
+ if priority_states
18
+ state_options += options_for_select(priority_states, selected)
19
+ state_options += "<option>-------------</option>\n"
20
+ end
21
+
22
+ if priority_states && priority_states.include?(selected)
23
+ state_options += options_for_select(USASTATES - priority_states, selected)
24
+ else
25
+ state_options += options_for_select(USASTATES, selected)
26
+ end
27
+
28
+ return state_options
29
+ end
30
+
31
+ USASTATES = [["Alabama", "AL"], ["Alaska", "AK"], ["Arizona", "AZ"], ["Arkansas", "AR"], ["California", "CA"], ["Colorado", "CO"], ["Connecticut", "CT"], ["Delaware", "DE"], ["District of Columbia", "DC"], ["Florida", "FL"], ["Georgia", "GA"], ["Hawaii", "HI"], ["Idaho", "ID"], ["Illinois", "IL"], ["Indiana", "IN"], ["Iowa", "IA"], ["Kansas", "KS"], ["Kentucky", "KY"], ["Louisiana", "LA"], ["Maine", "ME"], ["Maryland", "MD"], ["Massachusetts", "MA"], ["Michigan", "MI"], ["Minnesota", "MN"], ["Mississippi", "MS"], ["Missouri", "MO"], ["Montana", "MT"], ["Nebraska", "NE"], ["Nevada", "NV"], ["New Hampshire", "NH"], ["New Jersey", "NJ"], ["New Mexico", "NM"], ["New York", "NY"], ["North Carolina", "NC"], ["North Dakota", "ND"], ["Ohio", "OH"], ["Oklahoma", "OK"], ["Oregon", "OR"], ["Pennsylvania", "PA"], ["Rhode Island", "RI"], ["South Carolina", "SC"], ["South Dakota", "SD"], ["Tennessee", "TN"], ["Texas", "TX"], ["Utah", "UT"], ["Vermont", "VT"], ["Virginia", "VA"], ["Washington", "WA"], ["Wisconsin", "WI"], ["West Virginia", "WV"], ["Wyoming", "WY"]] unless const_defined?("USASTATES")
32
+
33
+ end
34
+
35
+ class InstanceTag #:nodoc:
36
+ include FormOptionsHelper
37
+
38
+ def to_usa_state_select_tag(priority_states, options, html_options)
39
+ html_options = html_options.stringify_keys
40
+ add_default_name_and_id(html_options)
41
+ value = value(object) if method(:value).arity > 0
42
+ content_tag("select", add_options(usa_state_options_for_select(value, priority_states), options, value), html_options)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,9 @@
1
1
  module ActiveScaffold
2
2
  module Finder
3
+ def self.like_operator
4
+ @@like_operator ||= ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
5
+ end
6
+
3
7
  module ClassMethods
4
8
  # Takes a collection of search terms (the tokens) and creates SQL that
5
9
  # searches all specified ActiveScaffold columns. A row will match if each
@@ -13,13 +17,13 @@ module ActiveScaffold
13
17
 
14
18
  where_clauses = []
15
19
  columns.each do |column|
16
- where_clauses << ((column.column.nil? || column.column.text?) ? "LOWER(#{column.search_sql}) LIKE ?" : "#{column.search_sql} = ?")
20
+ where_clauses << ((column.column.nil? || column.column.text?) ? "#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?" : "#{column.search_sql} = ?")
17
21
  end
18
22
  phrase = "(#{where_clauses.join(' OR ')})"
19
23
 
20
24
  sql = ([phrase] * tokens.length).join(' AND ')
21
25
  tokens = tokens.collect do |value|
22
- columns.collect {|column| (column.column.nil? || column.column.text?) ? like_pattern.sub('?', value.downcase) : column.column.type_cast(value)}
26
+ columns.collect {|column| (column.column.nil? || column.column.text?) ? like_pattern.sub('?', value) : column.column.type_cast(value)}
23
27
  end.flatten
24
28
 
25
29
  [sql, *tokens]
@@ -52,7 +56,7 @@ module ActiveScaffold
52
56
  ["#{column.search_sql} in (?)", Array(value)]
53
57
  else
54
58
  if column.column.nil? || column.column.text?
55
- ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
59
+ ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
56
60
  else
57
61
  ["#{column.search_sql} = ?", column.column.type_cast(value)]
58
62
  end
@@ -62,7 +66,7 @@ module ActiveScaffold
62
66
  end
63
67
  end
64
68
  rescue Exception => e
65
- logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{@controller.class}"
69
+ logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{self.name}"
66
70
  raise e
67
71
  end
68
72
  end
@@ -82,10 +86,12 @@ module ActiveScaffold
82
86
  def condition_for_range(column, value, like_pattern = nil)
83
87
  if !value.is_a?(Hash)
84
88
  if column.column.nil? || column.column.text?
85
- ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
89
+ ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
86
90
  else
87
91
  ["#{column.search_sql} = ?", column.column.type_cast(value)]
88
92
  end
93
+ elsif ActiveScaffold::Finder::NullComparators.include?(value[:opt])
94
+ condition_for_null_type(column, value[:opt], like_pattern)
89
95
  elsif value[:from].blank?
90
96
  nil
91
97
  elsif ActiveScaffold::Finder::StringComparators.values.include?(value[:opt])
@@ -98,7 +104,7 @@ module ActiveScaffold
98
104
  nil
99
105
  end
100
106
  end
101
-
107
+
102
108
  def condition_value_for_datetime(value, conversion = :to_time)
103
109
  if value.is_a? Hash
104
110
  Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[field][part].to_i}) rescue nil
@@ -132,7 +138,7 @@ module ActiveScaffold
132
138
  value
133
139
  end
134
140
  end
135
-
141
+
136
142
  def condition_for_datetime(column, value, like_pattern = nil)
137
143
  conversion = column.column.type == :date ? :to_date : :to_time
138
144
  from_value = condition_value_for_datetime(value[:from], conversion)
@@ -156,7 +162,7 @@ module ActiveScaffold
156
162
  ["#{column.search_sql} = ?", value]
157
163
  end
158
164
  end
159
-
165
+
160
166
  def condition_for_null_type(column, value, like_pattern = nil)
161
167
  case value.to_sym
162
168
  when :null
@@ -196,8 +202,8 @@ module ActiveScaffold
196
202
  :null,
197
203
  :not_null
198
204
  ]
199
-
200
-
205
+
206
+
201
207
 
202
208
  def self.included(klass)
203
209
  klass.extend ClassMethods
@@ -219,7 +225,7 @@ module ActiveScaffold
219
225
  def active_scaffold_habtm_joins
220
226
  @active_scaffold_habtm_joins ||= []
221
227
  end
222
-
228
+
223
229
  def all_conditions
224
230
  merge_conditions(
225
231
  active_scaffold_conditions, # from the search modules
@@ -229,7 +235,7 @@ module ActiveScaffold
229
235
  active_scaffold_session_storage[:conditions] # embedding conditions (weaker constraints)
230
236
  )
231
237
  end
232
-
238
+
233
239
  # returns a single record (the given id) but only if it's allowed for the specified action.
234
240
  # accomplishes this by checking model.#{action}_authorized?
235
241
  # TODO: this should reside on the model, not the controller
@@ -255,19 +261,19 @@ module ActiveScaffold
255
261
  options[:count_includes] ||= full_includes unless search_conditions.nil?
256
262
 
257
263
  klass = beginning_of_chain
258
-
264
+
259
265
  # create a general-use options array that's compatible with Rails finders
260
266
  finder_options = { :order => options[:sorting].try(:clause),
261
267
  :where => search_conditions,
262
268
  :joins => joins_for_finder,
263
269
  :includes => options[:count_includes]}
264
-
270
+
265
271
  finder_options.merge! custom_finder_options
266
272
 
267
273
  # NOTE: we must use :include in the count query, because some conditions may reference other tables
268
274
  count_query = append_to_query(klass, finder_options.reject{|k, v| [:select, :order].include?(k)})
269
275
  count = count_query.count unless options[:pagination] == :infinite
270
-
276
+
271
277
  # Converts count to an integer if ActiveRecord returned an OrderedHash
272
278
  # that happens when finder_options contains a :group key
273
279
  count = count.length if count.is_a? ActiveSupport::OrderedHash
@@ -288,12 +294,17 @@ module ActiveScaffold
288
294
  end
289
295
  pager.page(options[:page])
290
296
  end
291
-
297
+
292
298
  def append_to_query(query, options)
293
299
  options.assert_valid_keys :where, :select, :group, :order, :limit, :offset, :joins, :includes, :lock, :readonly, :from
294
300
  options.reject{|k, v| v.blank?}.inject(query) do |query, (k, v)|
295
- query = query.except(:order) if k.to_sym == :order
296
- query.send((k.to_sym), v)
301
+ # default ordering of model has a higher priority than current queries ordering
302
+ # fix this by removing existing ordering from arel
303
+ if k.to_sym == :order
304
+ query = query.where('1=1') unless query.is_a?(ActiveRecord::Relation)
305
+ query = query.except(:order)
306
+ end
307
+ query.send((k.to_sym), v)
297
308
  end
298
309
  end
299
310
 
@@ -307,7 +318,7 @@ module ActiveScaffold
307
318
  []
308
319
  end + active_scaffold_habtm_joins
309
320
  end
310
-
321
+
311
322
  def merge_conditions(*conditions)
312
323
  segments = []
313
324
  conditions.each do |condition|
@@ -4,9 +4,9 @@ module ActiveScaffold
4
4
  def self.included(controller)
5
5
  controller.class_eval { helper_method :params_for, :main_path_to_return, :render_parent?, :render_parent_options, :render_parent_action, :nested_singular_association?}
6
6
  end
7
-
7
+
8
8
  include ActiveScaffold::Helpers::IdHelpers
9
-
9
+
10
10
  def params_for(options = {})
11
11
  # :adapter and :position are one-use rendering arguments. they should not propagate.
12
12
  # :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
@@ -22,9 +22,7 @@ module ActiveScaffold
22
22
  @params_for.merge(options)
23
23
  end
24
24
 
25
- # Parameters to generate url to the main page (override if the
26
- # ActiveScaffold is used as a component on another controllers
27
- # page)
25
+ # Parameters to generate url to the main page (override if the ActiveScaffold is used as a component on another controllers page)
28
26
  def main_path_to_return
29
27
  if params[:return_to]
30
28
  params[:return_to]
@@ -31,6 +31,7 @@ module ActiveScaffold
31
31
  raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
32
32
  end
33
33
  elsif column.virtual?
34
+ options[:value] = format_number_value(@record.send(column.name), column.options) if column.number?
34
35
  active_scaffold_input_virtual(column, options)
35
36
 
36
37
  else # regular model attribute column
@@ -47,7 +48,7 @@ module ActiveScaffold
47
48
  options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"]
48
49
  end
49
50
  options[:include_blank] = true if column.column.null and [:date, :datetime, :time].include?(column.column.type)
50
- options[:value] = format_number_value(@record.send(column.name), column.options) if column.column.number?
51
+ options[:value] = format_number_value(@record.send(column.name), column.options) if column.number?
51
52
  text_field(:record, column.name, options.merge(column.options))
52
53
  end
53
54
  end
@@ -79,13 +80,14 @@ module ActiveScaffold
79
80
  def update_columns_options(column, scope, options)
80
81
  if column.update_columns
81
82
  form_action = params[:action] == 'edit' ? :update : :create
82
- url_params = {:action => 'render_field', :id => params[:id], :column => column.name, :update_columns => column.update_columns}
83
+ url_params = {:action => 'render_field', :id => params[:id], :column => column.name}
83
84
  url_params[:eid] = params[:eid] if params[:eid]
84
85
  url_params[:controller] = controller.class.active_scaffold_controller_for(@record.class).controller_path if scope
85
- url_params[:scope] = params[:scope] if scope
86
+ url_params[:scope] = scope if scope
86
87
 
87
88
  options[:class] = "#{options[:class]} update_form".strip
88
89
  options['data-update_url'] = url_for(url_params)
90
+ options['data-update_send_form'] = true if column.send_form_on_update_column
89
91
  end
90
92
  options
91
93
  end
@@ -107,6 +109,7 @@ module ActiveScaffold
107
109
 
108
110
  html_options.update(column.options[:html_options] || {})
109
111
  options.update(column.options)
112
+ html_options[:name] = "#{html_options[:name]}[]" if (html_options[:multiple] == true && !html_options[:name].to_s.ends_with?("[]"))
110
113
  select(:record, method, select_options.uniq, options, html_options)
111
114
  end
112
115
 
@@ -117,14 +120,14 @@ module ActiveScaffold
117
120
 
118
121
  active_scaffold_checkbox_list(column, select_options, associated_options.collect {|a| a[1]}, options)
119
122
  end
120
-
123
+
121
124
  def active_scaffold_checkbox_list(column, select_options, associated_ids, options)
122
125
  html = "<ul class=\"checkbox-list\" id=\"#{options[:id]}\">"
123
-
126
+
124
127
  select_options.each_with_index do |option, i|
125
128
  label, id = option
126
129
  this_id = "#{options[:id]}_#{i}_id"
127
- html << content_tag(:li) do
130
+ html << content_tag(:li) do
128
131
  check_box_tag("#{options[:name]}[]", id, associated_ids.include?(id), :id => this_id) <<
129
132
  content_tag(:label, h(label), :for => this_id)
130
133
  end
@@ -135,7 +138,7 @@ module ActiveScaffold
135
138
  end
136
139
 
137
140
  def active_scaffold_translated_option(column, text, value = nil)
138
- value ||= text
141
+ value = text if value.nil?
139
142
  [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value]
140
143
  end
141
144
 
@@ -167,39 +170,6 @@ module ActiveScaffold
167
170
  end.html_safe
168
171
  end
169
172
 
170
- # requires RecordSelect plugin to be installed and configured.
171
- # ... maybe this should be provided in a bridge?
172
- def active_scaffold_input_record_select(column, options)
173
- if column.singular_association?
174
- active_scaffold_record_select(column, options, @record.send(column.name), false)
175
- elsif column.plural_association?
176
- active_scaffold_record_select(column, options, @record.send(column.name), true)
177
- end
178
- end
179
-
180
- def active_scaffold_record_select(column, options, value, multiple)
181
- unless column.association
182
- raise ArgumentError, "record_select can only work against associations (and #{column.name} is not). A common mistake is to specify the foreign key field (like :user_id), instead of the association (:user)."
183
- end
184
- remote_controller = active_scaffold_controller_for(column.association.klass).controller_path
185
-
186
- # if the opposite association is a :belongs_to (in that case association in this class must be has_one or has_many)
187
- # then only show records that have not been associated yet
188
- if [:has_one, :has_many].include?(column.association.macro)
189
- params.merge!({column.association.primary_key_name => ''})
190
- end
191
-
192
- record_select_options = {:controller => remote_controller, :id => options[:id]}
193
- record_select_options.merge!(active_scaffold_input_text_options)
194
- record_select_options.merge!(column.options)
195
-
196
- if multiple
197
- record_multi_select_field(options[:name], value || [], record_select_options)
198
- else
199
- record_select_field(options[:name], value || column.association.klass.new, record_select_options)
200
- end
201
- end
202
-
203
173
  def active_scaffold_input_checkbox(column, options)
204
174
  check_box(:record, column.name, options)
205
175
  end
@@ -212,7 +182,7 @@ module ActiveScaffold
212
182
  def active_scaffold_input_textarea(column, options)
213
183
  text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size]))
214
184
  end
215
-
185
+
216
186
  def active_scaffold_input_virtual(column, options)
217
187
  options = active_scaffold_input_text_options(options)
218
188
  text_field :record, column.name, options.merge(column.options)
@@ -258,13 +228,17 @@ module ActiveScaffold
258
228
  "#{column.name}_form_column"
259
229
  end
260
230
 
261
- def override_form_field?(column)
262
- respond_to?(override_form_field(column))
231
+ def override_form_field(column)
232
+ method_with_class = override_form_field_name(column, true)
233
+ return method_with_class if respond_to?(method_with_class)
234
+ method = override_form_field_name(column)
235
+ method if respond_to?(method)
263
236
  end
237
+ alias_method :override_form_field?, :override_form_field
264
238
 
265
239
  # the naming convention for overriding form fields with helpers
266
- def override_form_field(column)
267
- "#{column.name}_form_column"
240
+ def override_form_field_name(column, class_prefix = false)
241
+ "#{clean_class_name(column.active_record_class.name) + '_' if class_prefix}#{clean_column_name(column.name)}_form_column"
268
242
  end
269
243
 
270
244
  def override_input?(form_ui)