active_scaffold_vho 3.0.6

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 (279) hide show
  1. data/.autotest +27 -0
  2. data/.document +5 -0
  3. data/CHANGELOG +179 -0
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +20 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README +63 -0
  8. data/Rakefile +53 -0
  9. data/frontends/default/images/add.gif +0 -0
  10. data/frontends/default/images/arrow_down.gif +0 -0
  11. data/frontends/default/images/arrow_up.gif +0 -0
  12. data/frontends/default/images/close.gif +0 -0
  13. data/frontends/default/images/config.png +0 -0
  14. data/frontends/default/images/cross.png +0 -0
  15. data/frontends/default/images/gears.png +0 -0
  16. data/frontends/default/images/indicator-small.gif +0 -0
  17. data/frontends/default/images/indicator.gif +0 -0
  18. data/frontends/default/images/magnifier.png +0 -0
  19. data/frontends/default/javascripts/jquery/active_scaffold.js +957 -0
  20. data/frontends/default/javascripts/jquery/jquery.editinplace.js +743 -0
  21. data/frontends/default/javascripts/prototype/active_scaffold.js +957 -0
  22. data/frontends/default/javascripts/prototype/dhtml_history.js +867 -0
  23. data/frontends/default/javascripts/prototype/form_enhancements.js +117 -0
  24. data/frontends/default/javascripts/prototype/rico_corner.js +370 -0
  25. data/frontends/default/stylesheets/stylesheet-ie.css +35 -0
  26. data/frontends/default/stylesheets/stylesheet.css +964 -0
  27. data/frontends/default/views/_action_group.html.erb +20 -0
  28. data/frontends/default/views/_add_existing_form.html.erb +30 -0
  29. data/frontends/default/views/_base_form.html.erb +45 -0
  30. data/frontends/default/views/_create_form.html.erb +8 -0
  31. data/frontends/default/views/_create_form_on_list.html.erb +6 -0
  32. data/frontends/default/views/_field_search.html.erb +32 -0
  33. data/frontends/default/views/_form.html.erb +24 -0
  34. data/frontends/default/views/_form_association.html.erb +14 -0
  35. data/frontends/default/views/_form_association_footer.html.erb +40 -0
  36. data/frontends/default/views/_form_attribute.html.erb +15 -0
  37. data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
  38. data/frontends/default/views/_form_messages.html.erb +5 -0
  39. data/frontends/default/views/_horizontal_subform.html.erb +19 -0
  40. data/frontends/default/views/_horizontal_subform_header.html.erb +10 -0
  41. data/frontends/default/views/_horizontal_subform_record.html.erb +37 -0
  42. data/frontends/default/views/_human_conditions.html.erb +1 -0
  43. data/frontends/default/views/_list.html.erb +18 -0
  44. data/frontends/default/views/_list_actions.html.erb +15 -0
  45. data/frontends/default/views/_list_calculations.html.erb +16 -0
  46. data/frontends/default/views/_list_column_headings.html.erb +12 -0
  47. data/frontends/default/views/_list_header.html.erb +10 -0
  48. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  49. data/frontends/default/views/_list_messages.html.erb +32 -0
  50. data/frontends/default/views/_list_pagination.html.erb +11 -0
  51. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  52. data/frontends/default/views/_list_record.html.erb +14 -0
  53. data/frontends/default/views/_list_record_columns.html.erb +8 -0
  54. data/frontends/default/views/_list_with_header.html.erb +32 -0
  55. data/frontends/default/views/_messages.html.erb +10 -0
  56. data/frontends/default/views/_render_field.js.rjs +13 -0
  57. data/frontends/default/views/_row.html.erb +12 -0
  58. data/frontends/default/views/_search.html.erb +34 -0
  59. data/frontends/default/views/_search_attribute.html.erb +10 -0
  60. data/frontends/default/views/_show.html.erb +8 -0
  61. data/frontends/default/views/_show_columns.html.erb +15 -0
  62. data/frontends/default/views/_update_actions.html.erb +9 -0
  63. data/frontends/default/views/_update_form.html.erb +6 -0
  64. data/frontends/default/views/_vertical_subform.html.erb +12 -0
  65. data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  66. data/frontends/default/views/action_confirmation.html.erb +13 -0
  67. data/frontends/default/views/add_existing.js.rjs +17 -0
  68. data/frontends/default/views/add_existing_form.html.erb +5 -0
  69. data/frontends/default/views/create.html.erb +5 -0
  70. data/frontends/default/views/delete.html.erb +13 -0
  71. data/frontends/default/views/destroy.js.rjs +11 -0
  72. data/frontends/default/views/edit_associated.js.rjs +11 -0
  73. data/frontends/default/views/field_search.html.erb +5 -0
  74. data/frontends/default/views/form_messages.js.rjs +1 -0
  75. data/frontends/default/views/list.html.erb +1 -0
  76. data/frontends/default/views/list.js.rjs +1 -0
  77. data/frontends/default/views/on_action_update.js.rjs +8 -0
  78. data/frontends/default/views/on_create.js.rjs +41 -0
  79. data/frontends/default/views/on_update.js.rjs +28 -0
  80. data/frontends/default/views/search.html.erb +5 -0
  81. data/frontends/default/views/show.html.erb +5 -0
  82. data/frontends/default/views/update.html.erb +8 -0
  83. data/frontends/default/views/update_column.js.rjs +13 -0
  84. data/frontends/default/views/update_row.js.rjs +1 -0
  85. data/init.rb +9 -0
  86. data/lib/active_record_permissions.rb +134 -0
  87. data/lib/active_scaffold/actions/common_search.rb +22 -0
  88. data/lib/active_scaffold/actions/core.rb +170 -0
  89. data/lib/active_scaffold/actions/create.rb +145 -0
  90. data/lib/active_scaffold/actions/delete.rb +75 -0
  91. data/lib/active_scaffold/actions/field_search.rb +82 -0
  92. data/lib/active_scaffold/actions/list.rb +184 -0
  93. data/lib/active_scaffold/actions/mark.rb +50 -0
  94. data/lib/active_scaffold/actions/nested.rb +250 -0
  95. data/lib/active_scaffold/actions/search.rb +47 -0
  96. data/lib/active_scaffold/actions/show.rb +61 -0
  97. data/lib/active_scaffold/actions/subform.rb +17 -0
  98. data/lib/active_scaffold/actions/update.rb +141 -0
  99. data/lib/active_scaffold/attribute_params.rb +207 -0
  100. data/lib/active_scaffold/bridges/ancestry/bridge.rb +5 -0
  101. data/lib/active_scaffold/bridges/ancestry/lib/ancestry_bridge.rb +39 -0
  102. data/lib/active_scaffold/bridges/bridge.rb +52 -0
  103. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +16 -0
  104. data/lib/active_scaffold/bridges/calendar_date_select/lib/as_cds_bridge.rb +79 -0
  105. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +7 -0
  106. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +38 -0
  107. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +26 -0
  108. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +35 -0
  109. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +17 -0
  110. data/lib/active_scaffold/bridges/date_picker/bridge.rb +22 -0
  111. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +225 -0
  112. data/lib/active_scaffold/bridges/date_picker/public/javascripts/date_picker_bridge.js +22 -0
  113. data/lib/active_scaffold/bridges/file_column/bridge.rb +11 -0
  114. data/lib/active_scaffold/bridges/file_column/lib/as_file_column_bridge.rb +46 -0
  115. data/lib/active_scaffold/bridges/file_column/lib/file_column_helpers.rb +59 -0
  116. data/lib/active_scaffold/bridges/file_column/lib/form_ui.rb +37 -0
  117. data/lib/active_scaffold/bridges/file_column/lib/list_ui.rb +26 -0
  118. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
  119. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
  120. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
  121. data/lib/active_scaffold/bridges/paperclip/bridge.rb +10 -0
  122. data/lib/active_scaffold/bridges/paperclip/lib/form_ui.rb +27 -0
  123. data/lib/active_scaffold/bridges/paperclip/lib/list_ui.rb +16 -0
  124. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge.rb +38 -0
  125. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge_helpers.rb +26 -0
  126. data/lib/active_scaffold/bridges/semantic_attributes/bridge.rb +5 -0
  127. data/lib/active_scaffold/bridges/semantic_attributes/lib/semantic_attributes_bridge.rb +20 -0
  128. data/lib/active_scaffold/bridges/shared/date_bridge.rb +187 -0
  129. data/lib/active_scaffold/bridges/tiny_mce/bridge.rb +5 -0
  130. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +45 -0
  131. data/lib/active_scaffold/bridges/validation_reflection/bridge.rb +8 -0
  132. data/lib/active_scaffold/bridges/validation_reflection/lib/validation_reflection_bridge.rb +21 -0
  133. data/lib/active_scaffold/config/base.rb +62 -0
  134. data/lib/active_scaffold/config/core.rb +220 -0
  135. data/lib/active_scaffold/config/create.rb +51 -0
  136. data/lib/active_scaffold/config/delete.rb +34 -0
  137. data/lib/active_scaffold/config/field_search.rb +75 -0
  138. data/lib/active_scaffold/config/form.rb +47 -0
  139. data/lib/active_scaffold/config/list.rb +174 -0
  140. data/lib/active_scaffold/config/mark.rb +22 -0
  141. data/lib/active_scaffold/config/nested.rb +44 -0
  142. data/lib/active_scaffold/config/search.rb +69 -0
  143. data/lib/active_scaffold/config/show.rb +35 -0
  144. data/lib/active_scaffold/config/subform.rb +35 -0
  145. data/lib/active_scaffold/config/update.rb +46 -0
  146. data/lib/active_scaffold/configurable.rb +29 -0
  147. data/lib/active_scaffold/constraints.rb +184 -0
  148. data/lib/active_scaffold/data_structures/action_columns.rb +133 -0
  149. data/lib/active_scaffold/data_structures/action_link.rb +171 -0
  150. data/lib/active_scaffold/data_structures/action_links.rb +175 -0
  151. data/lib/active_scaffold/data_structures/actions.rb +45 -0
  152. data/lib/active_scaffold/data_structures/column.rb +351 -0
  153. data/lib/active_scaffold/data_structures/columns.rb +75 -0
  154. data/lib/active_scaffold/data_structures/error_message.rb +24 -0
  155. data/lib/active_scaffold/data_structures/nested_info.rb +123 -0
  156. data/lib/active_scaffold/data_structures/set.rb +62 -0
  157. data/lib/active_scaffold/data_structures/sorting.rb +168 -0
  158. data/lib/active_scaffold/finder.rb +333 -0
  159. data/lib/active_scaffold/helpers/association_helpers.rb +40 -0
  160. data/lib/active_scaffold/helpers/controller_helpers.rb +82 -0
  161. data/lib/active_scaffold/helpers/country_helpers.rb +352 -0
  162. data/lib/active_scaffold/helpers/form_column_helpers.rb +347 -0
  163. data/lib/active_scaffold/helpers/human_condition_helpers.rb +59 -0
  164. data/lib/active_scaffold/helpers/id_helpers.rb +127 -0
  165. data/lib/active_scaffold/helpers/list_column_helpers.rb +361 -0
  166. data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
  167. data/lib/active_scaffold/helpers/search_column_helpers.rb +243 -0
  168. data/lib/active_scaffold/helpers/show_column_helpers.rb +46 -0
  169. data/lib/active_scaffold/helpers/view_helpers.rb +356 -0
  170. data/lib/active_scaffold/locale/de.rb +120 -0
  171. data/lib/active_scaffold/locale/en.rb +119 -0
  172. data/lib/active_scaffold/locale/es.yml +115 -0
  173. data/lib/active_scaffold/locale/fr.rb +116 -0
  174. data/lib/active_scaffold/locale/hu.yml +63 -0
  175. data/lib/active_scaffold/locale/ja.yml +64 -0
  176. data/lib/active_scaffold/locale/ru.yml +119 -0
  177. data/lib/active_scaffold/marked_model.rb +38 -0
  178. data/lib/active_scaffold/version.rb +9 -0
  179. data/lib/active_scaffold.rb +345 -0
  180. data/lib/active_scaffold_assets.rb +45 -0
  181. data/lib/dhtml_confirm.rb +54 -0
  182. data/lib/environment.rb +14 -0
  183. data/lib/extensions/action_controller_rendering.rb +20 -0
  184. data/lib/extensions/action_view_rendering.rb +113 -0
  185. data/lib/extensions/action_view_resolver.rb +7 -0
  186. data/lib/extensions/active_association_reflection.rb +13 -0
  187. data/lib/extensions/active_record_offset.rb +12 -0
  188. data/lib/extensions/array.rb +7 -0
  189. data/lib/extensions/localize.rb +10 -0
  190. data/lib/extensions/name_option_for_datetime.rb +12 -0
  191. data/lib/extensions/nil_id_in_url_params.rb +7 -0
  192. data/lib/extensions/paginator_extensions.rb +26 -0
  193. data/lib/extensions/reverse_associations.rb +62 -0
  194. data/lib/extensions/routing_mapper.rb +34 -0
  195. data/lib/extensions/to_label.rb +8 -0
  196. data/lib/extensions/unsaved_associated.rb +61 -0
  197. data/lib/extensions/unsaved_record.rb +20 -0
  198. data/lib/extensions/usa_state.rb +46 -0
  199. data/lib/generators/active_scaffold/USAGE +29 -0
  200. data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
  201. data/lib/generators/active_scaffold_controller/USAGE +19 -0
  202. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +28 -0
  203. data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
  204. data/lib/generators/active_scaffold_setup/USAGE +10 -0
  205. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +53 -0
  206. data/lib/paginator.rb +136 -0
  207. data/lib/responds_to_parent.rb +70 -0
  208. data/public/blank.html +33 -0
  209. data/shoulda_macros/macros.rb +136 -0
  210. data/test/bridges/bridge_test.rb +47 -0
  211. data/test/config/base_test.rb +15 -0
  212. data/test/config/create_test.rb +55 -0
  213. data/test/config/list_test.rb +74 -0
  214. data/test/config/show_test.rb +43 -0
  215. data/test/config/update_test.rb +17 -0
  216. data/test/const_mocker.rb +36 -0
  217. data/test/data_structures/action_columns_test.rb +113 -0
  218. data/test/data_structures/action_link_test.rb +78 -0
  219. data/test/data_structures/action_links_test.rb +78 -0
  220. data/test/data_structures/actions_test.rb +25 -0
  221. data/test/data_structures/association_column_test.rb +42 -0
  222. data/test/data_structures/column_test.rb +185 -0
  223. data/test/data_structures/columns_test.rb +69 -0
  224. data/test/data_structures/error_message_test.rb +28 -0
  225. data/test/data_structures/set_test.rb +86 -0
  226. data/test/data_structures/sorting_test.rb +126 -0
  227. data/test/data_structures/standard_column_test.rb +24 -0
  228. data/test/data_structures/virtual_column_test.rb +23 -0
  229. data/test/extensions/active_record_test.rb +45 -0
  230. data/test/extensions/array_test.rb +12 -0
  231. data/test/helpers/form_column_helpers_test.rb +31 -0
  232. data/test/helpers/list_column_helpers_test.rb +31 -0
  233. data/test/helpers/pagination_helpers_test.rb +55 -0
  234. data/test/misc/active_record_permissions_test.rb +154 -0
  235. data/test/misc/attribute_params_test.rb +110 -0
  236. data/test/misc/configurable_test.rb +96 -0
  237. data/test/misc/constraints_test.rb +193 -0
  238. data/test/misc/finder_test.rb +93 -0
  239. data/test/misc/lang_test.rb +12 -0
  240. data/test/mock_app/.gitignore +2 -0
  241. data/test/mock_app/app/controllers/application_controller.rb +10 -0
  242. data/test/mock_app/app/helpers/application_helper.rb +3 -0
  243. data/test/mock_app/config/boot.rb +110 -0
  244. data/test/mock_app/config/database.yml +16 -0
  245. data/test/mock_app/config/environment.rb +43 -0
  246. data/test/mock_app/config/environments/development.rb +17 -0
  247. data/test/mock_app/config/environments/production.rb +28 -0
  248. data/test/mock_app/config/environments/test.rb +28 -0
  249. data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  250. data/test/mock_app/config/initializers/inflections.rb +10 -0
  251. data/test/mock_app/config/initializers/mime_types.rb +5 -0
  252. data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  253. data/test/mock_app/config/initializers/session_store.rb +15 -0
  254. data/test/mock_app/config/locales/en.yml +5 -0
  255. data/test/mock_app/config/routes.rb +43 -0
  256. data/test/mock_app/db/test.sqlite3 +1 -0
  257. data/test/mock_app/public/blank.html +33 -0
  258. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  259. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  260. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  261. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  262. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  263. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  264. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  265. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  266. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  267. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  268. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  269. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  270. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  271. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  272. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  273. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  274. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +839 -0
  275. data/test/model_stub.rb +55 -0
  276. data/test/run_all.rb +8 -0
  277. data/test/test_helper.rb +39 -0
  278. data/uninstall.rb +13 -0
  279. metadata +492 -0
