active_scaffold 3.2.20 → 3.3.0.rc

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 (152) hide show
  1. data/CHANGELOG +19 -13
  2. data/README +66 -0
  3. data/app/assets/javascripts/jquery/active_scaffold.js +156 -113
  4. data/app/assets/javascripts/jquery/active_scaffold_chosen.js +11 -0
  5. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +0 -1
  6. data/app/assets/javascripts/jquery/jquery.editinplace.js +132 -128
  7. data/app/assets/javascripts/prototype/active_scaffold.js +68 -25
  8. data/{frontends/default/views/_horizontal_subform_footer.html.erb → app/assets/javascripts/prototype/active_scaffold_chosen.js} +0 -0
  9. data/app/assets/stylesheets/active_scaffold_colors.css.scss +8 -1
  10. data/app/assets/stylesheets/active_scaffold_layout.css +14 -8
  11. data/{frontends/default/views → app/views/active_scaffold_overrides}/_add_existing_form.html.erb +0 -0
  12. data/{frontends/default/views → app/views/active_scaffold_overrides}/_base_form.html.erb +0 -0
  13. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form.html.erb +0 -0
  14. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form_on_list.html.erb +0 -0
  15. data/{frontends/default/views → app/views/active_scaffold_overrides}/_field_search.html.erb +0 -0
  16. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form.html.erb +0 -0
  17. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association.html.erb +8 -3
  18. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association_footer.html.erb +5 -4
  19. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +85 -0
  20. data/app/views/active_scaffold_overrides/_form_attribute.html.erb +23 -0
  21. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_hidden_attribute.html.erb +0 -0
  22. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_messages.html.erb +0 -0
  23. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +12 -0
  24. data/app/views/active_scaffold_overrides/_horizontal_subform_footer.html.erb +0 -0
  25. data/{frontends/default/views → app/views/active_scaffold_overrides}/_horizontal_subform_header.html.erb +3 -2
  26. data/{frontends/default/views → app/views/active_scaffold_overrides}/_human_conditions.html.erb +0 -0
  27. data/app/views/active_scaffold_overrides/_list.html.erb +35 -0
  28. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_calculations.html.erb +0 -0
  29. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_column_headings.html.erb +0 -0
  30. data/app/views/active_scaffold_overrides/_list_header.html.erb +8 -0
  31. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_inline_adapter.html.erb +0 -0
  32. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_messages.html.erb +4 -4
  33. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination.html.erb +0 -0
  34. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination_links.html.erb +0 -0
  35. data/app/views/active_scaffold_overrides/_list_record.html.erb +30 -0
  36. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_with_header.html.erb +0 -0
  37. data/{frontends/default/views → app/views/active_scaffold_overrides}/_messages.html.erb +0 -0
  38. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -0
  39. data/{frontends/default/views → app/views/active_scaffold_overrides}/_render_field.js.erb +9 -1
  40. data/{frontends/default/views → app/views/active_scaffold_overrides}/_row.html.erb +0 -0
  41. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search.html.erb +0 -0
  42. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search_attribute.html.erb +0 -0
  43. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show.html.erb +0 -0
  44. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show_columns.html.erb +0 -0
  45. data/app/views/active_scaffold_overrides/_update_actions.html.erb +9 -0
  46. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_calculations.js.erb +0 -0
  47. data/app/views/active_scaffold_overrides/_update_column.js.erb +16 -0
  48. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_form.html.erb +0 -0
  49. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_messages.js.erb +0 -0
  50. data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +8 -0
  51. data/{frontends/default/views → app/views/active_scaffold_overrides}/action_confirmation.html.erb +0 -0
  52. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing.js.erb +0 -0
  53. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing_form.html.erb +0 -0
  54. data/{frontends/default/views → app/views/active_scaffold_overrides}/create.html.erb +0 -0
  55. data/{frontends/default/views → app/views/active_scaffold_overrides}/delete.html.erb +0 -0
  56. data/{frontends/default/views → app/views/active_scaffold_overrides}/destroy.js.erb +0 -0
  57. data/{frontends/default/views → app/views/active_scaffold_overrides}/edit_associated.js.erb +1 -1
  58. data/{frontends/default/views → app/views/active_scaffold_overrides}/field_search.html.erb +0 -0
  59. data/{frontends/default/views → app/views/active_scaffold_overrides}/form_messages.js.erb +0 -0
  60. data/{frontends/default/views → app/views/active_scaffold_overrides}/list.html.erb +0 -0
  61. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_action_update.js.erb +3 -3
  62. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_create.js.erb +1 -1
  63. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_mark.js.erb +0 -0
  64. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_update.js.erb +4 -4
  65. data/{frontends/default/views → app/views/active_scaffold_overrides}/render_field.js.erb +0 -0
  66. data/{frontends/default/views → app/views/active_scaffold_overrides}/row.js.erb +1 -1
  67. data/{frontends/default/views → app/views/active_scaffold_overrides}/search.html.erb +0 -0
  68. data/{frontends/default/views → app/views/active_scaffold_overrides}/show.html.erb +0 -0
  69. data/{frontends/default/views → app/views/active_scaffold_overrides}/update.html.erb +1 -1
  70. data/app/views/active_scaffold_overrides/update_column.js.erb +26 -0
  71. data/{frontends/default/views → app/views/active_scaffold_overrides}/update_row.js.erb +0 -0
  72. data/config/locales/de.yml +1 -0
  73. data/config/locales/en.yml +1 -0
  74. data/config/locales/es.yml +1 -0
  75. data/config/locales/fr.yml +1 -0
  76. data/config/locales/hu.yml +1 -0
  77. data/config/locales/ja.yml +1 -0
  78. data/config/locales/ru.yml +1 -0
  79. data/lib/active_scaffold.rb +14 -26
  80. data/lib/active_scaffold/actions/core.rb +14 -11
  81. data/lib/active_scaffold/actions/create.rb +3 -3
  82. data/lib/active_scaffold/actions/delete.rb +3 -0
  83. data/lib/active_scaffold/actions/list.rb +9 -6
  84. data/lib/active_scaffold/actions/mark.rb +1 -1
  85. data/lib/active_scaffold/actions/nested.rb +8 -6
  86. data/lib/active_scaffold/actions/show.rb +6 -1
  87. data/lib/active_scaffold/actions/update.rb +39 -19
  88. data/lib/active_scaffold/active_record_permissions.rb +29 -12
  89. data/lib/active_scaffold/attribute_params.rb +14 -7
  90. data/lib/active_scaffold/bridges/calendar_date_select.rb +1 -1
  91. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +1 -2
  92. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  93. data/lib/active_scaffold/bridges/chosen.rb +14 -0
  94. data/lib/active_scaffold/bridges/chosen/helpers.rb +48 -0
  95. data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -6
  96. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +1 -1
  97. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
  98. data/lib/active_scaffold/bridges/file_column.rb +1 -1
  99. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
  100. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +2 -2
  101. data/lib/active_scaffold/bridges/file_column/list_ui.rb +4 -4
  102. data/lib/active_scaffold/bridges/paperclip.rb +1 -1
  103. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +1 -1
  104. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  105. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +1 -1
  106. data/lib/active_scaffold/bridges/shared/date_bridge.rb +1 -1
  107. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -1
  108. data/lib/active_scaffold/config/core.rb +9 -2
  109. data/lib/active_scaffold/config/list.rb +9 -13
  110. data/lib/active_scaffold/config/nested.rb +11 -2
  111. data/lib/active_scaffold/data_structures/action_columns.rb +19 -5
  112. data/lib/active_scaffold/data_structures/action_link.rb +9 -2
  113. data/lib/active_scaffold/data_structures/action_links.rb +5 -36
  114. data/lib/active_scaffold/data_structures/column.rb +21 -21
  115. data/lib/active_scaffold/data_structures/nested_info.rb +31 -44
  116. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -0
  117. data/lib/active_scaffold/extensions/action_view_rendering.rb +30 -36
  118. data/lib/active_scaffold/extensions/reverse_associations.rb +10 -6
  119. data/lib/active_scaffold/extensions/routing_mapper.rb +6 -5
  120. data/lib/active_scaffold/extensions/unsaved_associated.rb +1 -1
  121. data/lib/active_scaffold/finder.rb +18 -10
  122. data/lib/active_scaffold/helpers/association_helpers.rb +21 -2
  123. data/lib/active_scaffold/helpers/controller_helpers.rb +14 -16
  124. data/lib/active_scaffold/helpers/form_column_helpers.rb +161 -21
  125. data/lib/active_scaffold/helpers/id_helpers.rb +7 -7
  126. data/lib/active_scaffold/helpers/list_column_helpers.rb +42 -92
  127. data/lib/active_scaffold/helpers/search_column_helpers.rb +10 -3
  128. data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -9
  129. data/lib/active_scaffold/helpers/view_helpers.rb +278 -78
  130. data/lib/active_scaffold/version.rb +2 -2
  131. data/lib/generators/active_scaffold_controller/templates/controller.rb +1 -1
  132. data/test/bridges/paperclip_test.rb +2 -2
  133. data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1882 -1276
  134. metadata +79 -80
  135. data/README.md +0 -67
  136. data/frontends/default/views/_action_group.html.erb +0 -24
  137. data/frontends/default/views/_form_attribute.html.erb +0 -23
  138. data/frontends/default/views/_horizontal_subform.html.erb +0 -22
  139. data/frontends/default/views/_horizontal_subform_record.html.erb +0 -43
  140. data/frontends/default/views/_list.html.erb +0 -18
  141. data/frontends/default/views/_list_actions.html.erb +0 -15
  142. data/frontends/default/views/_list_header.html.erb +0 -10
  143. data/frontends/default/views/_list_record.html.erb +0 -13
  144. data/frontends/default/views/_list_record_columns.html.erb +0 -8
  145. data/frontends/default/views/_refresh_list.js.erb +0 -1
  146. data/frontends/default/views/_update_actions.html.erb +0 -9
  147. data/frontends/default/views/_vertical_subform.html.erb +0 -12
  148. data/frontends/default/views/_vertical_subform_record.html.erb +0 -43
  149. data/frontends/default/views/refresh_list.js.erb +0 -2
  150. data/frontends/default/views/update_column.js.erb +0 -15
  151. data/lib/active_scaffold/extensions/active_record_offset.rb +0 -12
  152. data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +0 -7
