active_scaffold 3.0.0

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 (272) hide show
  1. data/.autotest +27 -0
  2. data/CHANGELOG +152 -0
  3. data/Gemfile +4 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README +51 -0
  6. data/Rakefile +24 -0
  7. data/active_scaffold.gemspec +24 -0
  8. data/environment.rb +22 -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/cross.png +0 -0
  14. data/frontends/default/images/indicator-small.gif +0 -0
  15. data/frontends/default/images/indicator.gif +0 -0
  16. data/frontends/default/images/magnifier.png +0 -0
  17. data/frontends/default/javascripts/jquery/active_scaffold.js +957 -0
  18. data/frontends/default/javascripts/jquery/jquery.editinplace.js +726 -0
  19. data/frontends/default/javascripts/prototype/active_scaffold.js +954 -0
  20. data/frontends/default/javascripts/prototype/dhtml_history.js +867 -0
  21. data/frontends/default/javascripts/prototype/form_enhancements.js +117 -0
  22. data/frontends/default/javascripts/prototype/rico_corner.js +370 -0
  23. data/frontends/default/stylesheets/stylesheet-ie.css +35 -0
  24. data/frontends/default/stylesheets/stylesheet.css +858 -0
  25. data/frontends/default/views/_add_existing_form.html.erb +30 -0
  26. data/frontends/default/views/_base_form.html.erb +41 -0
  27. data/frontends/default/views/_create_form.html.erb +6 -0
  28. data/frontends/default/views/_create_form_on_list.html.erb +5 -0
  29. data/frontends/default/views/_field_search.html.erb +32 -0
  30. data/frontends/default/views/_form.html.erb +24 -0
  31. data/frontends/default/views/_form_association.html.erb +14 -0
  32. data/frontends/default/views/_form_association_footer.html.erb +40 -0
  33. data/frontends/default/views/_form_attribute.html.erb +15 -0
  34. data/frontends/default/views/_form_hidden_attribute.html.erb +2 -0
  35. data/frontends/default/views/_form_messages.html.erb +5 -0
  36. data/frontends/default/views/_horizontal_subform.html.erb +19 -0
  37. data/frontends/default/views/_horizontal_subform_header.html.erb +10 -0
  38. data/frontends/default/views/_horizontal_subform_record.html.erb +37 -0
  39. data/frontends/default/views/_human_conditions.html.erb +1 -0
  40. data/frontends/default/views/_list.html.erb +18 -0
  41. data/frontends/default/views/_list_actions.html.erb +16 -0
  42. data/frontends/default/views/_list_calculations.html.erb +16 -0
  43. data/frontends/default/views/_list_column_headings.html.erb +12 -0
  44. data/frontends/default/views/_list_header.html.erb +12 -0
  45. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  46. data/frontends/default/views/_list_messages.html.erb +32 -0
  47. data/frontends/default/views/_list_pagination.html.erb +11 -0
  48. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  49. data/frontends/default/views/_list_record.html.erb +14 -0
  50. data/frontends/default/views/_list_record_columns.html.erb +8 -0
  51. data/frontends/default/views/_list_with_header.html.erb +32 -0
  52. data/frontends/default/views/_messages.html.erb +10 -0
  53. data/frontends/default/views/_render_field.js.rjs +13 -0
  54. data/frontends/default/views/_row.html.erb +12 -0
  55. data/frontends/default/views/_search.html.erb +34 -0
  56. data/frontends/default/views/_search_attribute.html.erb +10 -0
  57. data/frontends/default/views/_show.html.erb +8 -0
  58. data/frontends/default/views/_show_columns.html.erb +12 -0
  59. data/frontends/default/views/_update_actions.html.erb +9 -0
  60. data/frontends/default/views/_update_form.html.erb +5 -0
  61. data/frontends/default/views/_vertical_subform.html.erb +12 -0
  62. data/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  63. data/frontends/default/views/add_existing.js.rjs +17 -0
  64. data/frontends/default/views/add_existing_form.html.erb +5 -0
  65. data/frontends/default/views/create.html.erb +5 -0
  66. data/frontends/default/views/delete.html.erb +13 -0
  67. data/frontends/default/views/destroy.js.rjs +5 -0
  68. data/frontends/default/views/edit_associated.js.rjs +11 -0
  69. data/frontends/default/views/field_search.html.erb +5 -0
  70. data/frontends/default/views/form_messages.js.rjs +1 -0
  71. data/frontends/default/views/list.html.erb +1 -0
  72. data/frontends/default/views/list.js.rjs +1 -0
  73. data/frontends/default/views/on_action_update.js.rjs +8 -0
  74. data/frontends/default/views/on_create.js.rjs +24 -0
  75. data/frontends/default/views/on_update.js.rjs +15 -0
  76. data/frontends/default/views/search.html.erb +5 -0
  77. data/frontends/default/views/show.html.erb +5 -0
  78. data/frontends/default/views/update.html.erb +8 -0
  79. data/frontends/default/views/update_column.js.rjs +13 -0
  80. data/frontends/default/views/update_row.js.rjs +1 -0
  81. data/init.rb +1 -0
  82. data/install_assets.rb +44 -0
  83. data/lib/active_record_permissions.rb +134 -0
  84. data/lib/active_scaffold.rb +279 -0
  85. data/lib/active_scaffold/actions/common_search.rb +22 -0
  86. data/lib/active_scaffold/actions/core.rb +150 -0
  87. data/lib/active_scaffold/actions/create.rb +152 -0
  88. data/lib/active_scaffold/actions/delete.rb +72 -0
  89. data/lib/active_scaffold/actions/field_search.rb +82 -0
  90. data/lib/active_scaffold/actions/list.rb +128 -0
  91. data/lib/active_scaffold/actions/mark.rb +50 -0
  92. data/lib/active_scaffold/actions/nested.rb +241 -0
  93. data/lib/active_scaffold/actions/search.rb +47 -0
  94. data/lib/active_scaffold/actions/show.rb +54 -0
  95. data/lib/active_scaffold/actions/subform.rb +17 -0
  96. data/lib/active_scaffold/actions/update.rb +134 -0
  97. data/lib/active_scaffold/attribute_params.rb +207 -0
  98. data/lib/active_scaffold/bridges/ancestry/bridge.rb +5 -0
  99. data/lib/active_scaffold/bridges/ancestry/lib/ancestry_bridge.rb +38 -0
  100. data/lib/active_scaffold/bridges/bridge.rb +52 -0
  101. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +16 -0
  102. data/lib/active_scaffold/bridges/calendar_date_select/lib/as_cds_bridge.rb +79 -0
  103. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +7 -0
  104. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +38 -0
  105. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +26 -0
  106. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +35 -0
  107. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +17 -0
  108. data/lib/active_scaffold/bridges/date_picker/bridge.rb +22 -0
  109. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +225 -0
  110. data/lib/active_scaffold/bridges/date_picker/public/javascripts/date_picker_bridge.js +22 -0
  111. data/lib/active_scaffold/bridges/file_column/bridge.rb +11 -0
  112. data/lib/active_scaffold/bridges/file_column/lib/as_file_column_bridge.rb +46 -0
  113. data/lib/active_scaffold/bridges/file_column/lib/file_column_helpers.rb +59 -0
  114. data/lib/active_scaffold/bridges/file_column/lib/form_ui.rb +37 -0
  115. data/lib/active_scaffold/bridges/file_column/lib/list_ui.rb +26 -0
  116. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
  117. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
  118. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
  119. data/lib/active_scaffold/bridges/paperclip/bridge.rb +12 -0
  120. data/lib/active_scaffold/bridges/paperclip/lib/form_ui.rb +27 -0
  121. data/lib/active_scaffold/bridges/paperclip/lib/list_ui.rb +16 -0
  122. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge.rb +38 -0
  123. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge_helpers.rb +26 -0
  124. data/lib/active_scaffold/bridges/semantic_attributes/bridge.rb +5 -0
  125. data/lib/active_scaffold/bridges/semantic_attributes/lib/semantic_attributes_bridge.rb +20 -0
  126. data/lib/active_scaffold/bridges/shared/date_bridge.rb +187 -0
  127. data/lib/active_scaffold/bridges/tiny_mce/bridge.rb +5 -0
  128. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +45 -0
  129. data/lib/active_scaffold/bridges/validation_reflection/bridge.rb +8 -0
  130. data/lib/active_scaffold/bridges/validation_reflection/lib/validation_reflection_bridge.rb +21 -0
  131. data/lib/active_scaffold/config/base.rb +54 -0
  132. data/lib/active_scaffold/config/core.rb +229 -0
  133. data/lib/active_scaffold/config/create.rb +43 -0
  134. data/lib/active_scaffold/config/delete.rb +25 -0
  135. data/lib/active_scaffold/config/field_search.rb +74 -0
  136. data/lib/active_scaffold/config/form.rb +46 -0
  137. data/lib/active_scaffold/config/list.rb +174 -0
  138. data/lib/active_scaffold/config/mark.rb +22 -0
  139. data/lib/active_scaffold/config/nested.rb +43 -0
  140. data/lib/active_scaffold/config/search.rb +68 -0
  141. data/lib/active_scaffold/config/show.rb +34 -0
  142. data/lib/active_scaffold/config/subform.rb +35 -0
  143. data/lib/active_scaffold/config/update.rb +38 -0
  144. data/lib/active_scaffold/configurable.rb +29 -0
  145. data/lib/active_scaffold/constraints.rb +179 -0
  146. data/lib/active_scaffold/data_structures/action_columns.rb +133 -0
  147. data/lib/active_scaffold/data_structures/action_link.rb +162 -0
  148. data/lib/active_scaffold/data_structures/action_links.rb +59 -0
  149. data/lib/active_scaffold/data_structures/actions.rb +45 -0
  150. data/lib/active_scaffold/data_structures/column.rb +348 -0
  151. data/lib/active_scaffold/data_structures/columns.rb +75 -0
  152. data/lib/active_scaffold/data_structures/error_message.rb +24 -0
  153. data/lib/active_scaffold/data_structures/nested_info.rb +108 -0
  154. data/lib/active_scaffold/data_structures/set.rb +62 -0
  155. data/lib/active_scaffold/data_structures/sorting.rb +168 -0
  156. data/lib/active_scaffold/finder.rb +333 -0
  157. data/lib/active_scaffold/helpers/association_helpers.rb +40 -0
  158. data/lib/active_scaffold/helpers/controller_helpers.rb +40 -0
  159. data/lib/active_scaffold/helpers/country_helpers.rb +352 -0
  160. data/lib/active_scaffold/helpers/form_column_helpers.rb +343 -0
  161. data/lib/active_scaffold/helpers/human_condition_helpers.rb +59 -0
  162. data/lib/active_scaffold/helpers/id_helpers.rb +131 -0
  163. data/lib/active_scaffold/helpers/list_column_helpers.rb +363 -0
  164. data/lib/active_scaffold/helpers/pagination_helpers.rb +55 -0
  165. data/lib/active_scaffold/helpers/search_column_helpers.rb +238 -0
  166. data/lib/active_scaffold/helpers/show_column_helpers.rb +46 -0
  167. data/lib/active_scaffold/helpers/view_helpers.rb +315 -0
  168. data/lib/active_scaffold/locale/de.rb +113 -0
  169. data/lib/active_scaffold/locale/en.rb +118 -0
  170. data/lib/active_scaffold/locale/es.yml +112 -0
  171. data/lib/active_scaffold/locale/fr.rb +113 -0
  172. data/lib/active_scaffold/locale/hu.yml +63 -0
  173. data/lib/active_scaffold/locale/ja.yml +64 -0
  174. data/lib/active_scaffold/locale/ru.yml +62 -0
  175. data/lib/active_scaffold/marked_model.rb +38 -0
  176. data/lib/dhtml_confirm.rb +54 -0
  177. data/lib/extensions/action_controller_rendering.rb +20 -0
  178. data/lib/extensions/action_view_rendering.rb +113 -0
  179. data/lib/extensions/action_view_resolver.rb +7 -0
  180. data/lib/extensions/active_record_offset.rb +12 -0
  181. data/lib/extensions/array.rb +7 -0
  182. data/lib/extensions/localize.rb +10 -0
  183. data/lib/extensions/name_option_for_datetime.rb +12 -0
  184. data/lib/extensions/nil_id_in_url_params.rb +7 -0
  185. data/lib/extensions/paginator_extensions.rb +26 -0
  186. data/lib/extensions/reverse_associations.rb +62 -0
  187. data/lib/extensions/routing_mapper.rb +34 -0
  188. data/lib/extensions/to_label.rb +8 -0
  189. data/lib/extensions/unsaved_associated.rb +61 -0
  190. data/lib/extensions/unsaved_record.rb +20 -0
  191. data/lib/extensions/usa_state.rb +46 -0
  192. data/lib/generators/active_scaffold/USAGE +29 -0
  193. data/lib/generators/active_scaffold/active_scaffold_generator.rb +20 -0
  194. data/lib/generators/active_scaffold_controller/USAGE +19 -0
  195. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +28 -0
  196. data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
  197. data/lib/generators/active_scaffold_setup/USAGE +10 -0
  198. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +53 -0
  199. data/lib/paginator.rb +136 -0
  200. data/lib/responds_to_parent.rb +70 -0
  201. data/public/blank.html +33 -0
  202. data/shoulda_macros/macros.rb +136 -0
  203. data/test/bridges/bridge_test.rb +47 -0
  204. data/test/config/base_test.rb +15 -0
  205. data/test/config/create_test.rb +55 -0
  206. data/test/config/list_test.rb +74 -0
  207. data/test/config/show_test.rb +43 -0
  208. data/test/config/update_test.rb +17 -0
  209. data/test/const_mocker.rb +36 -0
  210. data/test/data_structures/action_columns_test.rb +113 -0
  211. data/test/data_structures/action_link_test.rb +78 -0
  212. data/test/data_structures/action_links_test.rb +78 -0
  213. data/test/data_structures/actions_test.rb +25 -0
  214. data/test/data_structures/association_column_test.rb +42 -0
  215. data/test/data_structures/column_test.rb +185 -0
  216. data/test/data_structures/columns_test.rb +69 -0
  217. data/test/data_structures/error_message_test.rb +28 -0
  218. data/test/data_structures/set_test.rb +86 -0
  219. data/test/data_structures/sorting_test.rb +126 -0
  220. data/test/data_structures/standard_column_test.rb +24 -0
  221. data/test/data_structures/virtual_column_test.rb +23 -0
  222. data/test/extensions/active_record_test.rb +45 -0
  223. data/test/extensions/array_test.rb +12 -0
  224. data/test/helpers/form_column_helpers_test.rb +31 -0
  225. data/test/helpers/list_column_helpers_test.rb +31 -0
  226. data/test/helpers/pagination_helpers_test.rb +55 -0
  227. data/test/misc/active_record_permissions_test.rb +154 -0
  228. data/test/misc/attribute_params_test.rb +110 -0
  229. data/test/misc/configurable_test.rb +96 -0
  230. data/test/misc/constraints_test.rb +193 -0
  231. data/test/misc/finder_test.rb +93 -0
  232. data/test/misc/lang_test.rb +12 -0
  233. data/test/mock_app/.gitignore +2 -0
  234. data/test/mock_app/app/controllers/application_controller.rb +10 -0
  235. data/test/mock_app/app/helpers/application_helper.rb +3 -0
  236. data/test/mock_app/config/boot.rb +110 -0
  237. data/test/mock_app/config/database.yml +16 -0
  238. data/test/mock_app/config/environment.rb +43 -0
  239. data/test/mock_app/config/environments/development.rb +17 -0
  240. data/test/mock_app/config/environments/production.rb +28 -0
  241. data/test/mock_app/config/environments/test.rb +28 -0
  242. data/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  243. data/test/mock_app/config/initializers/inflections.rb +10 -0
  244. data/test/mock_app/config/initializers/mime_types.rb +5 -0
  245. data/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  246. data/test/mock_app/config/initializers/session_store.rb +15 -0
  247. data/test/mock_app/config/locales/en.yml +5 -0
  248. data/test/mock_app/config/routes.rb +43 -0
  249. data/test/mock_app/db/test.sqlite3 +1 -0
  250. data/test/mock_app/public/blank.html +33 -0
  251. data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  252. data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  253. data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  254. data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  255. data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  256. data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  257. data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  258. data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  259. data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  260. data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  261. data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  262. data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  263. data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  264. data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  265. data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  266. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  267. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +839 -0
  268. data/test/model_stub.rb +55 -0
  269. data/test/run_all.rb +8 -0
  270. data/test/test_helper.rb +39 -0
  271. data/uninstall.rb +13 -0
  272. metadata +478 -0
