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,225 @@
1
+ class File #:nodoc:
2
+
3
+ unless File.respond_to?(:binread)
4
+ def self.binread(file)
5
+ File.open(file, 'rb') { |f| f.read }
6
+ end
7
+ end
8
+
9
+ end
10
+
11
+ ActiveScaffold::Config::Core.class_eval do
12
+ def initialize_with_date_picker(model_id)
13
+ initialize_without_date_picker(model_id)
14
+
15
+ date_picker_fields = self.model.columns.collect{|c| {:name => c.name.to_sym, :type => c.type} if [:date, :datetime].include?(c.type) }.compact
16
+ # check to see if file column was used on the model
17
+ return if date_picker_fields.empty?
18
+
19
+ # automatically set the forum_ui to a file column
20
+ date_picker_fields.each{|field|
21
+ col_config = self.columns[field[:name]]
22
+ col_config.form_ui = (field[:type] == :date ? :date_picker : :datetime_picker)
23
+ }
24
+ end
25
+
26
+ alias_method_chain :initialize, :date_picker
27
+ end
28
+
29
+
30
+ module ActiveScaffold
31
+ module Bridges
32
+ module DatePickerBridge
33
+ DATE_FORMAT_CONVERSION = {
34
+ '%a' => 'D',
35
+ '%A' => 'DD',
36
+ '%b' => 'M',
37
+ '$B' => 'MM',
38
+ '%d' => 'dd',
39
+ '%e' => 'd',
40
+ '%j' => 'oo',
41
+ '%m' => 'mm',
42
+ '%y' => 'y',
43
+ '%Y' => 'yy',
44
+ '%H' => 'hh', # options ampm => false
45
+ '%I' => 'hh', # options ampm => true
46
+ '%M' => 'mm',
47
+ '%p' => 'tt',
48
+ '%S' => 'ss'
49
+ }
50
+
51
+ def self.localization(js_file)
52
+ localization = "jQuery(function($){
53
+ if (typeof($.datepicker) === 'object') {
54
+ $.datepicker.regional['#{I18n.locale}'] = #{date_options.to_json};
55
+ $.datepicker.setDefaults($.datepicker.regional['#{I18n.locale}']);
56
+ }
57
+ if (typeof($.timepicker) === 'object') {
58
+ $.timepicker.regional['#{I18n.locale}'] = #{datetime_options.to_json};
59
+ $.timepicker.setDefaults($.timepicker.regional['#{I18n.locale}']);
60
+ }
61
+ });\n"
62
+ prepend_js_file(js_file, localization)
63
+ end
64
+
65
+ def self.date_options
66
+ date_options = I18n.translate! 'date'
67
+ date_picker_options = { :closeText => as_(:close),
68
+ :prevText => as_(:previous),
69
+ :nextText => as_(:next),
70
+ :currentText => as_(:today),
71
+ :monthNames => date_options[:month_names][1, (date_options[:month_names].length - 1)],
72
+ :monthNamesShort => date_options[:abbr_month_names][1, (date_options[:abbr_month_names].length - 1)],
73
+ :dayNames => date_options[:day_names],
74
+ :dayNamesShort => date_options[:abbr_day_names],
75
+ :dayNamesMin => date_options[:abbr_day_names],
76
+ :changeYear => true,
77
+ :changeMonth => true,
78
+ }
79
+
80
+ begin
81
+ as_date_picker_options = I18n.translate! 'active_scaffold.date_picker_options'
82
+ date_picker_options.merge!(as_date_picker_options) if as_date_picker_options.is_a? Hash
83
+ rescue
84
+ Rails.logger.warn "ActiveScaffold: Missing date picker localization for your locale: #{I18n.locale}"
85
+ end
86
+
87
+ js_format = self.to_datepicker_format(date_options[:formats][:default])
88
+ date_picker_options[:dateFormat] = js_format unless js_format.nil?
89
+ date_picker_options
90
+ end
91
+
92
+ def self.datetime_options
93
+ rails_time_format = I18n.translate! 'time.formats.default'
94
+ datetime_options = I18n.translate! 'datetime.prompts'
95
+ datetime_picker_options = {:ampm => false,
96
+ :hourText => datetime_options[:hour],
97
+ :minuteText => datetime_options[:minute],
98
+ :secondText => datetime_options[:second],
99
+ }
100
+
101
+ begin
102
+ as_datetime_picker_options = I18n.translate! 'active_scaffold.datetime_picker_options'
103
+ datetime_picker_options.merge!(as_datetime_picker_options) if as_datetime_picker_options.is_a? Hash
104
+ rescue
105
+ Rails.logger.warn "ActiveScaffold: Missing datetime picker localization for your locale: #{I18n.locale}"
106
+ end
107
+
108
+ date_format, time_format = self.split_datetime_format(self.to_datepicker_format(rails_time_format))
109
+ datetime_picker_options[:dateFormat] = date_format unless date_format.nil?
110
+ unless time_format.nil?
111
+ datetime_picker_options[:timeFormat] = time_format
112
+ datetime_picker_options[:ampm] = true if rails_time_format.include?('%I')
113
+ end
114
+ datetime_picker_options
115
+ end
116
+
117
+ def self.prepend_js_file(js_file, prepend)
118
+ content = File.binread(js_file)
119
+ content.gsub!(/\A/, prepend)
120
+ File.open(js_file, 'wb') { |file| file.write(content) }
121
+ end
122
+
123
+ def self.to_datepicker_format(rails_format)
124
+ return nil if rails_format.nil?
125
+ if rails_format =~ /%[cUWwxXZz]/
126
+ Rails.logger.warn("AS DatePickerBridge: Can t convert rails date format: #{rails_format} to jquery datepicker format. Options %c, %U, %W, %w, %x %X, %z, %Z are not supported by datepicker]")
127
+ nil
128
+ else
129
+ js_format = rails_format.dup
130
+ DATE_FORMAT_CONVERSION.each do |key, value|
131
+ js_format.gsub!(Regexp.new("#{key}"), value)
132
+ end
133
+ js_format
134
+ end
135
+ end
136
+
137
+ def self.split_datetime_format(datetime_format)
138
+ date_format = datetime_format
139
+ time_format = nil
140
+ time_start_indicators = %w{hh mm tt ss}
141
+ unless datetime_format.nil?
142
+ start_indicator = time_start_indicators.detect {|indicator| datetime_format.include?(indicator)}
143
+ unless start_indicator.nil?
144
+ pos_time_format = datetime_format.index(start_indicator)
145
+ date_format = datetime_format.to(pos_time_format - 1)
146
+ time_format = datetime_format.from(pos_time_format)
147
+ end
148
+ end
149
+ return date_format, time_format
150
+ end
151
+
152
+ module DatepickerColumnHelpers
153
+ def datepicker_split_datetime_format(datetime_format)
154
+ ActiveScaffold::Bridges::DatePickerBridge.split_datetime_format(datetime_format)
155
+ end
156
+
157
+ def to_datepicker_format(rails_format)
158
+ ActiveScaffold::Bridges::DatePickerBridge.to_datepicker_format(rails_format)
159
+ end
160
+
161
+ def datepicker_format_options(column, format, options)
162
+ if column.form_ui == :date_picker
163
+ js_format = to_datepicker_format(I18n.translate!("date.formats.#{format}"))
164
+ options['date:dateFormat'] = js_format unless js_format.nil?
165
+ else
166
+ rails_time_format = I18n.translate!("time.formats.#{format}")
167
+ date_format, time_format = datepicker_split_datetime_format(self.to_datepicker_format(rails_time_format))
168
+ options['date:dateFormat'] = date_format unless date_format.nil?
169
+ unless time_format.nil?
170
+ options['time:timeFormat'] = time_format
171
+ options['time:ampm'] = true if rails_time_format.include?('%I')
172
+ end
173
+ end unless format == :default
174
+ end
175
+ end
176
+
177
+ module SearchColumnHelpers
178
+ def active_scaffold_search_date_bridge_calendar_control(column, options, current_search, name)
179
+ if current_search.is_a? Hash
180
+ value = controller.class.condition_value_for_datetime(current_search[name], column.form_ui == :date_picker ? :to_date : :to_time)
181
+ else
182
+ value = current_search
183
+ end
184
+ options = column.options.merge(options).except!(:include_blank, :discard_time, :discard_date, :value)
185
+ options = active_scaffold_input_text_options(options.merge(column.options))
186
+ options[:class] << " #{column.search_ui.to_s}"
187
+ options[:style] = "display:#{(options[:show].nil? || options[:show]) ? '' : 'none'}"
188
+ format = options.delete(:format) || :default
189
+ datepicker_format_options(column, format, options)
190
+ text_field_tag("#{options[:name]}[#{name}]", value ? l(value, :format => format) : nil, options.merge(:id => "#{options[:id]}_#{name}", :name => "#{options[:name]}[#{name}]"))
191
+ end
192
+ end
193
+
194
+ module FormColumnHelpers
195
+ def active_scaffold_input_date_picker(column, options)
196
+ options = active_scaffold_input_text_options(options.merge(column.options))
197
+ options[:class] << " #{column.form_ui.to_s}"
198
+ value = controller.class.condition_value_for_datetime(@record.send(column.name), column.form_ui == :date_picker ? :to_date : :to_time)
199
+ format = options.delete(:format) || :default
200
+ datepicker_format_options(column, format, options)
201
+ options[:value] = (value ? l(value, :format => format) : nil)
202
+ text_field(:record, column.name, options)
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ ActionView::Base.class_eval do
210
+ include ActiveScaffold::Bridges::Shared::DateBridge::SearchColumnHelpers
211
+ alias_method :active_scaffold_search_date_picker, :active_scaffold_search_date_bridge
212
+ alias_method :active_scaffold_search_datetime_picker, :active_scaffold_search_date_bridge
213
+ include ActiveScaffold::Bridges::Shared::DateBridge::HumanConditionHelpers
214
+ alias_method :active_scaffold_human_condition_date_picker, :active_scaffold_human_condition_date_bridge
215
+ alias_method :active_scaffold_human_condition_datetime_picker, :active_scaffold_human_condition_date_bridge
216
+ include ActiveScaffold::Bridges::DatePickerBridge::SearchColumnHelpers
217
+ include ActiveScaffold::Bridges::DatePickerBridge::FormColumnHelpers
218
+ alias_method :active_scaffold_input_datetime_picker, :active_scaffold_input_date_picker
219
+ include ActiveScaffold::Bridges::DatePickerBridge::DatepickerColumnHelpers
220
+ end
221
+ ActiveScaffold::Finder::ClassMethods.module_eval do
222
+ include ActiveScaffold::Bridges::Shared::DateBridge::Finder::ClassMethods
223
+ alias_method :condition_for_date_picker_type, :condition_for_date_bridge_type
224
+ alias_method :condition_for_datetime_picker_type, :condition_for_date_picker_type
225
+ end
@@ -0,0 +1,22 @@
1
+ $(document).ready(function() {
2
+ $('input.date_picker').live('focus', function(event) {
3
+ var date_picker = $(this);
4
+ if (typeof(date_picker.datepicker) == 'function') {
5
+ if (!date_picker.hasClass('hasDatepicker')) {
6
+ date_picker.datepicker();
7
+ date_picker.trigger('focus');
8
+ }
9
+ }
10
+ return true;
11
+ });
12
+ $('input.datetime_picker').live('focus', function(event) {
13
+ var date_picker = $(this);
14
+ if (typeof(date_picker.datetimepicker) == 'function') {
15
+ if (!date_picker.hasClass('hasDatepicker')) {
16
+ date_picker.datetimepicker();
17
+ date_picker.trigger('focus');
18
+ }
19
+ }
20
+ return true;
21
+ });
22
+ });
@@ -0,0 +1,11 @@
1
+ ActiveScaffold::Bridges.bridge "FileColumn" do
2
+ install do
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column")
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
+ end
6
+ require File.join(File.dirname(__FILE__), "lib/as_file_column_bridge")
7
+ require File.join(File.dirname(__FILE__), "lib/form_ui")
8
+ require File.join(File.dirname(__FILE__), "lib/list_ui")
9
+ require File.join(File.dirname(__FILE__), "lib/file_column_helpers")
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ ActiveScaffold::DataStructures::Column.class_eval do
2
+ attr_accessor :file_column_display
3
+ end
4
+
5
+ module ActiveScaffold::Config
6
+ class Core < Base
7
+ attr_accessor :file_column_fields
8
+ def initialize_with_file_column(model_id)
9
+ initialize_without_file_column(model_id)
10
+
11
+ return unless ActiveScaffold::Bridges::Paperclip::Lib::FileColumnHelpers.klass_has_file_column_fields?(self.model)
12
+
13
+ self.model.send :extend, ActiveScaffold::Bridges::Paperclip::Lib::FileColumnHelpers
14
+
15
+ # include the "delete" helpers for use with active scaffold, unless they are already included
16
+ self.model.generate_delete_helpers
17
+
18
+ # switch on multipart
19
+ self.update.multipart = true
20
+ self.create.multipart = true
21
+
22
+ self.model.file_column_fields.each{ |field|
23
+ configure_file_column_field(field)
24
+ }
25
+ end
26
+
27
+ alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column")
28
+
29
+ def configure_file_column_field(field)
30
+ # set list_ui first because it gets its default value from form_ui
31
+ self.columns[field].list_ui ||= self.model.field_has_image_version?(field, "thumb") ? :thumbnail : :download_link_with_filename
32
+ self.columns[field].form_ui ||= :file_column
33
+
34
+ # these 2 parameters are necessary helper attributes for the file column that must be allowed to be set to the model by active scaffold.
35
+ self.columns[field].params.add "#{field}_temp", "delete_#{field}"
36
+
37
+ # set null to false so active_scaffold wont set it to null
38
+ # delete_file_column will take care of deleting a file or not.
39
+ self.model.columns_hash[field.to_s].instance_variable_set("@null", false)
40
+
41
+ rescue
42
+ false
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,59 @@
1
+ module ActiveScaffold
2
+ module Bridges
3
+ module Paperclip
4
+ module Lib
5
+ module FileColumnHelpers
6
+ class << self
7
+ def file_column_fields(klass)
8
+ klass.instance_methods.grep(/_just_uploaded\?$/).collect{|m| m[0..-16].to_sym }
9
+ end
10
+
11
+ def generate_delete_helpers(klass)
12
+ file_column_fields(klass).each { |field|
13
+ klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=")
14
+ attr_reader :delete_#{field}
15
+
16
+ def delete_#{field}=(value)
17
+ value = (value=="true") if String===value
18
+ return unless value
19
+
20
+ # passing nil to the file column causes the file to be deleted. Don't delete if we just uploaded a file!
21
+ self.#{field} = nil unless self.#{field}_just_uploaded?
22
+ end
23
+ EOF
24
+ }
25
+ end
26
+
27
+ def klass_has_file_column_fields?(klass)
28
+ true unless file_column_fields(klass).empty?
29
+ end
30
+ end
31
+
32
+ def file_column_fields
33
+ @file_column_fields||=FileColumnHelpers.file_column_fields(self)
34
+ end
35
+
36
+ def options_for_file_column_field(field)
37
+ self.allocate.send("#{field}_options")
38
+ end
39
+
40
+ def field_has_image_version?(field, version="thumb")
41
+ begin
42
+ # the only way to get to the options of a particular field is to use the instance method
43
+ options = options_for_file_column_field(field)
44
+ versions = options[:magick][:versions]
45
+ raise unless versions.stringify_keys[version]
46
+ true
47
+ rescue
48
+ false
49
+ end
50
+ end
51
+
52
+ def generate_delete_helpers
53
+ FileColumnHelpers.generate_delete_helpers(self)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ # Helpers that assist with the rendering of a Form Column
4
+ module FormColumnHelpers
5
+ def active_scaffold_input_file_column(column, options)
6
+ if @record.send(column.name)
7
+ # we already have a value? display the form for deletion.
8
+ if ActiveScaffold.js_framework == :jquery
9
+ js_remove_file_code = "$(this).prev().val('true'); $(this).parent().hide().next().show(); return false;";
10
+ else
11
+ js_remove_file_code = "$(this).previous().value='true'; p=$(this).up(); p.hide(); p.next().show(); return false;";
12
+ end
13
+ content_tag(
14
+ :div,
15
+ content_tag(
16
+ :div,
17
+ get_column_value(@record, column) + " " +
18
+ hidden_field(:record, "delete_#{column.name}", :value => "false") +
19
+ " | " +
20
+ content_tag(:a, as_(:remove_file), {:href => '#', :onclick => js_remove_file_code}),
21
+ {}
22
+ ) +
23
+ content_tag(
24
+ :div,
25
+ file_column_field("record", column.name, options),
26
+ :style => "display: none"
27
+ ),
28
+ {}
29
+ )
30
+ else
31
+ # no, just display the file_column_field
32
+ file_column_field("record", column.name, options)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ # Helpers that assist with the rendering of a List Column
4
+ module ListColumnHelpers
5
+ def active_scaffold_column_download_link_with_filename(column, record)
6
+ return nil if record.send(column.name).nil?
7
+ active_scaffold_column_download_link(column, record, File.basename(record.send(column.name)))
8
+ end
9
+
10
+ def active_scaffold_column_download_link(column, record, label = nil)
11
+ return nil if record.send(column.name).nil?
12
+ label||=as_(:download)
13
+ link_to( label, url_for_file_column(record, column.name.to_s), :popup => true)
14
+ end
15
+
16
+ def active_scaffold_column_thumbnail(column, record)
17
+ return nil if record.send(column.name).nil?
18
+ link_to(
19
+ image_tag(url_for_file_column(record, column.name.to_s, "thumb"), :border => 0),
20
+ url_for_file_column(record, column.name.to_s),
21
+ :popup => true)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ require File.join(File.dirname(__FILE__), "../test_helper.rb")
2
+
3
+ class DeleteFileColumnTest < Test::Unit::TestCase
4
+ def setup
5
+ DeleteFileColumn.generate_delete_helpers(MockModel)
6
+ @model = MockModel.new
7
+ @model.band_image = "coolio.jpg"
8
+ end
9
+
10
+ def test__file_column_fields
11
+ assert_equal(1, @model.file_column_fields.length)
12
+ end
13
+
14
+ def test__delete_band_image__boolean__should_delete
15
+ @model.delete_band_image = true
16
+ assert_nil @model.band_image
17
+ end
18
+
19
+ def test__delete_band_image__string__should_delete
20
+ @model.delete_band_image = "true"
21
+ assert_nil @model.band_image
22
+ end
23
+
24
+
25
+ def test__delete_band_image__boolean_false__shouldnt_delete
26
+ @model.delete_band_image = false
27
+ assert_not_nil @model.band_image
28
+ end
29
+
30
+ def test__delete_band_image__string_false__shouldnt_delete
31
+ @model.delete_band_image = "false"
32
+ assert_not_nil @model.band_image
33
+ end
34
+
35
+
36
+ def test__just_uploaded__shouldnt_delete
37
+ @model.band_image_just_uploaded = true
38
+ @model.delete_band_image = "true"
39
+ assert_not_nil(@model.band_image)
40
+ end
41
+
42
+
43
+ end
@@ -0,0 +1,9 @@
1
+ class MockModel
2
+ attr_accessor :name
3
+ attr_accessor :bio
4
+
5
+ attr_accessor :band_image
6
+ attr_accessor :band_image_just_uploaded
7
+ def band_image_just_uploaded?; self.band_image_just_uploaded ? true : false; end
8
+
9
+ end
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require "rubygems"
3
+ require 'active_support'
4
+
5
+ for file in ["../lib/delete_file_column.rb", "mock_model.rb"]
6
+ require File.expand_path(File.join(File.dirname(__FILE__), file))
7
+ end
8
+
9
+
10
+
11
+ def dbg
12
+ require 'ruby-debug'
13
+ Debugger.start
14
+ debugger
15
+ end
@@ -0,0 +1,10 @@
1
+ ActiveScaffold::Bridges.bridge "Paperclip" do
2
+ install do
3
+ if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip")
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
+ end
6
+ require File.join(File.dirname(__FILE__), "lib/form_ui")
7
+ require File.join(File.dirname(__FILE__), "lib/list_ui")
8
+ ActiveScaffold::Config::Core.send :include, ActiveScaffold::Bridges::Paperclip::Lib::PaperclipBridge
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module FormColumnHelpers
4
+ def active_scaffold_input_paperclip(column, options)
5
+ options = active_scaffold_input_text_options(options)
6
+ input = file_field(:record, column.name, options)
7
+ paperclip = @record.send("#{column.name}")
8
+ if paperclip.file?
9
+ if ActiveScaffold.js_framework == :jquery
10
+ js_remove_file_code = "$(this).prev().val('true'); $(this).parent().hide().next().show(); return false;";
11
+ else
12
+ js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;";
13
+ end
14
+
15
+ content = active_scaffold_column_paperclip(column, @record)
16
+ content_tag(:div,
17
+ content + " | " +
18
+ hidden_field(:record, "delete_#{column.name}", :value => "false") +
19
+ content_tag(:a, as_(:remove_file), {:href => '#', :onclick => js_remove_file_code})
20
+ ) + content_tag(:div, input, :style => "display: none")
21
+ else
22
+ input
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module ListColumnHelpers
4
+ def active_scaffold_column_paperclip(column, record)
5
+ paperclip = record.send("#{column.name}")
6
+ return nil unless paperclip.file?
7
+ content = if paperclip.styles.include?(ActiveScaffold::Bridges::Paperclip::Lib::PaperclipBridgeHelpers.thumbnail_style)
8
+ image_tag(paperclip.url(ActiveScaffold::Bridges::Paperclip::Lib::PaperclipBridgeHelpers.thumbnail_style), :border => 0)
9
+ else
10
+ paperclip.original_filename
11
+ end
12
+ link_to(content, paperclip.url, :popup => true)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ module ActiveScaffold
2
+ module Bridges
3
+ module Paperclip
4
+ module Lib
5
+ module PaperclipBridge
6
+ def initialize_with_paperclip(model_id)
7
+ initialize_without_paperclip(model_id)
8
+ return unless self.model.respond_to?(:attachment_definitions) && !self.model.attachment_definitions.nil?
9
+
10
+ self.update.multipart = true
11
+ self.create.multipart = true
12
+
13
+ self.model.attachment_definitions.keys.each do |field|
14
+ configure_paperclip_field(field.to_sym)
15
+ # define the "delete" helper for use with active scaffold, unless it's already defined
16
+ ActiveScaffold::Bridges::Paperclip::Lib::PaperclipBridgeHelpers.generate_delete_helper(self.model, field)
17
+ end
18
+ end
19
+
20
+ def self.included(base)
21
+ base.alias_method_chain :initialize, :paperclip
22
+ end
23
+
24
+ private
25
+ def configure_paperclip_field(field)
26
+ self.columns << field
27
+ self.columns[field].form_ui ||= :paperclip
28
+ self.columns[field].params.add "delete_#{field}"
29
+
30
+ [:file_name, :content_type, :file_size, :updated_at].each do |f|
31
+ self.columns.exclude("#{field}_#{f}".to_sym)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ module ActiveScaffold
2
+ module Bridges
3
+ module Paperclip
4
+ module Lib
5
+ module PaperclipBridgeHelpers
6
+ mattr_accessor :thumbnail_style
7
+ self.thumbnail_style = :thumbnail
8
+
9
+ def self.generate_delete_helper(klass, field)
10
+ klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("delete_#{field}=")
11
+ attr_reader :delete_#{field}
12
+
13
+ def delete_#{field}=(value)
14
+ value = (value == "true") if String === value
15
+ return unless value
16
+
17
+ # passing nil to the file column causes the file to be deleted. Don't delete if we just uploaded a file!
18
+ self.#{field} = nil unless self.#{field}.dirty?
19
+ end
20
+ EOF
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ ActiveScaffold::Bridges.bridge "SemanticAttributes" do
2
+ install do
3
+ require File.join(File.dirname(__FILE__), "lib/semantic_attributes_bridge.rb")
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveScaffold
2
+ module SemanticAttributesBridge
3
+ def self.included(base)
4
+ base.class_eval { alias_method_chain :initialize, :semantic_attributes }
5
+ end
6
+
7
+ def initialize_with_semantic_attributes(name, active_record_class)
8
+ initialize_without_semantic_attributes(name, active_record_class)
9
+ self.required = !active_record_class.semantic_attributes[self.name].predicates.find {|p| p.allow_empty? == false }.nil?
10
+ active_record_class.semantic_attributes[self.name].predicates.find do |p|
11
+ sem_type = p.class.to_s.split('::')[1].underscore.to_sym
12
+ next if [:required, :association].include?(sem_type)
13
+ @form_ui = sem_type
14
+ end
15
+ end
16
+ end
17
+ end
18
+ ActiveScaffold::DataStructures::Column.class_eval do
19
+ include ActiveScaffold::SemanticAttributesBridge
20
+ end