@@ -12,7 +12,7 @@ module ActiveScaffold::Bridges
12
12
  /%m/ => 'mm',
13
13
  /%y/ => 'y',
14
14
  /%Y/ => 'yy',
15
- /%H/ => 'hh', # options ampm => false
15
+ /%H/ => 'HH', # options ampm => false
16
16
  /%I/ => 'hh', # options ampm => true
17
17
  /%M/ => 'mm',
18
18
  /%p/ => 'tt',
@@ -101,6 +101,7 @@ module ActiveScaffold::Bridges
101
101
  nil
102
102
  end
103
103
  js_format = rails_format.dup
104
+ js_format.gsub! /([ ]|^)([^% ]\S*)/, " '\\2'"
104
105
  DATE_FORMAT_CONVERSION.each do |key, value|
105
106
  js_format.gsub!(key, value)
106
107
  end
@@ -110,13 +111,13 @@ module ActiveScaffold::Bridges
110
111
  def self.split_datetime_format(datetime_format)
111
112
  date_format = datetime_format
112
113
  time_format = nil
113
- time_start_indicators = %w{hh mm tt ss}
114
+ time_start_indicators = %w{HH hh mm tt ss}
114
115
  unless datetime_format.nil?
115
116
  start_indicator = time_start_indicators.detect {|indicator| datetime_format.include?(indicator)}