@@ -0,0 +1,187 @@
1
+ module ActiveScaffold
2
+ module Bridges
3
+ module Shared
4
+ module DateBridge
5
+ module SearchColumnHelpers
6
+ def active_scaffold_search_date_bridge(column, options)
7
+ current_search = {'from' => nil, 'to' => nil, 'opt' => 'BETWEEN',
8
+ 'number' => 1, 'unit' => 'DAYS', 'range' => nil}
9
+ current_search.merge!(options[:value]) unless options[:value].nil?
10
+ tags = []
11
+ tags << active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
12
+ tags << active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
13
+ tags << active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
14
+ tags << active_scaffold_search_date_bridge_range_tag(column, options, current_search)
15
+ tags.join("&nbsp;").html_safe
16
+ end
17
+
18
+ def active_scaffold_search_date_bridge_comparator_options(column)
19
+ select_options = ActiveScaffold::Finder::DateComparators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
20
+ select_options + ActiveScaffold::Finder::NumericComparators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
21
+ end
22
+
23
+ def active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
24
+ select_tag("#{options[:name]}[opt]", options_for_select(active_scaffold_search_date_bridge_comparator_options(column),current_search['opt']), :id => "#{options[:id]}_opt", :class => "as_search_range_option as_search_date_time_option")
25
+ end
26
+
27
+ def active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
28
+ numeric_controls = "" <<
29
+ active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'from') <<
30
+ content_tag(:span, (" - " + active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'to')).html_safe,
31
+ :id => "#{options[:id]}_between", :class => "as_search_range_between", :style => "display:#{current_search['opt'] == 'BETWEEN' ? '' : 'none'}")
32
+ content_tag("span", numeric_controls.html_safe, :id => "#{options[:id]}_numeric", :style => "display:#{ActiveScaffold::Finder::NumericComparators.include?(current_search['opt']) ? '' : 'none'}")
33
+ end
34
+
35
+ def active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
36
+ active_scaffold_date_bridge_trend_tag(column, options,
37
+ {:name_prefix => 'search',
38
+ :number_value => current_search['number'],
39
+ :unit_value => current_search["unit"],
40
+ :show => (current_search['opt'] == 'PAST' || current_search['opt'] == 'FUTURE')})
41
+ end
42
+
43
+ def active_scaffold_date_bridge_trend_tag(column, options, trend_options)
44
+ trend_controls = text_field_tag("#{trend_options[:name_prefix]}[#{column.name}][number]", trend_options[:number_value], :class => 'text-input', :size => 10, :autocomplete => 'off') << " " <<
45
+ select_tag("#{trend_options[:name_prefix]}[#{column.name}][unit]",
46
+ options_for_select(active_scaffold_search_date_bridge_trend_units(column), trend_options[:name_prefix]),
47
+ :class => 'text-input')
48
+ content_tag("span", trend_controls.html_safe, :id => "#{options[:id]}_trend", :style => "display:#{trend_options[:show] ? '' : 'none'}")
49
+ end
50
+
51
+ def active_scaffold_search_date_bridge_trend_units(column)
52
+ options = ActiveScaffold::Finder::DateUnits.collect{|unit| [as_(unit.downcase.to_sym), unit]}
53
+ options = ActiveScaffold::Finder::TimeUnits.collect{|unit| [as_(unit.downcase.to_sym), unit]} + options if column_datetime?(column)
54
+ options
55
+ end
56
+
57
+ def active_scaffold_search_date_bridge_range_tag(column, options, current_search)
58
+ range_controls = select_tag("search[#{column.name}][range]",
59
+ options_for_select( ActiveScaffold::Finder::DateRanges.collect{|range| [as_(range.downcase.to_sym), range]}, current_search["range"]),
60
+ :class => 'text-input')
61
+ content_tag("span", range_controls.html_safe, :id => "#{options[:id]}_range", :style => "display:#{(current_search['opt'] == 'RANGE') ? '' : 'none'}")
62
+ end
63
+
64
+ def column_datetime?(column)
65
+ (!column.column.nil? && [:datetime, :time].include?(column.column.type))
66
+ end
67
+ end
68
+
69
+ module HumanConditionHelpers
70
+ def active_scaffold_human_condition_date_bridge(column, value)
71
+ case value[:opt]
72
+ when 'RANGE'
73
+ "#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value[:range].downcase).downcase}"
74
+ when 'PAST', 'FUTURE'
75
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{as_(value[:number])} #{as_(value[:unit].downcase)}"
76
+ else
77
+ from, to = controller.class.date_bridge_from_to(column, value)
78
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
79
+ end
80
+ end
81
+ end
82
+
83
+ module Finder
84
+ module ClassMethods
85
+ def condition_for_date_bridge_type(column, value, like_pattern)
86
+ operator = ActiveScaffold::Finder::NumericComparators.include?(value[:opt]) && value[:opt] != 'BETWEEN' ? value[:opt] : nil
87
+ from_value, to_value = date_bridge_from_to(column, value)
88
+
89
+ if column.search_sql.is_a? Proc
90
+ column.search_sql.call(from_value, to_value, operator)
91
+ else
92
+ unless operator.nil?
93
+ ["#{column.search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
94
+ else
95
+ ["#{column.search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
96
+ end
97
+ end
98
+ end
99
+
100
+ def date_bridge_from_to(column, value)
101
+ conversion = column.column.type == :date ? :to_date : :to_time
102
+ case value[:opt]
103
+ when 'RANGE'
104
+ date_bridge_from_to_for_range(column, value).collect(&conversion)
105
+ when 'PAST', 'FUTURE'
106
+ date_bridge_from_to_for_trend(column, value).collect(&conversion)
107
+ else
108
+ ['from', 'to'].collect { |field| condition_value_for_datetime(value[field], conversion)}
109
+ end
110
+ end
111
+
112
+ def date_bridge_from_to_for_trend(column, value)
113
+ case value['opt']
114
+ when "PAST"
115
+ trend_number = [value['number'].to_i, 1].max
116
+ now = Time.zone.now
117
+ if date_bridge_column_date?(column)
118
+ from = now.beginning_of_day.ago((trend_number).send(value['unit'].downcase.singularize.to_sym))
119
+ to = now.end_of_day
120
+ else
121
+ from = now.ago((trend_number).send(value['unit'].downcase.singularize.to_sym))
122
+ to = now
123
+ end
124
+ return from, to
125
+ when "FUTURE"
126
+ trend_number = [value['number'].to_i, 1].max
127
+ now = Time.zone.now
128
+ if date_bridge_column_date?(column)
129
+ from = now.beginning_of_day
130
+ to = now.end_of_day.in((trend_number).send(value['unit'].downcase.singularize.to_sym))
131
+ else
132
+ from = now
133
+ to = now.in((trend_number).send(value['unit'].downcase.singularize.to_sym))
134
+ end
135
+ return from, to
136
+ end
137
+ end
138
+
139
+ def date_bridge_from_to_for_range(column, value)
140
+ case value[:range]
141
+ when 'TODAY'
142
+ return Time.zone.now.beginning_of_day, Time.zone.now.end_of_day
143
+ when 'YESTERDAY'
144
+ return Time.zone.now.ago(1.day).beginning_of_day, Time.zone.now.ago(1.day).end_of_day
145
+ when 'TOMMORROW'
146
+ return Time.zone.now.in(1.day).beginning_of_day, Time.zone.now.in(1.day).end_of_day
147
+ else
148
+ range_type, range = value[:range].downcase.split('_')
149
+ raise ArgumentError unless ['week', 'month', 'year'].include?(range)
150
+ case range_type
151
+ when 'this'
152
+ return Time.zone.now.send("beginning_of_#{range}".to_sym), Time.zone.now.send("end_of_#{range}")
153
+ when 'prev'
154
+ return Time.zone.now.ago(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), Time.zone.now.ago(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
155
+ when 'next'
156
+ return Time.zone.now.in(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), Time.zone.now.in(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
157
+ else
158
+ return nil, nil
159
+ end
160
+ end
161
+ end
162
+
163
+ def date_bridge_column_date?(column)
164
+ if [:date_picker, :datetime_picker].include? column.form_ui
165
+ column.form_ui == :date_picker
166
+ else
167
+ (!column.column.nil? && [:date].include?(column.column.type))
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ ActiveScaffold::Finder.const_set('DateComparators', ["PAST", "FUTURE", "RANGE"])
178
+ ActiveScaffold::Finder.const_set('DateUnits', ["DAYS", "WEEKS", "MONTHS", "YEARS"])
179
+ ActiveScaffold::Finder.const_set('TimeUnits', ["SECONDS", "MINUTES", "HOURS"])
180
+ ActiveScaffold::Finder.const_set('DateRanges', ["TODAY", "YESTERDAY", "TOMORROW",
181
+ "THIS_WEEK", "PREV_WEEK", "NEXT_WEEK",
182
+ "THIS_MONTH", "PREV_MONTH", "NEXT_MONTH",
183
+ "THIS_YEAR", "PREV_YEAR", "NEXT_YEAR"])
184
+
185
+
186
+
187
+
@@ -0,0 +1,5 @@
1
+ ActiveScaffold::Bridges.bridge "TinyMCE" do
2
+ install do
3
+ require File.join(File.dirname(__FILE__), "lib/tiny_mce_bridge.rb")
4
+ end
5
+ end
@@ -0,0 +1,45 @@
1
+ module ActiveScaffold
2
+ module TinyMceBridge
3
+ module ViewHelpers
4
+ def active_scaffold_includes(*args)
5
+ tiny_mce_js = javascript_tag(%|
6
+ var action_link_close = ActiveScaffold.ActionLink.Abstract.prototype.close;
7
+ ActiveScaffold.ActionLink.Abstract.prototype.close = function() {
8
+ this.adapter.select('textarea.mceEditor').each(function(elem) {
9
+ tinyMCE.execCommand('mceRemoveControl', false, elem.id);
10
+ });
11
+ action_link_close.apply(this);
12
+ };
13
+ |) if using_tiny_mce?
14
+ super(*args) + (include_tiny_mce_if_needed || '') + (tiny_mce_js || '')
15
+ end
16
+ end
17
+
18
+ module FormColumnHelpers
19
+ def active_scaffold_input_text_editor(column, options)
20
+ options[:class] = "#{options[:class]} mceEditor #{column.options[:class]}".strip
21
+ html = []
22
+ html << send(override_input(:textarea), column, options)
23
+ html << javascript_tag("tinyMCE.execCommand('mceAddControl', false, '#{options[:id]}');") if request.xhr?
24
+ html.join "\n"
25
+ end
26
+
27
+ def onsubmit
28
+ submit_js = 'tinyMCE.triggerSave();this.select("textarea.mceEditor").each(function(elem) { tinyMCE.execCommand("mceRemoveControl", false, elem.id); });' if using_tiny_mce?
29
+ [super, submit_js].compact.join ';'
30
+ end
31
+ end
32
+
33
+ module SearchColumnHelpers
34
+ def self.included(base)
35
+ base.class_eval { alias_method :active_scaffold_search_text_editor, :active_scaffold_search_text }
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ActionView::Base.class_eval do
42
+ include ActiveScaffold::TinyMceBridge::FormColumnHelpers
43
+ include ActiveScaffold::TinyMceBridge::SearchColumnHelpers
44
+ include ActiveScaffold::TinyMceBridge::ViewHelpers
45
+ end
@@ -0,0 +1,8 @@
1
+ ActiveScaffold::Bridges.bridge "ValidationReflection" do
2
+ install do
3
+ require File.join(File.dirname(__FILE__), "lib/validation_reflection_bridge.rb")
4
+ end
5
+ install? do
6
+ ActiveRecord::Base.respond_to? :reflect_on_validations_for
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveScaffold
2
+ module ValidationReflectionBridge
3
+ def self.included(base)
4
+ base.class_eval { alias_method_chain :initialize, :validation_reflection }
5
+ end
6
+
7
+ def initialize_with_validation_reflection(name, active_record_class)
8
+ initialize_without_validation_reflection(name, active_record_class)
9
+ column_names = [name]
10
+ column_names << @association.primary_key_name if @association
11
+ self.required = column_names.any? do |column_name|
12
+ active_record_class.reflect_on_validations_for(column_name.to_sym).any? do |val|
13
+ val.macro == :validates_presence_of or (val.macro == :validates_inclusion_of and not val.options[:allow_nil] and not val.options[:allow_blank])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ ActiveScaffold::DataStructures::Column.class_eval do
20
+ include ActiveScaffold::ValidationReflectionBridge
21
+ end
@@ -0,0 +1,62 @@
1
+ module ActiveScaffold::Config
2
+ class Base
3
+ include ActiveScaffold::Configurable
4
+ extend ActiveScaffold::Configurable
5
+
6
+ def self.inherited(subclass)
7
+ class << subclass
8
+ # the crud type of the action. possible values are :create, :read, :update, :delete, and nil.
9
+ # this is not a setting for the developer. it's self-description for the actions.
10
+ def crud_type; @crud_type; end
11
+
12
+ protected
13
+
14
+ def crud_type=(val)
15
+ raise ArgumentError, "unknown CRUD type #{val}" unless [:create, :read, :update, :delete].include?(val.to_sym)
16
+ @crud_type = val.to_sym
17
+ end
18
+ end
19
+ end
20
+
21
+ # delegate
22
+ def crud_type; self.class.crud_type end
23
+
24
+ # the user property gets set to the instantiation of the local UserSettings class during the automatic instantiation of this class.
25
+ attr_accessor :user
26
+
27
+ # define a default action_group for this action
28
+ # e.g. 'members.crud'
29
+ class_inheritable_accessor :action_group
30
+
31
+ # action_group this action should belong to
32
+ attr_accessor :action_group
33
+
34
+ class UserSettings
35
+ def initialize(conf, storage, params)
36
+ # the session hash relevant to this action
37
+ @session = storage
38
+ # all the request params
39
+ @params = params
40
+ # the configuration object for this action
41
+ @conf = conf
42
+ end
43
+ end
44
+
45
+ def formats
46
+ @formats ||= []
47
+ end
48
+
49
+ def formats=(val)
50
+ @formats=val
51
+ end
52
+
53
+ private
54
+
55
+ def columns=(val)
56
+ @columns = ActiveScaffold::DataStructures::ActionColumns.new(*val)
57
+ @columns.action = self
58
+ @columns.set_columns(@core.columns) if @columns.respond_to?(:set_columns)
59
+ @columns
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,220 @@
1
+ module ActiveScaffold::Config
2
+ # to fix the ckeditor bridge problem
3
+ class Core < ActiveScaffold::Config::Base
4
+ # code commented out (see above)
5
+ #class Core < Base
6
+ # global level configuration
7
+ # --------------------------
8
+
9
+ # provides read/write access to the global Actions DataStructure
10
+ cattr_reader :actions
11
+ def self.actions=(val)
12
+ @@actions = ActiveScaffold::DataStructures::Actions.new(*val)
13
+ end
14
+ self.actions = [:create, :list, :search, :update, :delete, :show, :nested, :subform]
15
+
16
+ # configures where the ActiveScaffold plugin itself is located. there is no instance version of this.
17
+ cattr_accessor :plugin_directory
18
+ @@plugin_directory = File.expand_path(__FILE__).match(%{(^.*)/lib/active_scaffold/config/core.rb})[1]
19
+
20
+ # lets you specify a global ActiveScaffold frontend.
21
+ cattr_accessor :frontend
22
+ @@frontend = :default
23
+
24
+ # lets you specify a global ActiveScaffold theme for your frontend.
25
+ cattr_accessor :theme
26
+ @@theme = :default
27
+
28
+ # lets you disable the DHTML history
29
+ def self.dhtml_history=(val)
30
+ @@dhtml_history = val
31
+ end
32
+ def self.dhtml_history?
33
+ @@dhtml_history ? true : false
34
+ end
35
+ @@dhtml_history = true
36
+
37
+ # action links are used by actions to tie together. you can use them, too! this is a collection of ActiveScaffold::DataStructures::ActionLink objects.
38
+ cattr_reader :action_links
39
+ @@action_links = ActiveScaffold::DataStructures::ActionLinks.new
40
+
41
+ # access to the permissions configuration.
42
+ # configuration options include:
43
+ # * current_user_method - what method on the controller returns the current user. default: :current_user
44
+ # * default_permission - what the default permission is. default: true
45
+ def self.security
46
+ ActiveRecordPermissions
47
+ end
48
+
49
+ # columns that should be ignored for every model. these should be metadata columns like change dates, versions, etc.
50
+ # values in this array may be symbols or strings.
51
+ def self.ignore_columns
52
+ @@ignore_columns
53
+ end
54
+ def self.ignore_columns=(val)
55
+ @@ignore_columns = ActiveScaffold::DataStructures::Set.new(*val)
56
+ end
57
+ @@ignore_columns = ActiveScaffold::DataStructures::Set.new
58
+
59
+ # lets you specify whether add a create link for each sti child
60
+ cattr_accessor :sti_create_links
61
+ @@sti_create_links = true
62
+
63
+ # instance-level configuration
64
+ # ----------------------------
65
+
66
+ # provides read/write access to the local Actions DataStructure
67
+ attr_reader :actions
68
+ def actions=(args)
69
+ @actions = ActiveScaffold::DataStructures::Actions.new(*args)
70
+ end
71
+
72
+ # provides read/write access to the local Columns DataStructure
73
+ attr_reader :columns
74
+ def columns=(val)
75
+ @columns._inheritable = val.collect {|c| c.to_sym}
76
+ # Add virtual columns
77
+ @columns << val.collect {|c| c.to_sym unless @columns[c.to_sym]}.compact
78
+ end
79
+
80
+ # lets you override the global ActiveScaffold frontend for a specific controller
81
+ attr_accessor :frontend
82
+
83
+ # lets you override the global ActiveScaffold theme for a specific controller
84
+ attr_accessor :theme
85
+
86
+ # lets you specify whether add a create link for each sti child for a specific controller
87
+ attr_accessor :sti_create_links
88
+ def add_sti_create_links?
89
+ self.sti_create_links and not self.sti_children.nil?
90
+ end
91
+
92
+ # action links are used by actions to tie together. they appear as links for each record, or general links for the ActiveScaffold.
93
+ attr_reader :action_links
94
+
95
+ # a generally-applicable name for this ActiveScaffold ... will be used for generating page/section headers
96
+ attr_writer :label
97
+ def label(options={})
98
+ as_(@label, options) || model.model_name.human(options.merge(options[:count].to_i == 1 ? {} : {:default => model.name.pluralize}))
99
+ end
100
+
101
+ # STI children models, use an array of model names
102
+ attr_accessor :sti_children
103
+
104
+ ##
105
+ ## internal usage only below this point
106
+ ## ------------------------------------
107
+
108
+ def initialize(model_id)
109
+ # model_id is the only absolutely required configuration value. it is also not publicly accessible.
110
+ @model_id = model_id.to_s.pluralize.singularize
111
+
112
+ # inherit the actions list directly from the global level
113
+ @actions = self.class.actions.clone
114
+
115
+ # create a new default columns datastructure, since it doesn't make sense before now
116
+ attribute_names = self.model.columns.collect{ |c| c.name.to_sym }.sort_by { |c| c.to_s }
117
+ association_column_names = self.model.reflect_on_all_associations.collect{ |a| a.name.to_sym }.sort_by { |c| c.to_s }
118
+ @columns = ActiveScaffold::DataStructures::Columns.new(self.model, attribute_names + association_column_names)
119
+
120
+ # and then, let's remove some columns from the inheritable set.
121
+ @columns.exclude(*self.class.ignore_columns)
122
+ @columns.exclude(*@columns.find_all { |c| c.column and (c.column.primary or c.column.name =~ /(_id|_count)$/) }.collect {|c| c.name})
123
+ @columns.exclude(*self.model.reflect_on_all_associations.collect{|a| :"#{a.name}_type" if a.options[:polymorphic]}.compact)
124
+
125
+ # inherit the global frontend
126
+ @frontend = self.class.frontend
127
+ @theme = self.class.theme
128
+ @sti_create_links = self.class.sti_create_links
129
+
130
+ # inherit from the global set of action links
131
+ @action_links = self.class.action_links.clone
132
+ end
133
+
134
+ # To be called after your finished configuration
135
+ def _load_action_columns
136
+ ActiveScaffold::DataStructures::ActionColumns.class_eval {include ActiveScaffold::DataStructures::ActionColumns::AfterConfiguration}
137
+
138
+ # then, register the column objects
139
+ self.actions.each do |action_name|
140
+ action = self.send(action_name)
141
+ next unless action.respond_to? :columns
142
+ action.columns.set_columns(self.columns)
143
+ end
144
+ end
145
+
146
+ # To be called after your finished configuration
147
+ def _configure_sti
148
+ column = self.model.inheritance_column
149
+ if sti_create_links
150
+ self.columns[column].form_ui ||= :hidden
151
+ else
152
+ self.columns[column].form_ui ||= :select
153
+ self.columns[column].options ||= {}
154
+ self.columns[column].options[:options] = self.sti_children.collect do |model_name|
155
+ [model_name.to_s.camelize.constantize.model_name.human, model_name.to_s.camelize]
156
+ end
157
+ end
158
+ end
159
+
160
+ # configuration routing.
161
+ # we want to route calls named like an activated action to that action's global or local Config class.
162
+ # ---------------------------
163
+ def method_missing(name, *args)
164
+ @action_configs ||= {}
165
+ titled_name = name.to_s.camelcase
166
+ underscored_name = name.to_s.underscore.to_sym
167
+ klass = "ActiveScaffold::Config::#{titled_name}".constantize rescue nil
168
+ if klass
169
+ if @actions.include? underscored_name
170
+ return @action_configs[underscored_name] ||= klass.new(self)
171
+ else
172
+ raise "#{titled_name} is not enabled. Please enable it or remove any references in your configuration (e.g. config.#{underscored_name}.columns = [...])."
173
+ end
174
+ end
175
+ super
176
+ end
177
+
178
+ def self.method_missing(name, *args)
179
+ klass = "ActiveScaffold::Config::#{name.to_s.titleize}".constantize rescue nil
180
+ if @@actions.include? name.to_s.underscore and klass
181
+ return eval("ActiveScaffold::Config::#{name.to_s.titleize}")
182
+ end
183
+ super
184
+ end
185
+ # some utility methods
186
+ # --------------------
187
+
188
+ def model_id
189
+ @model_id
190
+ end
191
+
192
+ def model
193
+ @model ||= @model_id.to_s.camelize.constantize
194
+ end
195
+
196
+ # warning - this won't work as a per-request dynamic attribute in rails 2.0. You'll need to interact with Controller#generic_view_paths
197
+ def inherited_view_paths
198
+ @inherited_view_paths||=[]
199
+ end
200
+
201
+ # must be a class method so the layout doesn't depend on a controller that uses active_scaffold
202
+ # note that this is unaffected by per-controller frontend configuration.
203
+ def self.asset_path(filename, frontend = self.frontend)
204
+ "active_scaffold/#{frontend}/#{filename}"
205
+ end
206
+
207
+ # must be a class method so the layout doesn't depend on a controller that uses active_scaffold
208
+ # note that this is unaffected by per-controller frontend configuration.
209
+ def self.javascripts(frontend = self.frontend)
210
+ javascript_dir = File.join(Rails.public_path, "javascripts", asset_path('', frontend))
211
+ Dir.entries(javascript_dir).reject { |e| !e.match(/\.js$/) or (!self.dhtml_history? and e.match('dhtml_history')) }
212
+ end
213
+
214
+ def self.available_frontends
215
+ frontends_dir = File.join(Rails.root, "vendor", "plugins", ActiveScaffold::Config::Core.plugin_directory, "frontends")
216
+ Dir.entries(frontends_dir).reject { |e| e.match(/^\./) } # Get rid of files that start with .
217
+ end
218
+ end
219
+ end
220
+
@@ -0,0 +1,51 @@
1
+ module ActiveScaffold::Config
2
+ class Create < ActiveScaffold::Config::Form
3
+ self.crud_type = :create
4
+ def initialize(*args)
5
+ super
6
+ self.persistent = self.class.persistent
7
+ self.edit_after_create = self.class.edit_after_create
8
+ self.refresh_list = self.class.refresh_list
9
+ end
10
+
11
+ # global level configuration
12
+ # --------------------------
13
+ # the ActionLink for this action
14
+ def self.link
15
+ @@link
16
+ end
17
+ def self.link=(val)
18
+ @@link = val
19
+ end
20
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('new', :label => :create_new, :type => :collection, :security_method => :create_authorized?, :ignore_method => :create_ignore?)
21
+
22
+ # whether the form stays open after a create or not
23
+ cattr_accessor :persistent
24
+ @@persistent = false
25
+
26
+ # whether update form is opened after a create or not
27
+ cattr_accessor :edit_after_create
28
+ @@edit_after_create = false
29
+
30
+ # whether we should refresh list after create or not
31
+ cattr_accessor :refresh_list
32
+ @@refresh_list = false
33
+
34
+ # instance-level configuration
35
+ # ----------------------------
36
+ # the label= method already exists in the Form base class
37
+ def label(model = nil)
38
+ model ||= @core.label(:count => 1)
39
+ @label ? as_(@label) : as_(:create_model, :model => model)
40
+ end
41
+
42
+ # whether the form stays open after a create or not
43
+ attr_accessor :persistent
44
+
45
+ # whether the form stays open after a create or not
46
+ attr_accessor :edit_after_create
47
+
48
+ # whether we should refresh list after create or not
49
+ attr_accessor :refresh_list
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveScaffold::Config
2
+ class Delete < Base
3
+ self.crud_type = :delete
4
+
5
+ def initialize(core_config)
6
+ @core = core_config
7
+
8
+ # start with the ActionLink defined globally
9
+ @link = self.class.link.clone
10
+ @action_group = self.class.action_group.clone if self.class.action_group
11
+ self.refresh_list = self.class.refresh_list
12
+ end
13
+
14
+ # global level configuration
15
+ # --------------------------
16
+
17
+ # the ActionLink for this action
18
+ cattr_accessor :link
19
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('destroy', :label => :delete, :type => :member, :confirm => :are_you_sure_to_delete, :method => :delete, :crud_type => :delete, :position => false, :parameters => {:destroy_action => true}, :security_method => :delete_authorized?)
20
+
21
+ # whether we should refresh list after destroy or not
22
+ cattr_accessor :refresh_list
23
+ @@refresh_list = false
24
+
25
+ # instance-level configuration
26
+ # ----------------------------
27
+
28
+ # the ActionLink for this action
29
+ attr_accessor :link
30
+
31
+ # whether we should refresh list after destroy or not
32
+ attr_accessor :refresh_list
33
+ end
34
+ end