@@ -0,0 +1,40 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module AssociationHelpers
4
+ # Provides a way to honor the :conditions on an association while searching the association's klass
5
+ def association_options_find(association, conditions = nil)
6
+ association.klass.where(controller.send(:merge_conditions, conditions, association.options[:conditions])).all
7
+ end
8
+
9
+ def association_options_count(association, conditions = nil)
10
+ association.klass.where(controller.send(:merge_conditions, conditions, association.options[:conditions])).count
11
+ end
12
+
13
+ # returns options for the given association as a collection of [id, label] pairs intended for the +options_for_select+ helper.
14
+ def options_for_association(association, include_all = false)
15
+ available_records = association_options_find(association, include_all ? nil : options_for_association_conditions(association))
16
+ available_records ||= []
17
+ available_records.sort{|a,b| a.to_label <=> b.to_label}.collect { |model| [ model.to_label, model.id ] }
18
+ end
19
+
20
+ def options_for_association_count(association)
21
+ association_options_count(association, options_for_association_conditions(association))
22
+ end
23
+
24
+ # A useful override for customizing the records present in an association dropdown.
25
+ # Should work in both the subform and form_ui=>:select modes.
26
+ # Check association.name to specialize the conditions per-column.
27
+ def options_for_association_conditions(association)
28
+ return nil if association.options[:through]
29
+ case association.macro
30
+ when :has_one, :has_many
31
+ # Find only orphaned objects
32
+ "#{association.primary_key_name} IS NULL"
33
+ when :belongs_to, :has_and_belongs_to_many
34
+ # Find all
35
+ nil
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module ControllerHelpers
4
+ def self.included(controller)
5
+ controller.class_eval { helper_method :params_for, :main_path_to_return }
6
+ end
7
+
8
+ include ActiveScaffold::Helpers::IdHelpers
9
+
10
+ def params_for(options = {})
11
+ # :adapter and :position are one-use rendering arguments. they should not propagate.
12
+ # :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
13
+ # and wow. no we don't want to propagate :record.
14
+ # :commit is a special rails variable for form buttons
15
+ blacklist = [:adapter, :position, :sort, :sort_direction, :page, :record, :commit, :_method, :authenticity_token, :iframe]
16
+ unless @params_for
17
+ @params_for = {}
18
+ params.select { |key, value| blacklist.exclude? key.to_sym if key }.each {|key, value| @params_for[key.to_sym] = value.duplicable? ? value.clone : value}
19
+ @params_for[:controller] = '/' + @params_for[:controller].to_s unless @params_for[:controller].to_s.first(1) == '/' # for namespaced controllers
20
+ @params_for.delete(:id) if @params_for[:id].nil?
21
+ end
22
+ @params_for.merge(options)
23
+ end
24
+
25
+ # Parameters to generate url to the main page (override if the ActiveScaffold is used as a component on another controllers page)
26
+ def main_path_to_return
27
+ parameters = {}
28
+ if params[:parent_controller]
29
+ parameters[:controller] = params[:parent_controller]
30
+ parameters[:eid] = params[:parent_controller]
31
+ end
32
+ parameters[:parent_column] = nil
33
+ parameters[:parent_id] = nil
34
+ parameters[:action] = "index"
35
+ parameters[:id] = nil
36
+ params_for(parameters)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,352 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module CountryHelpers
4
+ # Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
5
+ def country_select(object, method, priority_countries = nil, options = {}, html_options = {})
6
+ ActionView::Helpers::InstanceTag.new(object, method, self, options.delete(:object)).to_country_select_tag(priority_countries, options, html_options)
7
+ end
8
+
9
+ def usa_state_select(object, method, priority_states = nil, options = {}, html_options = {})
10
+ ActionView::Helpers::InstanceTag.new(object, method, self, options.delete(:object)).to_usa_state_select_tag(priority_states, options, html_options)
11
+ end
12
+
13
+ # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to
14
+ # have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so
15
+ # that they will be listed above the rest of the (long) list.
16
+ #
17
+ # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
18
+ def country_options_for_select(selected = nil, priority_countries = nil)
19
+ if priority_countries
20
+ country_options = options_for_select(priority_countries.collect {|country| [I18n.t("countries.#{country}", :default => country.to_s.titleize), country.to_s]} + [['-------------', '']], :selected => selected, :disabled => '')
21
+ else
22
+ country_options = ""
23
+ end
24
+
25
+ return country_options + options_for_select(COUNTRIES.collect {|country| [I18n.t("countries.#{country}", :default => country.to_s.titleize), country.to_s]}, :selected => selected)
26
+ end
27
+
28
+ # Returns a string of option tags for the states in the United States. Supply a state name as +selected to
29
+ # have it marked as the selected option tag. Included also is the option to set a couple of +priority_states+
30
+ # in case you want to highligh a local area
31
+ # NOTE: Only the option tags are returned from this method, wrap it in a <select>
32
+ def usa_state_options_for_select(selected = nil, priority_states = nil)
33
+ if priority_states
34
+ state_options = options_for_select(priority_states + [['-------------', '']], :selected => selected, :disabled => '')
35
+ else
36
+ state_options = ""
37
+ end
38
+
39
+ if priority_states && priority_states.include?(selected)
40
+ state_options += options_for_select(USASTATES - priority_states, :selected => selected)
41
+ else
42
+ state_options += options_for_select(USASTATES, :selected => selected)
43
+ end
44
+
45
+ return state_options
46
+ end
47
+ # All the countries included in the country_options output.
48
+ COUNTRIES = [
49
+ :afghanistan,
50
+ :aland_islands,
51
+ :albania,
52
+ :algeria,
53
+ :american_samoa,
54
+ :andorra,
55
+ :angola,
56
+ :anguilla,
57
+ :antarctica,
58
+ :antigua_and_barbuda,
59
+ :argentina,
60
+ :armenia,
61
+ :aruba,
62
+ :australia,
63
+ :austria,
64
+ :azerbaijan,
65
+ :bahamas,
66
+ :bahrain,
67
+ :bangladesh,
68
+ :barbados,
69
+ :belarus,
70
+ :belgium,
71
+ :belize,
72
+ :benin,
73
+ :bermuda,
74
+ :bhutan,
75
+ :bolivia,
76
+ :bosnia_and_herzegowina,
77
+ :botswana,
78
+ :bouvet_island,
79
+ :brazil,
80
+ :british_indian_ocean_territory,
81
+ :brunei_darussalam,
82
+ :bulgaria,
83
+ :burkina_faso,
84
+ :burundi,
85
+ :cambodia,
86
+ :cameroon,
87
+ :canada,
88
+ :cape_verde,
89
+ :cayman_islands,
90
+ :central_african_republic,
91
+ :chad,
92
+ :chile,
93
+ :china,
94
+ :christmas_island,
95
+ :cocos_keeling_islands,
96
+ :colombia,
97
+ :comoros,
98
+ :congo,
99
+ :congo_the_democratic_republic_of_the,
100
+ :cook_islands,
101
+ :costa_rica,
102
+ :cote_divoire,
103
+ :croatia,
104
+ :cuba,
105
+ :cyprus,
106
+ :czech_republic,
107
+ :denmark,
108
+ :djibouti,
109
+ :dominica,
110
+ :dominican_republic,
111
+ :ecuador,
112
+ :egypt,
113
+ :el_salvador,
114
+ :equatorial_guinea,
115
+ :eritrea,
116
+ :estonia,
117
+ :ethiopia,
118
+ :falkland_islands_malvinas,
119
+ :faroe_islands,
120
+ :fiji,
121
+ :finland,
122
+ :france,
123
+ :french_guiana,
124
+ :french_polynesia,
125
+ :french_southern_territories,
126
+ :gabon,
127
+ :gambia,
128
+ :georgia,
129
+ :germany,
130
+ :ghana,
131
+ :gibraltar,
132
+ :greece,
133
+ :greenland,
134
+ :grenada,
135
+ :guadeloupe,
136
+ :guam,
137
+ :guatemala,
138
+ :guernsey,
139
+ :guinea,
140
+ :guinea_bissau,
141
+ :guyana,
142
+ :haiti,
143
+ :heard_and_mcdonald_islands,
144
+ :holy_see_vatican_city_state,
145
+ :honduras,
146
+ :hong_kong,
147
+ :hungary,
148
+ :iceland,
149
+ :india,
150
+ :indonesia,
151
+ :iran_islamic_republic_of,
152
+ :iraq,
153
+ :ireland,
154
+ :isle_of_man,
155
+ :israel,
156
+ :italy,
157
+ :jamaica,
158
+ :japan,
159
+ :jersey,
160
+ :jordan,
161
+ :kazakhstan,
162
+ :kenya,
163
+ :kiribati,
164
+ :korea_democratic_peoples_republic_of,
165
+ :korea_republic_of,
166
+ :kuwait,
167
+ :kyrgyzstan,
168
+ :lao_peoples_democratic_republic,
169
+ :latvia,
170
+ :lebanon,
171
+ :lesotho,
172
+ :liberia,
173
+ :libyan_arab_jamahiriya,
174
+ :liechtenstein,
175
+ :lithuania,
176
+ :luxembourg,
177
+ :macao,
178
+ :macedonia_the_former_yugoslav_republic_of,
179
+ :madagascar,
180
+ :malawi,
181
+ :malaysia,
182
+ :maldives,
183
+ :mali,
184
+ :malta,
185
+ :marshall_islands,
186
+ :martinique,
187
+ :mauritania,
188
+ :mauritius,
189
+ :mayotte,
190
+ :mexico,
191
+ :micronesia_federated_states_of,
192
+ :moldova_republic_of,
193
+ :monaco,
194
+ :mongolia,
195
+ :montenegro,
196
+ :montserrat,
197
+ :morocco,
198
+ :mozambique,
199
+ :myanmar,
200
+ :namibia,
201
+ :nauru,
202
+ :nepal,
203
+ :netherlands,
204
+ :netherlands_antilles,
205
+ :new_caledonia,
206
+ :new_zealand,
207
+ :nicaragua,
208
+ :niger,
209
+ :nigeria,
210
+ :niue,
211
+ :norfolk_island,
212
+ :northern_mariana_islands,
213
+ :norway,
214
+ :oman,
215
+ :pakistan,
216
+ :palau,
217
+ :palestinian_territory_occupied,
218
+ :panama,
219
+ :papua_new_guinea,
220
+ :paraguay,
221
+ :peru,
222
+ :philippines,
223
+ :pitcairn,
224
+ :poland,
225
+ :portugal,
226
+ :puerto_rico,
227
+ :qatar,
228
+ :reunion,
229
+ :romania,
230
+ :russian_federation,
231
+ :rwanda,
232
+ :saint_barthelemy,
233
+ :saint_helena,
234
+ :saint_kitts_and_nevis,
235
+ :saint_lucia,
236
+ :saint_pierre_and_miquelon,
237
+ :saint_vincent_and_the_grenadines,
238
+ :samoa,
239
+ :san_marino,
240
+ :sao_tome_and_principe,
241
+ :saudi_arabia,
242
+ :senegal,
243
+ :serbia,
244
+ :seychelles,
245
+ :sierra_leone,
246
+ :singapore,
247
+ :slovakia,
248
+ :slovenia,
249
+ :solomon_islands,
250
+ :somalia,
251
+ :south_africa,
252
+ :south_georgia_and_the_south_sandwich_islands,
253
+ :spain,
254
+ :sri_lanka,
255
+ :sudan,
256
+ :suriname,
257
+ :svalbard_and_jan_mayen,
258
+ :swaziland,
259
+ :sweden,
260
+ :switzerland,
261
+ :syrian_arab_republic,
262
+ :taiwan_province_of_china,
263
+ :tajikistan,
264
+ :tanzania_united_republic_of,
265
+ :thailand,
266
+ :timor_leste,
267
+ :togo,
268
+ :tokelau,
269
+ :tonga,
270
+ :trinidad_and_tobago,
271
+ :tunisia,
272
+ :turkey,
273
+ :turkmenistan,
274
+ :turks_and_caicos_islands,
275
+ :tuvalu,
276
+ :uganda,
277
+ :ukraine,
278
+ :united_arab_emirates,
279
+ :united_kingdom,
280
+ :united_states,
281
+ :united_states_minor_outlying_islands,
282
+ :uruguay,
283
+ :uzbekistan,
284
+ :vanuatu,
285
+ :venezuela,
286
+ :viet_nam,
287
+ :virgin_islands_british,
288
+ :virgin_islands_us,
289
+ :wallis_and_futuna,
290
+ :western_sahara,
291
+ :yemen,
292
+ :zambia,
293
+ :zimbabwe] unless const_defined?("COUNTRIES")
294
+
295
+
296
+ USASTATES = [["Alabama", "AL"], ["Alaska", "AK"], ["Arizona", "AZ"], ["Arkansas", "AR"], ["California", "CA"], ["Colorado", "CO"], ["Connecticut", "CT"], ["Delaware", "DE"], ["District of Columbia", "DC"], ["Florida", "FL"], ["Georgia", "GA"], ["Hawaii", "HI"], ["Idaho", "ID"], ["Illinois", "IL"], ["Indiana", "IN"], ["Iowa", "IA"], ["Kansas", "KS"], ["Kentucky", "KY"], ["Louisiana", "LA"], ["Maine", "ME"], ["Maryland", "MD"], ["Massachusetts", "MA"], ["Michigan", "MI"], ["Minnesota", "MN"], ["Mississippi", "MS"], ["Missouri", "MO"], ["Montana", "MT"], ["Nebraska", "NE"], ["Nevada", "NV"], ["New Hampshire", "NH"], ["New Jersey", "NJ"], ["New Mexico", "NM"], ["New York", "NY"], ["North Carolina", "NC"], ["North Dakota", "ND"], ["Ohio", "OH"], ["Oklahoma", "OK"], ["Oregon", "OR"], ["Pennsylvania", "PA"], ["Rhode Island", "RI"], ["South Carolina", "SC"], ["South Dakota", "SD"], ["Tennessee", "TN"], ["Texas", "TX"], ["Utah", "UT"], ["Vermont", "VT"], ["Virginia", "VA"], ["Washington", "WA"], ["Wisconsin", "WI"], ["West Virginia", "WV"], ["Wyoming", "WY"]] unless const_defined?("USASTATES")
297
+
298
+ class ActionView::Helpers::InstanceTag #:nodoc:
299
+ include CountryHelpers
300
+
301
+ def to_country_select_tag(priority_countries, options, html_options)
302
+ html_options = html_options.stringify_keys
303
+ add_default_name_and_id(html_options)
304
+ value = value(object)
305
+ selected_value = options.has_key?(:selected) ? options[:selected] : value
306
+ content_tag("select",
307
+ add_options(
308
+ country_options_for_select(selected_value, priority_countries),
309
+ options, selected_value
310
+ ), html_options
311
+ )
312
+ end
313
+
314
+ def to_usa_state_select_tag(priority_states, options, html_options)
315
+ html_options = html_options.stringify_keys
316
+ add_default_name_and_id(html_options)
317
+ value = value(object)
318
+ selected_value = options.has_key?(:selected) ? options[:selected] : value
319
+ content_tag("select", add_options(usa_state_options_for_select(selected_value, priority_states), options, selected_value), html_options)
320
+ end
321
+ end
322
+ end
323
+
324
+ module FormColumnHelpers
325
+ def active_scaffold_input_country(column, options)
326
+ select_options = {:prompt => as_(:_select_)}
327
+ select_options.merge!(options)
328
+ options.reverse_merge!(column.options).except!(:prompt, :priority)
329
+ options[:name] += '[]' if options[:multiple]
330
+ country_select(:record, column.name, column.options[:priority] || [:united_states], select_options, options)
331
+ end
332
+
333
+ def active_scaffold_input_usa_state(column, options)
334
+ select_options = {:prompt => as_(:_select_)}
335
+ select_options.merge!(options)
336
+ options.reverse_merge!(column.options).except!(:prompt, :priority)
337
+ options[:name] += '[]' if options[:multiple]
338
+ usa_state_select(:record, column.name, column.options[:priority], select_options, options)
339
+ end
340
+ end
341
+
342
+ module SearchColumnHelpers
343
+ def active_scaffold_search_country(column, options)
344
+ active_scaffold_input_country(column, options.merge!(:selected => options.delete(:value)))
345
+ end
346
+
347
+ def active_scaffold_search_usa_state(column, options)
348
+ active_scaffold_input_usa_state(column, options.merge!(:selected => options.delete(:value)))
349
+ end
350
+ end
351
+ end
352
+ end
@@ -0,0 +1,343 @@
1
+ module ActiveScaffold
2
+ module Helpers
3
+ # Helpers that assist with the rendering of a Form Column
4
+ module FormColumnHelpers
5
+ # This method decides which input to use for the given column.
6
+ # It does not do any rendering. It only decides which method is responsible for rendering.
7
+ def active_scaffold_input_for(column, scope = nil, options = {})
8
+ options = active_scaffold_input_options(column, scope, options)
9
+ options = update_columns_options(column, scope, options)
10
+ active_scaffold_render_input(column, options)
11
+ end
12
+
13
+ alias form_column active_scaffold_input_for
14
+
15
+ def active_scaffold_render_input(column, options)
16
+ begin
17
+ # first, check if the dev has created an override for this specific field
18
+ if override_form_field?(column)
19
+ send(override_form_field(column), @record, options)
20
+ # second, check if the dev has specified a valid form_ui for this column
21
+ elsif column.form_ui and override_input?(column.form_ui)
22
+ send(override_input(column.form_ui), column, options)
23
+ # fallback: we get to make the decision
24
+ else
25
+ if column.association
26
+ if column.form_ui.nil?
27
+ # its an association and nothing is specified, we will assume form_ui :select
28
+ active_scaffold_input_select(column, options)
29
+ else
30
+ # if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about.
31
+ raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
32
+ end
33
+ elsif column.virtual?
34
+ active_scaffold_input_virtual(column, options)
35
+
36
+ else # regular model attribute column
37
+ # if we (or someone else) have created a custom render option for the column type, use that
38
+ if override_input?(column.column.type)
39
+ send(override_input(column.column.type), column, options)
40
+ # final ultimate fallback: use rails' generic input method
41
+ else
42
+ # for textual fields we pass different options
43
+ text_types = [:text, :string, :integer, :float, :decimal, :date, :time, :datetime]
44
+ options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
45
+ if column.column.type == :string && options[:maxlength].blank?
46
+ options[:maxlength] = column.column.limit
47
+ options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"]
48
+ end
49
+ options[:include_blank] = true if column.column.null and [:date, :datetime, :time].include?(column.column.type)
50
+ options[:value] = format_number_value(@record.send(column.name), column.options) if column.column.number?
51
+ text_field(:record, column.name, options.merge(column.options))
52
+ end
53
+ end
54
+ end
55
+ rescue Exception => e
56
+ logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}"
57
+ raise e
58
+ end
59
+ end
60
+
61
+ # the standard active scaffold options used for textual inputs
62
+ def active_scaffold_input_text_options(options = {})
63
+ options[:autocomplete] = 'off'
64
+ options[:class] = "#{options[:class]} text-input".strip
65
+ options
66
+ end
67
+
68
+ # the standard active scaffold options used for class, name and scope
69
+ def active_scaffold_input_options(column, scope = nil, options = {})
70
+ name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]"
71
+
72
+ # Fix for keeping unique IDs in subform
73
+ id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}"
74
+ id_control += scope.gsub(/(\[|\])/, '_').gsub('__', '_').gsub(/_$/, '') if scope
75
+
76
+ { :name => name, :class => "#{column.name}-input", :id => id_control}.merge(options)
77
+ end
78
+
79
+ def update_columns_options(column, scope, options)
80
+ if column.update_columns
81
+ form_action = params[:action] == 'edit' ? :update : :create
82
+ url_params = {:action => 'render_field', :id => params[:id], :column => column.name, :update_columns => column.update_columns}
83
+ url_params[:eid] = params[:eid] if params[:eid]
84
+ url_params[:controller] = controller.class.active_scaffold_controller_for(@record.class).controller_path if scope
85
+ url_params[:scope] = params[:scope] if scope
86
+
87
+ options[:class] = "#{options[:class]} update_form".strip
88
+ options['data-update_url'] = url_for(url_params)
89
+ end
90
+ options
91
+ end
92
+
93
+ ##
94
+ ## Form input methods
95
+ ##
96
+
97
+ def active_scaffold_input_singular_association(column, html_options)
98
+ associated = @record.send(column.association.name)
99
+
100
+ select_options = options_for_association(column.association)
101
+ select_options.unshift([ associated.to_label, associated.id ]) unless associated.nil? or select_options.find {|label, id| id == associated.id}
102
+
103
+ selected = associated.nil? ? nil : associated.id
104
+ method = column.name
105
+ #html_options[:name] += '[id]'
106
+ options = {:selected => selected, :include_blank => as_(:_select_)}
107
+
108
+ html_options.update(column.options[:html_options] || {})
109
+ options.update(column.options)
110
+ select(:record, method, select_options.uniq, options, html_options)
111
+ end
112
+
113
+ def active_scaffold_input_plural_association(column, options)
114
+ associated_options = @record.send(column.association.name).collect {|r| [r.to_label, r.id]}
115
+ select_options = associated_options | options_for_association(column.association)
116
+ return content_tag(:span, as_(:no_options), :id => options[:id]) if select_options.empty?
117
+
118
+ active_scaffold_checkbox_list(column, select_options, associated_options.collect {|a| a[1]}, options)
119
+ end
120
+
121
+ def active_scaffold_checkbox_list(column, select_options, associated_ids, options)
122
+ html = "<ul class=\"checkbox-list\" id=\"#{options[:id]}\">"
123
+
124
+ select_options.each_with_index do |option, i|
125
+ label, id = option
126
+ this_id = "#{options[:id]}_#{i}_id"
127
+ html << content_tag(:li) do
128
+ check_box_tag("#{options[:name]}[]", id, associated_ids.include?(id), :id => this_id) <<
129
+ content_tag(:label, h(label), :for => this_id)
130
+ end
131
+ end
132
+ html << '</ul>'
133
+ html << javascript_tag("new DraggableLists('#{options[:id]}')") if column.options[:draggable_lists]
134
+ html.html_safe
135
+ end
136
+
137
+ def active_scaffold_translated_option(column, text, value = nil)
138
+ value ||= text
139
+ [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value]
140
+ end
141
+
142
+ def active_scaffold_input_select(column, html_options)
143
+ if column.singular_association?
144
+ active_scaffold_input_singular_association(column, html_options)
145
+ elsif column.plural_association?
146
+ active_scaffold_input_plural_association(column, html_options)
147
+ else
148
+ options = { :selected => @record.send(column.name) }
149
+ options_for_select = column.options[:options].collect do |text, value|
150
+ active_scaffold_translated_option(column, text, value)
151
+ end
152
+ html_options.update(column.options[:html_options] || {})
153
+ options.update(column.options)
154
+ select(:record, column.name, options_for_select, options, html_options)
155
+ end
156
+ end
157
+
158
+ def active_scaffold_input_radio(column, html_options)
159
+ html_options.update(column.options[:html_options] || {})
160
+ column.options[:options].inject('') do |html, (text, value)|
161
+ text, value = active_scaffold_translated_option(column, text, value)
162
+ html << content_tag(:label, radio_button(:record, column.name, value, html_options.merge(:id => html_options[:id] + '-' + value.to_s)) + text)
163
+ end
164
+ end
165
+
166
+ # requires RecordSelect plugin to be installed and configured.
167
+ # ... maybe this should be provided in a bridge?
168
+ def active_scaffold_input_record_select(column, options)
169
+ if column.singular_association?
170
+ active_scaffold_record_select(column, options, @record.send(column.name), false)
171
+ elsif column.plural_association?
172
+ active_scaffold_record_select(column, options, @record.send(column.name), true)
173
+ end
174
+ end
175
+
176
+ def active_scaffold_record_select(column, options, value, multiple)
177
+ unless column.association
178
+ raise ArgumentError, "record_select can only work against associations (and #{column.name} is not). A common mistake is to specify the foreign key field (like :user_id), instead of the association (:user)."
179
+ end
180
+ remote_controller = active_scaffold_controller_for(column.association.klass).controller_path
181
+
182
+ # if the opposite association is a :belongs_to (in that case association in this class must be has_one or has_many)
183
+ # then only show records that have not been associated yet
184
+ if [:has_one, :has_many].include?(column.association.macro)
185
+ params.merge!({column.association.primary_key_name => ''})
186
+ end
187
+
188
+ record_select_options = {:controller => remote_controller, :id => options[:id]}
189
+ record_select_options.merge!(active_scaffold_input_text_options)
190
+ record_select_options.merge!(column.options)
191
+
192
+ if multiple
193
+ record_multi_select_field(options[:name], value || [], record_select_options)
194
+ else
195
+ record_select_field(options[:name], value || column.association.klass.new, record_select_options)
196
+ end
197
+ end
198
+
199
+ def active_scaffold_input_checkbox(column, options)
200
+ check_box(:record, column.name, options)
201
+ end
202
+
203
+ def active_scaffold_input_password(column, options)
204
+ options = active_scaffold_input_text_options(options)
205
+ password_field :record, column.name, options.merge(column.options)
206
+ end
207
+
208
+ def active_scaffold_input_textarea(column, options)
209
+ text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size]))
210
+ end
211
+
212
+ def active_scaffold_input_virtual(column, options)
213
+ options = active_scaffold_input_text_options(options)
214
+ text_field :record, column.name, options.merge(column.options)
215
+ end
216
+
217
+ #
218
+ # Column.type-based inputs
219
+ #
220
+
221
+ def active_scaffold_input_boolean(column, options)
222
+ select_options = []
223
+ select_options << [as_(:_select_), nil] if !column.virtual? && column.column.null
224
+ select_options << [as_(:true), true]
225
+ select_options << [as_(:false), false]
226
+
227
+ select_tag(options[:name], options_for_select(select_options, @record.send(column.name)), options)
228
+ end
229
+
230
+ def onsubmit
231
+ end
232
+
233
+ ##
234
+ ## Form column override signatures
235
+ ##
236
+
237
+ # add functionality for overriding subform partials from association class path
238
+ def override_subform_partial?(column, subform_partial)
239
+ path, partial_name = partial_pieces(override_subform_partial(column, subform_partial))
240
+ template_exists?(partial_name, path, true)
241
+ end
242
+
243
+ def override_subform_partial(column, subform_partial)
244
+ File.join(active_scaffold_controller_for(column.association.klass).controller_path, subform_partial) if column_renders_as(column) == :subform
245
+ end
246
+
247
+ def override_form_field_partial?(column)
248
+ path, partial_name = partial_pieces(override_form_field_partial(column))
249
+ template_exists?(partial_name, path, true)
250
+ end
251
+
252
+ # the naming convention for overriding form fields with partials
253
+ def override_form_field_partial(column)
254
+ "#{column.name}_form_column"
255
+ end
256
+
257
+ def override_form_field?(column)
258
+ respond_to?(override_form_field(column))
259
+ end
260
+
261
+ # the naming convention for overriding form fields with helpers
262
+ def override_form_field(column)
263
+ "#{column.name}_form_column"
264
+ end
265
+
266
+ def override_input?(form_ui)
267
+ respond_to?(override_input(form_ui))
268
+ end
269
+
270
+ # the naming convention for overriding form input types with helpers
271
+ def override_input(form_ui)
272
+ "active_scaffold_input_#{form_ui}"
273
+ end
274
+
275
+ def form_partial_for_column(column, renders_as = nil)
276
+ renders_as ||= column_renders_as(column)
277
+ if override_form_field_partial?(column)
278
+ override_form_field_partial(column)
279
+ elsif renders_as == :field or override_form_field?(column)
280
+ "form_attribute"
281
+ elsif renders_as == :subform
282
+ "form_association"
283
+ elsif renders_as == :hidden
284
+ "form_hidden_attribute"
285
+ end
286
+ end
287
+
288
+ def subform_partial_for_column(column)
289
+ subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
290
+ if override_subform_partial?(column, subform_partial)
291
+ override_subform_partial(column, subform_partial)
292
+ else
293
+ subform_partial
294
+ end
295
+ end
296
+
297
+ ##
298
+ ## Macro-level rendering decisions for columns
299
+ ##
300
+
301
+ def column_renders_as(column)
302
+ if column.is_a? ActiveScaffold::DataStructures::ActionColumns
303
+ return :subsection
304
+ elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden
305
+ return :hidden
306
+ elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform)
307
+ return :field
308
+ else
309
+ return :subform
310
+ end
311
+ end
312
+
313
+ def column_scope(column)
314
+ if column.plural_association?
315
+ "[#{column.name}][#{@record.id || generate_temporary_id}]"
316
+ else
317
+ "[#{column.name}]"
318
+ end
319
+ end
320
+
321
+ def active_scaffold_add_existing_input(options)
322
+ if ActiveScaffold.js_framework == :prototype && controller.respond_to?(:record_select_config)
323
+ remote_controller = active_scaffold_controller_for(record_select_config.model).controller_path
324
+ options.merge!(:controller => remote_controller)
325
+ options.merge!(active_scaffold_input_text_options)
326
+ record_select_field(options[:name], @record, options)
327
+ else
328
+ select_options = options_for_select(options_for_association(nested.association)) #unless column.through_association?
329
+ select_options ||= options_for_select(active_scaffold_config.model.all.collect {|c| [h(c.to_label), c.id]})
330
+ select_tag 'associated_id', ('<option value="">' + as_(:_select_) + '</option>' + select_options).html_safe unless select_options.empty?
331
+ end
332
+ end
333
+
334
+ def active_scaffold_add_existing_label
335
+ if controller.respond_to?(:record_select_config)
336
+ record_select_config.model.model_name.human
337
+ else
338
+ active_scaffold_config.model.model_name.human
339
+ end
340
+ end
341
+ end
342
+ end
343
+ end