116
117
  unless start_indicator.nil?
117
118
  pos_time_format = datetime_format.index(start_indicator)
118
- date_format = datetime_format.to(pos_time_format - 1)
119
- time_format = datetime_format.from(pos_time_format)
119
+ date_format = datetime_format.to(pos_time_format - 1).strip
120
+ time_format = datetime_format.from(pos_time_format).strip
120
121
  end
121
122
  end
122
123
  return date_format, time_format
@@ -158,7 +159,7 @@ module ActiveScaffold::Bridges
158
159
  options = active_scaffold_input_text_options(options.merge(column.options))
159
160
  options[:class] << " #{column.search_ui.to_s}"
160
161
  options[:style] = (options[:show].nil? || options[:show]) ? nil : "display: none"
161
- format = options.delete(:format) || column.search_ui == :date_picker ? :default : :picker
162
+ format = options.delete(:format) || (column.search_ui == :date_picker ? :default : :picker)
162
163
  datepicker_format_options(column, format, options)
163
164
  text_field_tag("#{options[:name]}[#{name}]", value ? l(value, :format => format) : nil, options.merge(:id => "#{options[:id]}_#{name}", :name => "#{options[:name]}[#{name}]"))
164
165
  end
@@ -169,7 +170,7 @@ module ActiveScaffold::Bridges
169
170
  options = active_scaffold_input_text_options(options.merge(column.options))
170
171
  options[:class] << " #{column.form_ui.to_s}"
171
172
  value = controller.class.condition_value_for_datetime(@record.send(column.name), column.form_ui == :date_picker ? :to_date : :to_time)
172
- format = options.delete(:format) || column.form_ui == :date_picker ? :default : :picker
173
+ format = options.delete(:format) || (column.form_ui == :date_picker ? :default : :picker)
173
174
  datepicker_format_options(column, format, options)
174
175
  options[:value] = (value ? l(value, :format => format) : nil)
175
176
  text_field(:record, column.name, options)
@@ -12,7 +12,7 @@ module ActiveScaffold
12
12
  js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;";
13
13
  end
14
14
 
15
- content = active_scaffold_column_dragonfly(column, @record)
15
+ content = active_scaffold_column_dragonfly(@record, column)
16
16
  content_tag(:div,
17
17
  content + " | " +
18
18
  hidden_field(:record, "remove_#{column.name}", :value => "false") +
@@ -1,7 +1,7 @@
1
1
  module ActiveScaffold
2
2
  module Helpers
3
3
  module ListColumnHelpers
4
- def active_scaffold_column_dragonfly(column, record)
4
+ def active_scaffold_column_dragonfly(record, column)
5
5
  attachment = record.send("#{column.name}")
6
6
  return nil unless attachment.present?
7
7
  content = if attachment.image?
@@ -1,6 +1,6 @@
1
1
  class ActiveScaffold::Bridges::FileColumn < ActiveScaffold::DataStructures::Bridge
2
2
  def self.install
3
- if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column")
4
4
  raise RuntimeError, "We've detected that you have active_scaffold_file_column_bridge installed. This plugin has been moved to core. Please remove active_scaffold_file_column_bridge to prevent any conflicts"
5
5
  end
6
6
  require File.join(File.dirname(__FILE__), "file_column/as_file_column_bridge")
@@ -24,7 +24,7 @@ module ActiveScaffold::Config
24
24
  }
25
25
  end
26
26
 
27
- alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
27
+ alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column")
28
28
 
29
29
  def configure_file_column_field(field)
30
30
  # set list_ui first because it gets its default value from form_ui
@@ -4,12 +4,12 @@ module ActiveScaffold
4
4
  module FileColumnHelpers
5
5
  class << self
6
6
  def file_column_fields(klass)
7
- klass.instance_methods.select{|m| m.to_s =~ /_just_uploaded\?$/}.collect{|m| m[0..-16].to_sym }
7
+ klass.instance_methods.grep(/_just_uploaded\?$/).collect{|m| m[0..-16].to_sym }
8
8
  end
9
9
 
10
10
  def generate_delete_helpers(klass)
11
11
  file_column_fields(klass).each { |field|
12
- klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=".send(::ActiveScaffold::METHOD_CONVERSION))
12
+ klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=")
13
13
  attr_reader :delete_#{field}
14
14
 
15
15
  def delete_#{field}=(value)
@@ -2,18 +2,18 @@ module ActiveScaffold
2
2
  module Helpers
3
3
  # Helpers that assist with the rendering of a List Column
4
4
  module ListColumnHelpers
5
- def active_scaffold_column_download_link_with_filename(column, record)
5
+ def active_scaffold_column_download_link_with_filename(record, column)
6
6
  return nil if record.send(column.name).nil?
7
- active_scaffold_column_download_link(column, record, File.basename(record.send(column.name)))
7
+ active_scaffold_column_download_link(record, column, File.basename(record.send(column.name)))
8
8
  end
9
9
 
10
- def active_scaffold_column_download_link(column, record, label = nil)
10
+ def active_scaffold_column_download_link(record, column, label = nil)
11
11
  return nil if record.send(column.name).nil?
12
12
  label||=as_(:download)
13
13
  link_to( label, url_for_file_column(record, column.name.to_s), :popup => true)
14
14
  end
15
15
 
16
- def active_scaffold_column_thumbnail(column, record)
16
+ def active_scaffold_column_thumbnail(record, column)
17
17
  return nil if record.send(column.name).nil?
18
18
  link_to(
19
19
  image_tag(url_for_file_column(record, column.name.to_s, "thumb"), :border => 0),
@@ -1,6 +1,6 @@
1
1
  class ActiveScaffold::Bridges::Paperclip < ActiveScaffold::DataStructures::Bridge
2
2
  def self.install
3
- if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip".send(::ActiveScaffold::METHOD_CONVERSION))
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip")
4
4
  raise RuntimeError, "We've detected that you have active_scaffold_paperclip_bridge installed. This plugin has been moved to core. Please remove active_scaffold_paperclip_bridge to prevent any conflicts"
5
5
  end
6
6
  require File.join(File.dirname(__FILE__), "paperclip/form_ui")
@@ -12,7 +12,7 @@ module ActiveScaffold
12
12
  js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;";
13
13
  end
14
14
 
15
- content = active_scaffold_column_paperclip(column, @record)
15
+ content = active_scaffold_column_paperclip(@record, column)
16
16
  content_tag(:div,
17
17
  content + " | " +
18
18
  hidden_field(:record, "delete_#{column.name}", :value => "false") +
@@ -1,7 +1,7 @@
1
1
  module ActiveScaffold
2
2
  module Helpers
3
3
  module ListColumnHelpers
4
- def active_scaffold_column_paperclip(column, record)
4
+ def active_scaffold_column_paperclip(record, column)
5
5
  paperclip = record.send("#{column.name}")
6
6
  return nil unless paperclip.file?
7
7
  content = if paperclip.styles.include?(ActiveScaffold::Bridges::Paperclip::PaperclipBridgeHelpers.thumbnail_style)
@@ -6,7 +6,7 @@ module ActiveScaffold
6
6
  self.thumbnail_style = :thumbnail
7
7
 
8
8
  def self.generate_delete_helper(klass, field)
9
- klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=".send(::ActiveScaffold::METHOD_CONVERSION))
9
+ klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=")
10
10
  attr_reader :delete_#{field}
11
11
 
12
12
  def delete_#{field}=(value)
@@ -114,7 +114,7 @@ module ActiveScaffold
114
114
  unless operator.nil?
115
115
  ["%{search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
116
116
  else
117
- ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? || to_value.nil?
117
+ ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
118
118
  end
119
119
  end
120
120
  end
@@ -16,7 +16,7 @@ class ActiveScaffold::Bridges::TinyMce
16
16
  options[:class] = "#{options[:class]} mceEditor #{column.options[:class]}".strip
17
17
 
18
18
  settings = { :theme => 'simple' }.merge(column.options[:tinymce] || {})
19
- settings = settings.to_json
19
+ settings = settings.to_s.gsub(/:(.+?)\=\>/, '\1:')
20
20
  settings = "tinyMCE.settings = #{settings};"
21
21
 
22
22
  html = []
@@ -25,6 +25,10 @@ module ActiveScaffold::Config
25
25
  cattr_accessor :theme
26
26
  @@theme = :default
27
27
 
28
+ # enable caching of action link urls
29
+ cattr_accessor :cache_action_link_urls
30
+ @@cache_action_link_urls = true
31
+
28
32
  # lets you disable the DHTML history
29
33
  def self.dhtml_history=(val)
30
34
  @@dhtml_history = val
@@ -91,6 +95,9 @@ module ActiveScaffold::Config
91
95
  # lets you override the global ActiveScaffold theme for a specific controller
92
96
  attr_accessor :theme
93
97
 
98
+ # enable caching of action link urls
99
+ attr_accessor :cache_action_link_urls
100
+
94
101
  # lets you specify whether add a create link for each sti child for a specific controller
95
102
  attr_accessor :sti_create_links
96
103
  def add_sti_create_links?
@@ -139,6 +146,7 @@ module ActiveScaffold::Config
139
146
  # inherit the global frontend
140
147
  @frontend = self.class.frontend
141
148
  @theme = self.class.theme
149
+ @cache_action_link_urls = self.class.cache_action_link_urls
142
150
  @sti_create_links = self.class.sti_create_links
143
151
 
144
152
  # inherit from the global set of action links
@@ -154,8 +162,7 @@ module ActiveScaffold::Config
154
162
  # then, register the column objects
155
163
  self.actions.each do |action_name|
156
164
  action = self.send(action_name)
157
- next unless action.respond_to? :columns
158
- action.columns.set_columns(self.columns)
165
+ action.columns.set_columns(self.columns) if action.respond_to?(:columns)
159
166
  end
160
167
  end
161
168
 
@@ -23,6 +23,7 @@ module ActiveScaffold::Config
23
23
  @wrap_tag = self.class.wrap_tag
24
24
  @always_show_search = self.class.always_show_search
25
25
  @always_show_create = self.class.always_show_create
26
+ @messages_above_header = self.class.messages_above_header
26
27
  end
27
28
 
28
29
  # global level configuration
@@ -39,17 +40,14 @@ module ActiveScaffold::Config
39
40
  cattr_accessor :page_links_outer_window
40
41
  @@page_links_outer_window = 0
41
42
 
42
- class << self
43
- def page_links_window=(value)
44
- ActiveSupport::Deprecation.warn("Use page_links_inner_window", caller(1))
45
- self.page_links_inner_window = value
46
- end
47
- end
48
-
49
43
  # what string to use when a field is empty
50
44
  cattr_accessor :empty_field_text
51
45
  @@empty_field_text = '-'
52
46
 
47
+ # display messages above table header
48
+ cattr_accessor :messages_above_header
49
+ @@messages_above_header = false
50
+
53
51
  # what string to use to join records from plural associations
54
52
  cattr_accessor :association_join_text
55
53
  @@association_join_text = ', '
@@ -67,7 +65,7 @@ module ActiveScaffold::Config
67
65
 
68
66
  # the ActionLink to reset search
69
67
  cattr_reader :reset_link
70
- @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false)
68
+ @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false, :parameters => {:search => ''})
71
69
 
72
70
  # wrap normal cells (not inplace editable columns or with link) with a tag
73
71
  # it allows for more css styling
@@ -102,11 +100,6 @@ module ActiveScaffold::Config
102
100
  # how many page links around current page to show
103
101
  attr_accessor :page_links_outer_window
104
102
 
105
- def page_links_window=(value)
106
- ActiveSupport::Deprecation.warn("Use page_links_inner_window", caller(1))
107
- self.page_links_inner_window = value
108
- end
109
-
110
103
  # What kind of pagination to use:
111
104
  # * true: The usual pagination
112
105
  # * :infinite: Treat the source as having an infinite number of pages (i.e. don't count the records; useful for large tables where counting is slow and we don't really care anyway)
@@ -116,6 +109,9 @@ module ActiveScaffold::Config
116
109
  # what string to use when a field is empty
117
110
  attr_accessor :empty_field_text
118
111
 
112
+ # display messages above table header
113
+ attr_accessor :messages_above_header
114
+
119
115
  # what string to use to join records from plural associations
120
116
  attr_accessor :association_join_text
121
117
 
@@ -6,25 +6,34 @@ module ActiveScaffold::Config
6
6
  super
7
7
  @label = :add_existing_model
8
8
  @shallow_delete = self.class.shallow_delete
9
+ @ignore_order_from_association = self.class.ignore_order_from_association
9
10
  end
10
11
 
11
12
  # global level configuration
12
13
  # --------------------------
13
14
  cattr_accessor :shallow_delete
14
15
  @@shallow_delete = true
16
+
17
+ cattr_accessor :ignore_order_from_association
15
18
 
16
19
  # instance-level configuration
17
20
  # ----------------------------
18
21
  attr_accessor :shallow_delete
22
+
23
+ attr_accessor :ignore_order_from_association
19
24
 
20
25
  # Add a nested ActionLink
21
26
  def add_link(attribute, options = {})
22
27
  column = @core.columns[attribute.to_sym]
23
28
  unless column.nil? || column.association.nil?
24
- options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => column.singular_association? ? 1 : 2, :default => column.association.klass.name.pluralize})
29
+ label = if column.polymorphic_association?
30
+ column.label
31
+ else
32
+ column.association.klass.model_name.human({:count => column.singular_association? ? 1 : 2, :default => column.association.klass.name.pluralize})
33
+ end
34
+ options.reverse_merge! :security_method => :nested_authorized?, :label => label
25
35
  action_group = options.delete(:action_group) || self.action_group
26
36
  action_link = @core.link_for_association(column, options)
27
- action_link.action ||= :index
28
37
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
29
38
  else
30
39
  # TODO: raise exception
@@ -16,6 +16,16 @@ module ActiveScaffold::DataStructures
16
16
  @label.to_s.underscore
17
17
  end
18
18
 
19
+ # this is so that array.delete and array.include?, etc., will work by column name
20
+ def ==(other) #:nodoc:
21
+ # another ActionColumns
22
+ if other.class == self.class
23
+ self.label == other.label
24
+ else
25
+ @label.to_s == other.to_s
26
+ end
27
+ end
28
+
19
29
  # Whether this column set is collapsed by default in contexts where collapsing is supported
20
30
  attr_accessor :collapsed
21
31
 
@@ -39,7 +49,7 @@ module ActiveScaffold::DataStructures
39
49
 
40
50
  def names
41
51
  if @columns
42
- self.collect(&:name)
52
+ self.collect_visible(:flatten => true) { |c| c.name }
43
53
  else
44
54
  names_without_auth_check
45
55
  end
@@ -66,8 +76,12 @@ module ActiveScaffold::DataStructures
66
76
  item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
67
77
  next if self.skip_column?(item, options)
68
78
  end
69
- if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
70
- item.each(options, &proc)
79
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns
80
+ if options[:flatten]
81
+ item.each(options, &proc)
82
+ elsif !options[:skip_groups]
83
+ yield item
84
+ end
71
85
  else
72
86
  yield item
73
87
  end
@@ -84,9 +98,9 @@ module ActiveScaffold::DataStructures
84
98
  next if self.skip_column?(item, options)
85
99
  end
86
100
  if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
87
- columns = columns + item.collect(options, &proc)
101
+ columns += item.collect_visible(options, &proc)
88
102
  else
89
- columns << item
103
+ columns << (block_given? ? yield(item) : item)
90
104
  end
91
105
  end
92
106
  columns
@@ -172,13 +172,20 @@ module ActiveScaffold::DataStructures
172
172
  # nested action_links are referencing a column
173
173
  attr_accessor :column
174
174
 
175
+ # don't close the panel when another action link is open
176
+ attr_writer :keep_open
177
+ def keep_open?
178
+ @keep_open
179
+ end
180
+
175
181
  # indicates that this a nested_link
176
182
  def nested_link?
177
183
  @column || (parameters && parameters[:named_scope])
178
184
  end
179
185
 
180
- # Internal use: generated eid for this action_link
181
- attr_accessor :eid
186
+ def name_to_cache_link_url
187
+ @name_to_cache_link_url ||= :"#{controller || 'self'}_#{action}#{'_' if parameters.present?}#{parameters.map{|k,v| "#{k}_#{v}"}.join('_')}_link_url"
188
+ end
182
189
 
183
190
 
184
191
  end
@@ -88,8 +88,9 @@ module ActiveScaffold::DataStructures
88
88
 
89
89
  # iterates over the links, possibly by type
90
90
  def each(options = {}, &block)
91
- @set.each {|item|
92
- if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
91
+ method = options[:reverse] ? :reverse_each : :each
92
+ @set.send(method) do |item|
93
+ if item.is_a?(ActiveScaffold::DataStructures::ActionLinks) && !options[:groups]
93
94
  item.each(options, &block)
94
95
  else
95
96
  if options[:include_set]
@@ -98,7 +99,7 @@ module ActiveScaffold::DataStructures
98
99
  yield item
99
100
  end
100
101
  end
101
- }
102
+ end
102
103
  end
103
104
 
104
105
  def collect_by_type(type = nil)
@@ -107,34 +108,6 @@ module ActiveScaffold::DataStructures
107
108
  links
108
109
  end
109
110
 
110
- def traverse(controller, options = {}, &block)
111
- traverse_method = options.delete(:reverse).nil? ? :each : :reverse_each
112
- options[:level] ||= -1
113
- options[:level] += 1
114
- first_action = true
115
- @set.send(traverse_method) do |link|
116
- if link.is_a?(ActiveScaffold::DataStructures::ActionLinks)
117
- unless link.empty?
118
- yield(link, nil, {:node => :start_traversing, :first_action => first_action, :level => options[:level]})
119
- link.traverse(controller,options, &block)
120
- yield(link, nil, {:node => :finished_traversing, :first_action => first_action, :level => options[:level]})
121
- first_action = false
122
- end
123
- elsif controller.nil? || !skip_action_link(controller, link, *(Array(options[:for])))
124
- security_method = link.security_method_set? || controller.respond_to?(link.security_method)
125
- authorized = if security_method
126
- controller.send(link.security_method, *(Array(options[:for])))
127
- else
128
- options[:for].nil? ? true : options[:for].authorized_for?(:crud_type => link.crud_type, :action => link.action)
129
- end
130
- next unless authorized || link.type == :member
131
- yield(self, link, {:authorized => authorized, :first_action => first_action, :level => options[:level]})
132
- first_action = false
133
- end
134
- end
135
- options[:level] -= 1
136
- end
137
-
138
111
  def collect
139
112
  @set
140
113
  end
@@ -178,14 +151,10 @@ module ActiveScaffold::DataStructures
178
151
 
179
152
  protected
180
153
 
181
- def skip_action_link(controller, link, *args)
182
- !link.ignore_method.nil? && controller.respond_to?(link.ignore_method) && controller.send(link.ignore_method, *args)
183
- end
184
-
185
154
  # called during clone or dup. makes the clone/dup deeper.
186
155
  def initialize_copy(from)
187
156
  @set = []
188
157
  from.instance_variable_get('@set').each { |link| @set << link.clone }
189
158
  end
190
159
  end
191
- end
160
+ end