admin_assistant 1.0.0 → 1.0.1

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 (377) hide show
  1. data/.gitignore +16 -0
  2. data/Rakefile +34 -6
  3. data/VERSION +1 -0
  4. data/admin_assistant.gemspec +440 -0
  5. data/doc/img/blog_posts-index.png +0 -0
  6. data/install.rb +25 -4
  7. data/lib/admin_assistant/active_record_column.rb +133 -45
  8. data/lib/admin_assistant/association_target.rb +16 -3
  9. data/lib/admin_assistant/belongs_to_column.rb +18 -10
  10. data/lib/admin_assistant/builder.rb +67 -30
  11. data/lib/admin_assistant/column.rb +153 -71
  12. data/lib/admin_assistant/date_time_range_end_point_selector.rb +340 -0
  13. data/lib/admin_assistant/default_search_column.rb +3 -7
  14. data/lib/admin_assistant/form_view.rb +114 -10
  15. data/lib/admin_assistant/has_many_column.rb +56 -0
  16. data/lib/admin_assistant/index.rb +220 -83
  17. data/lib/admin_assistant/polymorphic_belongs_to_column.rb +1 -1
  18. data/lib/admin_assistant/request/base.rb +196 -67
  19. data/lib/admin_assistant/request/create.rb +55 -7
  20. data/lib/admin_assistant/request/edit.rb +1 -2
  21. data/lib/admin_assistant/request/index.rb +16 -9
  22. data/lib/admin_assistant/request/new.rb +19 -7
  23. data/lib/admin_assistant/request/update.rb +28 -13
  24. data/lib/admin_assistant/search.rb +17 -2
  25. data/lib/admin_assistant/virtual_column.rb +15 -7
  26. data/lib/admin_assistant.rb +101 -81
  27. data/lib/javascripts/admin_assistant.js +1 -1
  28. data/lib/stylesheets/activescaffold.css +6 -1
  29. data/lib/stylesheets/default.css +17 -0
  30. data/lib/views/form.html.erb +7 -3
  31. data/lib/views/index.html.erb +13 -8
  32. data/lib/views/multi_form.html.erb +71 -0
  33. data/lib/views/show.html.erb +4 -4
  34. data/test_rails_app/README +256 -0
  35. data/test_rails_app/Rakefile +13 -0
  36. data/test_rails_app/app/controllers/admin/appointments2_controller.rb +15 -0
  37. data/test_rails_app/app/controllers/admin/appointments_controller.rb +11 -0
  38. data/test_rails_app/app/controllers/admin/blog_posts2_controller.rb +138 -0
  39. data/test_rails_app/app/controllers/admin/blog_posts3_controller.rb +76 -0
  40. data/test_rails_app/app/controllers/admin/blog_posts4_controller.rb +21 -0
  41. data/test_rails_app/app/controllers/admin/blog_posts5_controller.rb +27 -0
  42. data/test_rails_app/app/controllers/admin/blog_posts6_controller.rb +10 -0
  43. data/test_rails_app/app/controllers/admin/blog_posts_controller.rb +8 -0
  44. data/test_rails_app/app/controllers/admin/blog_posts_custom_new_and_edit_controller.rb +15 -0
  45. data/test_rails_app/app/controllers/admin/blog_posts_read_only_controller.rb +19 -0
  46. data/test_rails_app/app/controllers/admin/bookmarks_controller.rb +11 -0
  47. data/test_rails_app/app/controllers/admin/comments2_controller.rb +14 -0
  48. data/test_rails_app/app/controllers/admin/comments_controller.rb +12 -0
  49. data/test_rails_app/app/controllers/admin/file_column_images2_controller.rb +10 -0
  50. data/test_rails_app/app/controllers/admin/file_column_images_controller.rb +6 -0
  51. data/test_rails_app/app/controllers/admin/images2_controller.rb +11 -0
  52. data/test_rails_app/app/controllers/admin/images_controller.rb +6 -0
  53. data/test_rails_app/app/controllers/admin/misconfigured1_controller.rb +7 -0
  54. data/test_rails_app/app/controllers/admin/not_migrated_yets_controller.rb +9 -0
  55. data/test_rails_app/app/controllers/admin/product_categories2_controller.rb +7 -0
  56. data/test_rails_app/app/controllers/admin/product_categories_controller.rb +5 -0
  57. data/test_rails_app/app/controllers/admin/products2_controller.rb +15 -0
  58. data/test_rails_app/app/controllers/admin/products_controller.rb +31 -0
  59. data/test_rails_app/app/controllers/admin/television_airings_controller.rb +5 -0
  60. data/test_rails_app/app/controllers/admin/television_time_slots_controller.rb +5 -0
  61. data/test_rails_app/app/controllers/admin/users2_controller.rb +10 -0
  62. data/test_rails_app/app/controllers/admin/users_controller.rb +63 -0
  63. data/test_rails_app/app/controllers/application.rb +16 -0
  64. data/test_rails_app/app/controllers/application_controller.rb +16 -0
  65. data/test_rails_app/app/controllers/blog_posts_controller.rb +5 -0
  66. data/test_rails_app/app/helpers/admin/appointments2_helper.rb +2 -0
  67. data/test_rails_app/app/helpers/admin/appointments_helper.rb +2 -0
  68. data/test_rails_app/app/helpers/admin/blog_posts2_helper.rb +27 -0
  69. data/test_rails_app/app/helpers/admin/blog_posts3_helper.rb +2 -0
  70. data/test_rails_app/app/helpers/admin/blog_posts4_helper.rb +2 -0
  71. data/test_rails_app/app/helpers/admin/blog_posts6_helper.rb +16 -0
  72. data/test_rails_app/app/helpers/admin/blog_posts_custom_new_and_edit_helper.rb +29 -0
  73. data/test_rails_app/app/helpers/admin/blog_posts_helper.rb +2 -0
  74. data/test_rails_app/app/helpers/admin/blog_posts_read_only_helper.rb +2 -0
  75. data/test_rails_app/app/helpers/admin/bookmarks_helper.rb +2 -0
  76. data/test_rails_app/app/helpers/admin/comments2_helper.rb +2 -0
  77. data/test_rails_app/app/helpers/admin/comments_helper.rb +2 -0
  78. data/test_rails_app/app/helpers/admin/file_column_images2_helper.rb +2 -0
  79. data/test_rails_app/app/helpers/admin/file_column_images_helper.rb +2 -0
  80. data/test_rails_app/app/helpers/admin/images2_helper.rb +8 -0
  81. data/test_rails_app/app/helpers/admin/images_helper.rb +2 -0
  82. data/test_rails_app/app/helpers/admin/misconfigured1_helper.rb +2 -0
  83. data/test_rails_app/app/helpers/admin/not_migrated_yets_helper.rb +2 -0
  84. data/test_rails_app/app/helpers/admin/product_categories2_helper.rb +2 -0
  85. data/test_rails_app/app/helpers/admin/product_categories_helper.rb +2 -0
  86. data/test_rails_app/app/helpers/admin/products2_helper.rb +3 -0
  87. data/test_rails_app/app/helpers/admin/products_helper.rb +6 -0
  88. data/test_rails_app/app/helpers/admin/television_airings_helper.rb +2 -0
  89. data/test_rails_app/app/helpers/admin/television_time_slots_helper.rb +2 -0
  90. data/test_rails_app/app/helpers/admin/users2_helper.rb +2 -0
  91. data/test_rails_app/app/helpers/admin/users_helper.rb +25 -0
  92. data/test_rails_app/app/helpers/application_helper.rb +3 -0
  93. data/test_rails_app/app/helpers/blog_posts_helper.rb +2 -0
  94. data/test_rails_app/app/models/appointment.rb +5 -0
  95. data/test_rails_app/app/models/blog_post.rb +14 -0
  96. data/test_rails_app/app/models/blog_post_tag.rb +6 -0
  97. data/test_rails_app/app/models/bookmark.rb +6 -0
  98. data/test_rails_app/app/models/comment.rb +4 -0
  99. data/test_rails_app/app/models/file_column_image.rb +3 -0
  100. data/test_rails_app/app/models/image.rb +3 -0
  101. data/test_rails_app/app/models/not_migrated_yet.rb +2 -0
  102. data/test_rails_app/app/models/product.rb +7 -0
  103. data/test_rails_app/app/models/product_category.rb +9 -0
  104. data/test_rails_app/app/models/tag.rb +4 -0
  105. data/test_rails_app/app/models/television_airing.rb +3 -0
  106. data/test_rails_app/app/models/television_time_slot.rb +11 -0
  107. data/test_rails_app/app/models/user.rb +14 -0
  108. data/test_rails_app/app/views/admin/appointments/_subject_input.html.erb +2 -0
  109. data/test_rails_app/app/views/admin/appointments2/_time_input.html.erb +31 -0
  110. data/test_rails_app/app/views/admin/blog_posts2/_after_form.html.erb +5 -0
  111. data/test_rails_app/app/views/admin/blog_posts2/_after_index.html.erb +1 -0
  112. data/test_rails_app/app/views/admin/blog_posts2/_after_tags_input.html.erb +16 -0
  113. data/test_rails_app/app/views/admin/blog_posts2/_before_index.html.erb +2 -0
  114. data/test_rails_app/app/views/admin/blog_posts5/_after_index_header.html.erb +8 -0
  115. data/test_rails_app/app/views/admin/blog_posts_read_only/_body_for_show.html.erb +1 -0
  116. data/test_rails_app/app/views/admin/products/_name_input.html.erb +2 -0
  117. data/test_rails_app/app/views/admin/products/_percent_off_input.html.erb +2 -0
  118. data/test_rails_app/app/views/admin/products/_price_input.html.erb +10 -0
  119. data/test_rails_app/app/views/blog_posts/show.html.erb +13 -0
  120. data/test_rails_app/app/views/layouts/admin.html.erb +31 -0
  121. data/test_rails_app/config/boot.rb +109 -0
  122. data/test_rails_app/config/database.yml +28 -0
  123. data/test_rails_app/config/environment.rb +78 -0
  124. data/test_rails_app/config/environments/development.rb +17 -0
  125. data/test_rails_app/config/environments/production.rb +24 -0
  126. data/test_rails_app/config/environments/test.rb +24 -0
  127. data/test_rails_app/config/initializers/inflections.rb +10 -0
  128. data/test_rails_app/config/initializers/mime_types.rb +5 -0
  129. data/test_rails_app/config/initializers/new_rails_defaults.rb +17 -0
  130. data/test_rails_app/config/locales/en.yml +5 -0
  131. data/test_rails_app/config/routes.rb +43 -0
  132. data/test_rails_app/db/migrate/20090213215514_create_blog_posts.rb +12 -0
  133. data/test_rails_app/db/migrate/20090217225542_add_body_to_blog_posts.rb +9 -0
  134. data/test_rails_app/db/migrate/20090221220917_create_tags.rb +13 -0
  135. data/test_rails_app/db/migrate/20090221220947_create_blog_post_tags.rb +14 -0
  136. data/test_rails_app/db/migrate/20090222162204_add_textile_to_blog_posts.rb +9 -0
  137. data/test_rails_app/db/migrate/20090222163231_add_published_at_to_blog_posts.rb +9 -0
  138. data/test_rails_app/db/migrate/20090301191722_create_images.rb +16 -0
  139. data/test_rails_app/db/migrate/20090305165345_create_accounts.rb +14 -0
  140. data/test_rails_app/db/migrate/20090307225027_rename_accounts_to_users.rb +9 -0
  141. data/test_rails_app/db/migrate/20090307225750_add_user_id_to_blog_posts.rb +9 -0
  142. data/test_rails_app/db/migrate/20090309185114_change_blog_posts_textile.rb +9 -0
  143. data/test_rails_app/db/migrate/20090309193635_create_products.rb +14 -0
  144. data/test_rails_app/db/migrate/20090309203056_create_comments.rb +15 -0
  145. data/test_rails_app/db/migrate/20090323005947_create_file_column_images.rb +12 -0
  146. data/test_rails_app/db/migrate/20090326160049_add_birthday_to_users.rb +9 -0
  147. data/test_rails_app/db/migrate/20090326223606_add_state_to_users.rb +9 -0
  148. data/test_rails_app/db/migrate/20090503134004_add_file_column_image_to_products.rb +9 -0
  149. data/test_rails_app/db/migrate/20090617173651_create_bookmarks.rb +15 -0
  150. data/test_rails_app/db/migrate/20090624165355_add_tags_string_to_blog_post.rb +9 -0
  151. data/test_rails_app/db/migrate/20090625144313_add_avatar_fields_to_user.rb +11 -0
  152. data/test_rails_app/db/migrate/20090629202956_add_merged_into_to_blog_posts.rb +9 -0
  153. data/test_rails_app/db/migrate/20090701171857_add_force_textile_to_users.rb +9 -0
  154. data/test_rails_app/db/migrate/20090704163647_add_deleted_at_to_products.rb +9 -0
  155. data/test_rails_app/db/migrate/20090704173800_add_sale_fields_to_products.rb +13 -0
  156. data/test_rails_app/db/migrate/20090714024501_create_product_categories.rb +15 -0
  157. data/test_rails_app/db/migrate/20090819162835_add_admin_level_to_users.rb +9 -0
  158. data/test_rails_app/db/migrate/20091115134559_add_first_and_last_names_to_users.rb +11 -0
  159. data/test_rails_app/db/migrate/20091221011256_add_position_to_product_categories.rb +9 -0
  160. data/test_rails_app/db/migrate/20091222160814_create_appointments.rb +14 -0
  161. data/test_rails_app/db/migrate/20091227224547_add_user_id_to_appointments.rb +9 -0
  162. data/test_rails_app/db/migrate/20100214213359_create_television_time_slots.rb +13 -0
  163. data/test_rails_app/db/migrate/20100214213451_create_television_airings.rb +15 -0
  164. data/test_rails_app/doc/README_FOR_APP +5 -0
  165. data/test_rails_app/lib/tasks/rspec.rake +163 -0
  166. data/test_rails_app/public/404.html +30 -0
  167. data/test_rails_app/public/422.html +30 -0
  168. data/test_rails_app/public/500.html +33 -0
  169. data/test_rails_app/public/dispatch.cgi +10 -0
  170. data/test_rails_app/public/dispatch.fcgi +24 -0
  171. data/test_rails_app/public/dispatch.rb +10 -0
  172. data/test_rails_app/public/favicon.ico +0 -0
  173. data/test_rails_app/public/images/rails.png +0 -0
  174. data/test_rails_app/public/index.html +274 -0
  175. data/test_rails_app/public/javascripts/application.js +2 -0
  176. data/test_rails_app/public/javascripts/controls.js +963 -0
  177. data/test_rails_app/public/javascripts/dragdrop.js +973 -0
  178. data/test_rails_app/public/javascripts/effects.js +1128 -0
  179. data/test_rails_app/public/javascripts/prototype.js +4320 -0
  180. data/test_rails_app/public/robots.txt +5 -0
  181. data/test_rails_app/public/stylesheets/admin.css +3 -0
  182. data/test_rails_app/public/stylesheets/scaffold.css +54 -0
  183. data/test_rails_app/script/about +4 -0
  184. data/test_rails_app/script/autospec +5 -0
  185. data/test_rails_app/script/console +3 -0
  186. data/test_rails_app/script/dbconsole +3 -0
  187. data/test_rails_app/script/destroy +3 -0
  188. data/test_rails_app/script/generate +3 -0
  189. data/test_rails_app/script/performance/benchmarker +3 -0
  190. data/test_rails_app/script/performance/profiler +3 -0
  191. data/test_rails_app/script/performance/request +3 -0
  192. data/test_rails_app/script/plugin +3 -0
  193. data/test_rails_app/script/populate_tables.rb +49 -0
  194. data/test_rails_app/script/process/inspector +3 -0
  195. data/test_rails_app/script/process/reaper +3 -0
  196. data/test_rails_app/script/process/spawner +3 -0
  197. data/test_rails_app/script/runner +3 -0
  198. data/test_rails_app/script/server +3 -0
  199. data/test_rails_app/script/spec +5 -0
  200. data/test_rails_app/script/spec_server +125 -0
  201. data/test_rails_app/spec/controllers/admin/appointments2_controller_spec.rb +88 -0
  202. data/test_rails_app/spec/controllers/admin/appointments_controller_spec.rb +419 -0
  203. data/test_rails_app/spec/controllers/admin/blog_posts2_controller_spec.rb +1021 -0
  204. data/test_rails_app/spec/controllers/admin/blog_posts3_controller_spec.rb +532 -0
  205. data/test_rails_app/spec/controllers/admin/blog_posts4_controller_spec.rb +231 -0
  206. data/test_rails_app/spec/controllers/admin/blog_posts5_controller_spec.rb +77 -0
  207. data/test_rails_app/spec/controllers/admin/blog_posts6_controller_spec.rb +49 -0
  208. data/test_rails_app/spec/controllers/admin/blog_posts_controller_spec.rb +987 -0
  209. data/test_rails_app/spec/controllers/admin/blog_posts_custom_new_and_edit_controller_spec.rb +99 -0
  210. data/test_rails_app/spec/controllers/admin/blog_posts_read_only_controller_spec.rb +94 -0
  211. data/test_rails_app/spec/controllers/admin/bookmarks_controller_spec.rb +505 -0
  212. data/test_rails_app/spec/controllers/admin/comments2_controller_spec.rb +70 -0
  213. data/test_rails_app/spec/controllers/admin/comments_controller_spec.rb +82 -0
  214. data/test_rails_app/spec/controllers/admin/file_column_images2_controller_spec.rb +25 -0
  215. data/test_rails_app/spec/controllers/admin/file_column_images_controller_spec.rb +82 -0
  216. data/test_rails_app/spec/controllers/admin/images2_controller_spec.rb +44 -0
  217. data/test_rails_app/spec/controllers/admin/images_controller_spec.rb +97 -0
  218. data/test_rails_app/spec/controllers/admin/misconfigured1_controller_spec.rb +21 -0
  219. data/test_rails_app/spec/controllers/admin/not_migrated_yets_controller_spec.rb +10 -0
  220. data/test_rails_app/spec/controllers/admin/product_categories2_controller_spec.rb +215 -0
  221. data/test_rails_app/spec/controllers/admin/product_categories_controller_spec.rb +19 -0
  222. data/test_rails_app/spec/controllers/admin/products2_controller_spec.rb +203 -0
  223. data/test_rails_app/spec/controllers/admin/products_controller_spec.rb +255 -0
  224. data/test_rails_app/spec/controllers/admin/television_airings_controller_spec.rb +32 -0
  225. data/test_rails_app/spec/controllers/admin/television_time_slots_controller_spec.rb +10 -0
  226. data/test_rails_app/spec/controllers/admin/users2_controller_spec.rb +65 -0
  227. data/test_rails_app/spec/controllers/admin/users_controller_spec.rb +344 -0
  228. data/test_rails_app/spec/controllers/blog_posts_controller_spec.rb +13 -0
  229. data/test_rails_app/spec/data/ruby_throated.jpg +0 -0
  230. data/test_rails_app/spec/data/tweenbot.jpg +0 -0
  231. data/test_rails_app/spec/fixtures/appointments.yml +9 -0
  232. data/test_rails_app/spec/fixtures/blog_post_tags.yml +9 -0
  233. data/test_rails_app/spec/fixtures/blog_posts.yml +7 -0
  234. data/test_rails_app/spec/fixtures/bookmarks.yml +11 -0
  235. data/test_rails_app/spec/fixtures/comments.yml +11 -0
  236. data/test_rails_app/spec/fixtures/file_column_images.yml +7 -0
  237. data/test_rails_app/spec/fixtures/images.yml +7 -0
  238. data/test_rails_app/spec/fixtures/not_migrated_yets.yml +7 -0
  239. data/test_rails_app/spec/fixtures/product_categories.yml +7 -0
  240. data/test_rails_app/spec/fixtures/products.yml +9 -0
  241. data/test_rails_app/spec/fixtures/tags.yml +7 -0
  242. data/test_rails_app/spec/fixtures/television_airings.yml +11 -0
  243. data/test_rails_app/spec/fixtures/television_time_slots.yml +7 -0
  244. data/test_rails_app/spec/fixtures/users.yml +9 -0
  245. data/test_rails_app/spec/helpers/admin/appointments2_helper_spec.rb +11 -0
  246. data/test_rails_app/spec/helpers/admin/appointments_helper_spec.rb +11 -0
  247. data/test_rails_app/spec/helpers/admin/blog_posts2_helper_spec.rb +11 -0
  248. data/test_rails_app/spec/helpers/admin/blog_posts3_helper_spec.rb +11 -0
  249. data/test_rails_app/spec/helpers/admin/blog_posts4_helper_spec.rb +11 -0
  250. data/test_rails_app/spec/helpers/admin/blog_posts_custom_new_and_edit_helper_spec.rb +11 -0
  251. data/test_rails_app/spec/helpers/admin/blog_posts_helper_spec.rb +11 -0
  252. data/test_rails_app/spec/helpers/admin/blog_posts_read_only_helper_spec.rb +11 -0
  253. data/test_rails_app/spec/helpers/admin/bookmarks_helper_spec.rb +11 -0
  254. data/test_rails_app/spec/helpers/admin/comments2_helper_spec.rb +11 -0
  255. data/test_rails_app/spec/helpers/admin/comments_helper_spec.rb +11 -0
  256. data/test_rails_app/spec/helpers/admin/file_column_images2_helper_spec.rb +11 -0
  257. data/test_rails_app/spec/helpers/admin/file_column_images_helper_spec.rb +11 -0
  258. data/test_rails_app/spec/helpers/admin/images2_helper_spec.rb +11 -0
  259. data/test_rails_app/spec/helpers/admin/images_helper_spec.rb +11 -0
  260. data/test_rails_app/spec/helpers/admin/misconfigured1_helper_spec.rb +11 -0
  261. data/test_rails_app/spec/helpers/admin/not_migrated_yets_helper_spec.rb +11 -0
  262. data/test_rails_app/spec/helpers/admin/product_categories2_helper_spec.rb +11 -0
  263. data/test_rails_app/spec/helpers/admin/product_categories_helper_spec.rb +11 -0
  264. data/test_rails_app/spec/helpers/admin/products2_helper_spec.rb +11 -0
  265. data/test_rails_app/spec/helpers/admin/products_helper_spec.rb +11 -0
  266. data/test_rails_app/spec/helpers/admin/television_airings_helper_spec.rb +11 -0
  267. data/test_rails_app/spec/helpers/admin/television_time_slots_helper_spec.rb +11 -0
  268. data/test_rails_app/spec/helpers/admin/users2_helper_spec.rb +11 -0
  269. data/test_rails_app/spec/helpers/admin/users_helper_spec.rb +11 -0
  270. data/test_rails_app/spec/helpers/blog_posts_helper_spec.rb +11 -0
  271. data/test_rails_app/spec/models/appointment_spec.rb +16 -0
  272. data/test_rails_app/spec/models/blog_post_spec.rb +13 -0
  273. data/test_rails_app/spec/models/blog_post_tag_spec.rb +14 -0
  274. data/test_rails_app/spec/models/bookmark_spec.rb +15 -0
  275. data/test_rails_app/spec/models/comment_spec.rb +15 -0
  276. data/test_rails_app/spec/models/file_column_image_spec.rb +12 -0
  277. data/test_rails_app/spec/models/image_spec.rb +12 -0
  278. data/test_rails_app/spec/models/not_migrated_yet_spec.rb +15 -0
  279. data/test_rails_app/spec/models/product_category_spec.rb +15 -0
  280. data/test_rails_app/spec/models/product_spec.rb +14 -0
  281. data/test_rails_app/spec/models/tag_spec.rb +13 -0
  282. data/test_rails_app/spec/models/television_airing_spec.rb +15 -0
  283. data/test_rails_app/spec/models/television_time_slot_spec.rb +13 -0
  284. data/test_rails_app/spec/models/user_spec.rb +14 -0
  285. data/test_rails_app/spec/rcov.opts +2 -0
  286. data/test_rails_app/spec/spec.opts +4 -0
  287. data/test_rails_app/spec/spec_helper.rb +88 -0
  288. data/test_rails_app/spec/spec_or_test_helper.rb +49 -0
  289. data/test_rails_app/test/fixtures/file_column_images.yml +7 -0
  290. data/test_rails_app/test/integration/admin_blog_posts2_integration_test.rb +16 -0
  291. data/test_rails_app/test/integration/admin_blog_posts5_integration_test.rb +19 -0
  292. data/test_rails_app/test/integration/admin_blog_posts_integration_test.rb +25 -0
  293. data/test_rails_app/test/test_helper.rb +28 -0
  294. data/test_rails_app/vendor/plugins/file_column/CHANGELOG +69 -0
  295. data/test_rails_app/vendor/plugins/file_column/README +54 -0
  296. data/test_rails_app/vendor/plugins/file_column/Rakefile +36 -0
  297. data/test_rails_app/vendor/plugins/file_column/TODO +6 -0
  298. data/test_rails_app/vendor/plugins/file_column/init.rb +13 -0
  299. data/test_rails_app/vendor/plugins/file_column/lib/file_column.rb +723 -0
  300. data/test_rails_app/vendor/plugins/file_column/lib/file_column_helper.rb +150 -0
  301. data/test_rails_app/vendor/plugins/file_column/lib/file_compat.rb +28 -0
  302. data/test_rails_app/vendor/plugins/file_column/lib/magick_file_column.rb +260 -0
  303. data/test_rails_app/vendor/plugins/file_column/lib/rails_file_column.rb +19 -0
  304. data/test_rails_app/vendor/plugins/file_column/lib/test_case.rb +124 -0
  305. data/test_rails_app/vendor/plugins/file_column/lib/validations.rb +112 -0
  306. data/test_rails_app/vendor/plugins/file_column/test/abstract_unit.rb +63 -0
  307. data/test_rails_app/vendor/plugins/file_column/test/connection.rb +17 -0
  308. data/test_rails_app/vendor/plugins/file_column/test/file_column_helper_test.rb +97 -0
  309. data/test_rails_app/vendor/plugins/file_column/test/file_column_test.rb +650 -0
  310. data/test_rails_app/vendor/plugins/file_column/test/fixtures/entry.rb +32 -0
  311. data/test_rails_app/vendor/plugins/file_column/test/fixtures/invalid-image.jpg +1 -0
  312. data/test_rails_app/vendor/plugins/file_column/test/fixtures/kerb.jpg +0 -0
  313. data/test_rails_app/vendor/plugins/file_column/test/fixtures/mysql.sql +25 -0
  314. data/test_rails_app/vendor/plugins/file_column/test/fixtures/schema.rb +10 -0
  315. data/test_rails_app/vendor/plugins/file_column/test/fixtures/skanthak.png +0 -0
  316. data/test_rails_app/vendor/plugins/file_column/test/magick_test.rb +380 -0
  317. data/test_rails_app/vendor/plugins/file_column/test/magick_view_only_test.rb +21 -0
  318. data/vendor/ar_query/ar_query.gemspec +16 -0
  319. data/website/_layouts/api.html +39 -0
  320. data/website/_layouts/default.html +34 -0
  321. data/website/api/core.markdown +106 -0
  322. data/website/api/destroy.markdown +25 -0
  323. data/website/api/form.markdown +291 -0
  324. data/website/api/idx.markdown +286 -0
  325. data/website/api/index.markdown +147 -0
  326. data/website/api/search.markdown +108 -0
  327. data/website/api/show.markdown +22 -0
  328. data/website/community.markdown +27 -0
  329. data/website/css/lightbox.css +29 -0
  330. data/website/css/main.css +70 -0
  331. data/website/design_principles.markdown +50 -0
  332. data/website/getting_started.markdown +10 -0
  333. data/website/img/blog_posts-index.png +0 -0
  334. data/website/img/blog_posts-search.png +0 -0
  335. data/website/img/lightbox/bullet.gif +0 -0
  336. data/website/img/lightbox/close.gif +0 -0
  337. data/website/img/lightbox/closelabel.gif +0 -0
  338. data/website/img/lightbox/donate-button.gif +0 -0
  339. data/website/img/lightbox/download-icon.gif +0 -0
  340. data/website/img/lightbox/image-1.jpg +0 -0
  341. data/website/img/lightbox/loading.gif +0 -0
  342. data/website/img/lightbox/nextlabel.gif +0 -0
  343. data/website/img/lightbox/prevlabel.gif +0 -0
  344. data/website/img/lightbox/thumb-1.jpg +0 -0
  345. data/website/img/screen1-thumb.png +0 -0
  346. data/website/img/screen1.png +0 -0
  347. data/website/img/screen10-thumb.png +0 -0
  348. data/website/img/screen10.png +0 -0
  349. data/website/img/screen11-thumb.png +0 -0
  350. data/website/img/screen11.png +0 -0
  351. data/website/img/screen2-thumb.png +0 -0
  352. data/website/img/screen2.png +0 -0
  353. data/website/img/screen3-thumb.png +0 -0
  354. data/website/img/screen3.png +0 -0
  355. data/website/img/screen4-thumb.png +0 -0
  356. data/website/img/screen4.png +0 -0
  357. data/website/img/screen5-thumb.png +0 -0
  358. data/website/img/screen5.png +0 -0
  359. data/website/img/screen6-thumb.png +0 -0
  360. data/website/img/screen6.png +0 -0
  361. data/website/img/screen7-thumb.png +0 -0
  362. data/website/img/screen7.png +0 -0
  363. data/website/img/screen8-thumb.png +0 -0
  364. data/website/img/screen8.png +0 -0
  365. data/website/img/screen9-thumb.png +0 -0
  366. data/website/img/screen9.png +0 -0
  367. data/website/img/user-form.png +0 -0
  368. data/website/index.markdown +35 -0
  369. data/website/js/builder.js +136 -0
  370. data/website/js/effects.js +1122 -0
  371. data/website/js/lightbox.js +497 -0
  372. data/website/js/prototype.js +4221 -0
  373. data/website/js/scriptaculous.js +58 -0
  374. data/website/quick_start.markdown +44 -0
  375. data/website/screenshots.markdown +27 -0
  376. data/website/tutorial.markdown +56 -0
  377. metadata +391 -23
@@ -1,13 +1,5 @@
1
1
  class AdminAssistant
2
- class Column
3
- def blank?(search)
4
- search.params["#{name}(blank)"] == '1'
5
- end
6
-
7
- def comparator(search)
8
- search.params["#{name}(comparator)"]
9
- end
10
-
2
+ class Column
11
3
  def form_view(action_view, admin_assistant, opts = {})
12
4
  view 'FormView', action_view, admin_assistant, opts
13
5
  end
@@ -38,10 +30,6 @@ class AdminAssistant
38
30
  end
39
31
 
40
32
  module FormViewMethods
41
- def description
42
- @description
43
- end
44
-
45
33
  def after_html(rails_form)
46
34
  after = render_from_custom_template("_after_#{name}_input", rails_form)
47
35
  if after
@@ -53,9 +41,13 @@ class AdminAssistant
53
41
  end
54
42
  end
55
43
  end
56
-
57
- def controller
58
- @action_view.controller
44
+
45
+ def description
46
+ @description
47
+ end
48
+
49
+ def errors(record)
50
+ record.errors.on name
59
51
  end
60
52
 
61
53
  def html(rails_form)
@@ -82,50 +74,41 @@ class AdminAssistant
82
74
  end
83
75
  end
84
76
 
77
+ def field_id
78
+ "#{@model_class.name.underscore}_#{name}"
79
+ end
80
+
85
81
  def render_from_custom_template(slug, rails_form)
86
- abs_template_file = File.join(
87
- RAILS_ROOT, 'app/views', controller.controller_path,
88
- "#{slug}.html.erb"
89
- )
90
- if File.exist?(abs_template_file)
91
- template = if RAILS_GEM_VERSION == '2.1.0'
92
- File.join(controller.controller_path, "#{slug}.html.erb")
93
- else
94
- abs_template_file
95
- end
82
+ if File.exist?(custom_template_file_path(slug))
96
83
  varname = @model_class.name.underscore
97
84
  @action_view.instance_variable_set(
98
85
  "@#{varname}".to_sym, rails_form.object
99
86
  )
87
+ locals = {varname.to_sym => rails_form.object, :form => rails_form}
88
+ if rails_form.respond_to?(:prefix)
89
+ locals[:prefix] = rails_form.prefix
90
+ @action_view.instance_variable_set(:@prefix, rails_form.prefix)
91
+ end
100
92
  @action_view.render(
101
- :file => template,
102
- :locals => {
103
- varname.to_sym => rails_form.object,
104
- :form => rails_form
105
- }
93
+ :file => file_option_for_custom_template_render(slug),
94
+ :locals => locals
106
95
  )
107
96
  end
108
97
  end
109
98
 
110
99
  def set_instance_variables_from_options(admin_assistant, opts)
111
100
  setting = admin_assistant.form_settings[name.to_sym]
112
- @clear_link = setting.clear_link
113
- @description = setting.description
114
- @datetime_select_options = setting.datetime_select_options || {}
115
- @date_select_options = setting.date_select_options || {}
116
- fum_name = name + '_url'
117
- if @action_view.respond_to?(fum_name)
118
- @file_url_method = @action_view.method(fum_name)
101
+ ivars = %w(
102
+ clear_link datetime_select_options date_select_options description
103
+ image_size input select_choices select_options text_area_options
104
+ )
105
+ ivars.each do |ivar|
106
+ instance_variable_set "@#{ivar}".to_sym, setting.send(ivar)
119
107
  end
120
- @image_size = setting.image_size
121
- @input = setting.input
122
- @polymorphic_types = admin_assistant[name.to_sym].polymorphic_types
123
- @read_only = setting.read_only?
124
- @select_options = setting.select_options || {}
125
- unless @select_options.has_key?(:include_blank)
126
- @select_options[:include_blank] = true
108
+ if @action_view.respond_to?(name + '_url')
109
+ @file_url_method = @action_view.method(name + '_url')
127
110
  end
128
- @text_area_options = setting.text_area_options || {}
111
+ @read_only = setting.read_only?
129
112
  @write_once = setting.write_once?
130
113
  end
131
114
  end
@@ -134,15 +117,7 @@ class AdminAssistant
134
117
  def header_css_class
135
118
  "sort #{sort_order}" if sort_order
136
119
  end
137
-
138
- def td_css_class
139
- 'sort' if sort_order
140
- end
141
-
142
- def unconfigured_html(record)
143
- @action_view.send(:h, string(record))
144
- end
145
-
120
+
146
121
  def html(record)
147
122
  html_for_index_method = "#{name}_html_for_index"
148
123
  html = if @action_view.respond_to?(html_for_index_method)
@@ -181,7 +156,22 @@ class AdminAssistant
181
156
  @link_to_args = setting.link_to_args
182
157
  @sort_order = index.sort_order if name == index.sort
183
158
  @image_size = setting.image_size
184
- @ajax_toggle_allowed = admin_assistant.update?
159
+ @ajax_toggle_allowed =
160
+ admin_assistant.update? && setting.ajax_toggle != false
161
+ end
162
+
163
+ def td_css_classes(column, record)
164
+ css_classes = []
165
+ css_classes << 'sort' if sort_order
166
+ td_css_class_for_index_method = "#{name}_css_class_for_index_td"
167
+ if @action_view.respond_to?(td_css_class_for_index_method)
168
+ css_classes << @action_view.send(td_css_class_for_index_method, record)
169
+ end
170
+ css_classes.reject{ |c| c.blank? }.join(' ')
171
+ end
172
+
173
+ def unconfigured_html(record)
174
+ @action_view.send(:h, string(record))
185
175
  end
186
176
  end
187
177
 
@@ -193,12 +183,19 @@ class AdminAssistant
193
183
  end
194
184
  @search = opts[:search]
195
185
  @blank_checkbox = setting.blank_checkbox
186
+ @compare_to_range = setting.compare_to_range
196
187
  end
197
188
  end
198
189
 
199
190
  module SimpleColumnSearchViewMethods
200
191
  include SearchViewMethods
201
192
 
193
+ def blank_checkbox_html(form)
194
+ check_box_and_hidden_tags(
195
+ "search[#{name}(blank)]", form.object.blank?(@column.name)
196
+ ) + "is blank"
197
+ end
198
+
202
199
  def boolean_input(form)
203
200
  opts = [['', nil]]
204
201
  if @boolean_labels
@@ -212,7 +209,7 @@ class AdminAssistant
212
209
  end
213
210
 
214
211
  def comparator_html(search)
215
- selected_comparator = @column.comparator(search) || '='
212
+ selected_comparator = search.comparator(@column.name) || '='
216
213
  option_tags = comparator_opts.map { |text, value|
217
214
  opt = "<option value=\"#{value}\""
218
215
  if selected_comparator == value
@@ -233,22 +230,69 @@ class AdminAssistant
233
230
  ]
234
231
  end
235
232
 
233
+ def datetime_input(form)
234
+ input = ''
235
+ if @compare_to_range
236
+ input = datetime_range_input(form)
237
+ else
238
+ input << comparator_html(form.object) << ' ' if @comparators == :all
239
+ input << form.datetime_select(name, :include_blank => true)
240
+ input << @action_view.send(
241
+ :link_to_function, 'Clear',
242
+ "AdminAssistant.clear_datetime_select('search_#{name.underscore}')"
243
+ )
244
+ end
245
+ input
246
+ end
247
+
248
+ def datetime_range_end_point_input(form, comparator, label)
249
+ input = "#{label} "
250
+ input << DateTimeRangeEndPointSelector.new(
251
+ form.object.send(name)[comparator],
252
+ :prefix => "search", :field_name => comparator.to_s,
253
+ :include_position => true, :index => name, :include_blank => true,
254
+ :datetime_separator => ' &mdash; ', :time_separator => ' : '
255
+ ).select_datetime
256
+ input << @action_view.send(
257
+ :link_to_function, 'Clear',
258
+ "AdminAssistant.clear_datetime_select('search_#{name.underscore}_#{comparator}')"
259
+ )
260
+ input
261
+ end
262
+
263
+ def datetime_range_input(form)
264
+ input = ''
265
+ input << datetime_range_end_point_input(form, :gt, 'After')
266
+ input << "&nbsp;&nbsp;&nbsp;"
267
+ input << datetime_range_end_point_input(form, :lt, 'Before')
268
+ input
269
+ end
270
+
236
271
  def html(form)
237
272
  input = ''
238
- case @column.field_type
239
- when :boolean
240
- input = boolean_input form
273
+ if @column.field_type == :boolean
274
+ input = boolean_input form
275
+ elsif @column.field_type == :datetime
276
+ input = datetime_input form
277
+ else
278
+ if @compare_to_range
279
+ input << "Greater than "
280
+ input << @action_view.send(
281
+ :text_field_tag, "search[#{name}][gt]",
282
+ form.object.send(name)[:gt]
283
+ )
284
+ input << "&nbsp;&nbsp;&nbsp;Less than "
285
+ input << @action_view.send(
286
+ :text_field_tag, "search[#{name}][lt]",
287
+ form.object.send(name)[:lt]
288
+ )
241
289
  else
242
290
  if @column.field_type == :integer && @comparators == :all
243
291
  input << comparator_html(form.object) << ' '
244
292
  end
245
293
  input << form.text_field(name)
246
- if @blank_checkbox
247
- input << check_box_and_hidden_tags(
248
- "search[#{name}(blank)]", @column.blank?(form.object)
249
- )
250
- input << "is blank"
251
- end
294
+ input << blank_checkbox_html(form) if @blank_checkbox
295
+ end
252
296
  end
253
297
  "<p><label>#{label}</label> <br/>#{input}</p>"
254
298
  end
@@ -256,7 +300,18 @@ class AdminAssistant
256
300
 
257
301
  module ShowViewMethods
258
302
  def html(record)
259
- @action_view.send(:h, value(record))
303
+ slug = "_#{name}_for_show"
304
+ if File.exist?(custom_template_file_path(slug))
305
+ varname = @model_class.name.underscore
306
+ @action_view.instance_variable_set("@#{varname}".to_sym, record)
307
+ locals = {varname.to_sym => record}
308
+ @action_view.render(
309
+ :file => file_option_for_custom_template_render(slug),
310
+ :locals => locals
311
+ )
312
+ else
313
+ @action_view.send(:h, string(record))
314
+ end
260
315
  end
261
316
  end
262
317
 
@@ -268,6 +323,7 @@ class AdminAssistant
268
323
  @model_class = admin_assistant.model_class
269
324
  base_setting = admin_assistant[name]
270
325
  @boolean_labels = base_setting.boolean_labels
326
+ @strftime_format = base_setting.strftime_format
271
327
  fem_name = name + '_exists?'
272
328
  if @action_view.respond_to?(fem_name)
273
329
  @file_exists_method = @action_view.method(fem_name)
@@ -283,11 +339,30 @@ class AdminAssistant
283
339
  # Rails 2.3 wants the hidden tag to come before the checkbox, but it's
284
340
  # the opposite for Rails 2.2 and 2.1
285
341
  if RAILS_GEM_VERSION =~ /^2.3/
286
- @action_view.send(:hidden_field_tag, input_name, '0') +
342
+ @action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden") +
287
343
  @action_view.send(:check_box_tag, input_name, '1', value)
288
344
  else
289
345
  @action_view.send(:check_box_tag, input_name, '1', value) +
290
- @action_view.send(:hidden_field_tag, input_name, '0')
346
+ @action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden")
347
+ end
348
+ end
349
+
350
+ def controller
351
+ @action_view.controller
352
+ end
353
+
354
+ def custom_template_file_path(slug)
355
+ File.join(
356
+ RAILS_ROOT, 'app/views', controller.controller_path,
357
+ "#{slug}.html.erb"
358
+ )
359
+ end
360
+
361
+ def file_option_for_custom_template_render(slug)
362
+ if RAILS_GEM_VERSION == '2.1.0'
363
+ File.join(controller.controller_path, "#{slug}.html.erb")
364
+ else
365
+ custom_template_file_path slug
291
366
  end
292
367
  end
293
368
 
@@ -322,6 +397,8 @@ class AdminAssistant
322
397
  value = value(record)
323
398
  if @boolean_labels
324
399
  value ? @boolean_labels.first : @boolean_labels.last
400
+ elsif value.respond_to?(:strftime) && @strftime_format
401
+ value.strftime @strftime_format
325
402
  else
326
403
  value.to_s
327
404
  end
@@ -329,12 +406,17 @@ class AdminAssistant
329
406
  end
330
407
 
331
408
  def value(record)
332
- record.send(name) if record.respond_to?(name)
409
+ value_method = "#{name}_value"
410
+ if @action_view.respond_to?(value_method)
411
+ @action_view.send value_method, record
412
+ else
413
+ record.send(name) if record.respond_to?(name)
414
+ end
333
415
  end
334
416
  end
335
417
 
336
418
  class FormView < View
337
- include IndexViewMethods
419
+ include FormViewMethods
338
420
  end
339
421
 
340
422
  class IndexView < View
@@ -0,0 +1,340 @@
1
+ class AdminAssistant
2
+ # Copied (and then streamlined) from Rails 2.3.5 in an effort to provide
3
+ # consistent functionality all the way back to Rails 2.1.0
4
+ class DateTimeRangeEndPointSelector
5
+ include ActionView::Helpers::TagHelper
6
+
7
+ DEFAULT_PREFIX = 'date'.freeze unless const_defined?('DEFAULT_PREFIX')
8
+ POSITION = {
9
+ :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
10
+ }.freeze unless const_defined?('POSITION')
11
+
12
+ def initialize(datetime, options = {}, html_options = {})
13
+ @options = options.dup
14
+ @html_options = html_options.dup
15
+ @datetime = datetime
16
+ end
17
+
18
+ def select_datetime
19
+ # TODO: Remove tag conditional
20
+ # Ideally we could just join select_date and select_date for the tag case
21
+ if @options[:tag] && @options[:ignore_date]
22
+ select_time
23
+ elsif @options[:tag]
24
+ order = date_order.dup
25
+ order -= [:hour, :minute, :second]
26
+
27
+ @options[:discard_year] ||= true unless order.include?(:year)
28
+ @options[:discard_month] ||= true unless order.include?(:month)
29
+ @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day)
30
+ @options[:discard_minute] ||= true if @options[:discard_hour]
31
+ @options[:discard_second] ||= true unless @options[:include_seconds] && !@options[:discard_minute]
32
+
33
+ # If the day is hidden and the month is visible, the day should be set to the 1st so all month choices are
34
+ # valid (otherwise it could be 31 and february wouldn't be a valid date)
35
+ if @datetime && @options[:discard_day] && !@options[:discard_month]
36
+ @datetime = @datetime.change(:day => 1)
37
+ end
38
+
39
+ [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }
40
+ order += [:hour, :minute, :second] unless @options[:discard_hour]
41
+
42
+ build_selects_from_types(order)
43
+ else
44
+ "#{select_date}#{@options[:datetime_separator]}#{select_time}"
45
+ end
46
+ end
47
+
48
+ def select_date
49
+ order = date_order.dup
50
+
51
+ # TODO: Remove tag conditional
52
+ if @options[:tag]
53
+ @options[:discard_hour] = true
54
+ @options[:discard_minute] = true
55
+ @options[:discard_second] = true
56
+
57
+ @options[:discard_year] ||= true unless order.include?(:year)
58
+ @options[:discard_month] ||= true unless order.include?(:month)
59
+ @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day)
60
+
61
+ # If the day is hidden and the month is visible, the day should be set to the 1st so all month choices are
62
+ # valid (otherwise it could be 31 and february wouldn't be a valid date)
63
+ if @datetime && @options[:discard_day] && !@options[:discard_month]
64
+ @datetime = @datetime.change(:day => 1)
65
+ end
66
+ end
67
+
68
+ [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }
69
+
70
+ build_selects_from_types(order)
71
+ end
72
+
73
+ def select_time
74
+ order = []
75
+
76
+ # TODO: Remove tag conditional
77
+ if @options[:tag]
78
+ @options[:discard_month] = true
79
+ @options[:discard_year] = true
80
+ @options[:discard_day] = true
81
+ @options[:discard_second] ||= true unless @options[:include_seconds]
82
+
83
+ order += [:year, :month, :day] unless @options[:ignore_date]
84
+ end
85
+
86
+ order += [:hour, :minute]
87
+ order << :second if @options[:include_seconds]
88
+
89
+ build_selects_from_types(order)
90
+ end
91
+
92
+ def select_second
93
+ if @options[:use_hidden] || @options[:discard_second]
94
+ build_hidden(:second, sec) if @options[:include_seconds]
95
+ else
96
+ build_options_and_select(:second, sec)
97
+ end
98
+ end
99
+
100
+ def select_minute
101
+ if @options[:use_hidden] || @options[:discard_minute]
102
+ build_hidden(:minute, min)
103
+ else
104
+ build_options_and_select(:minute, min, :step => @options[:minute_step])
105
+ end
106
+ end
107
+
108
+ def select_hour
109
+ if @options[:use_hidden] || @options[:discard_hour]
110
+ build_hidden(:hour, hour)
111
+ else
112
+ build_options_and_select(:hour, hour, :end => 23)
113
+ end
114
+ end
115
+
116
+ def select_day
117
+ if @options[:use_hidden] || @options[:discard_day]
118
+ build_hidden(:day, day)
119
+ else
120
+ build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false)
121
+ end
122
+ end
123
+
124
+ def select_month
125
+ if @options[:use_hidden] || @options[:discard_month]
126
+ build_hidden(:month, month)
127
+ else
128
+ month_options = []
129
+ 1.upto(12) do |month_number|
130
+ options = { :value => month_number }
131
+ options[:selected] = "selected" if month == month_number
132
+ month_options << content_tag(:option, month_name(month_number), options) + "\n"
133
+ end
134
+ build_select(:month, month_options.join)
135
+ end
136
+ end
137
+
138
+ def select_year
139
+ if !@datetime || @datetime == 0
140
+ val = ''
141
+ middle_year = Date.today.year
142
+ else
143
+ val = middle_year = year
144
+ end
145
+
146
+ if @options[:use_hidden] || @options[:discard_year]
147
+ build_hidden(:year, val)
148
+ else
149
+ options = {}
150
+ options[:start] = @options[:start_year] || middle_year - 5
151
+ options[:end] = @options[:end_year] || middle_year + 5
152
+ options[:step] = options[:start] < options[:end] ? 1 : -1
153
+ options[:leading_zeros] = false
154
+
155
+ build_options_and_select(:year, val, options)
156
+ end
157
+ end
158
+
159
+ private
160
+ %w( sec min hour day month year ).each do |method|
161
+ define_method(method) do
162
+ @datetime.kind_of?(Fixnum) ? @datetime : @datetime.send(method) if @datetime
163
+ end
164
+ end
165
+
166
+ # Returns translated month names, but also ensures that a custom month
167
+ # name array has a leading nil element
168
+ def month_names
169
+ month_names = @options[:use_month_names] || translated_month_names
170
+ month_names.unshift(nil) if month_names.size < 13
171
+ month_names
172
+ end
173
+
174
+ # Returns translated month names
175
+ # => [nil, "January", "February", "March",
176
+ # "April", "May", "June", "July",
177
+ # "August", "September", "October",
178
+ # "November", "December"]
179
+ #
180
+ # If :use_short_month option is set
181
+ # => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
182
+ # "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
183
+ def translated_month_names
184
+ if @options[:use_short_month]
185
+ [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
186
+ "Oct", "Nov", "Dec"]
187
+ else
188
+ [nil, "January", "February", "March", "April", "May", "June", "July",
189
+ "August", "September", "October", "November", "December"]
190
+ end
191
+ end
192
+
193
+ # Lookup month name for number
194
+ # month_name(1) => "January"
195
+ #
196
+ # If :use_month_numbers option is passed
197
+ # month_name(1) => 1
198
+ #
199
+ # If :add_month_numbers option is passed
200
+ # month_name(1) => "1 - January"
201
+ def month_name(number)
202
+ if @options[:use_month_numbers]
203
+ number
204
+ elsif @options[:add_month_numbers]
205
+ "#{number} - #{month_names[number]}"
206
+ else
207
+ month_names[number]
208
+ end
209
+ end
210
+
211
+ def date_order
212
+ @options[:order] || translated_date_order
213
+ end
214
+
215
+ def translated_date_order
216
+ [:year, :month, :day]
217
+ end
218
+
219
+ # Build full select tag from date type and options
220
+ def build_options_and_select(type, selected, options = {})
221
+ build_select(type, build_options(selected, options))
222
+ end
223
+
224
+ # Build select option html from date value and options
225
+ # build_options(15, :start => 1, :end => 31)
226
+ # => "<option value="1">1</option>
227
+ # <option value=\"2\">2</option>
228
+ # <option value=\"3\">3</option>..."
229
+ def build_options(selected, options = {})
230
+ start = options.delete(:start) || 0
231
+ stop = options.delete(:end) || 59
232
+ step = options.delete(:step) || 1
233
+ leading_zeros = options.delete(:leading_zeros).nil? ? true : false
234
+
235
+ select_options = []
236
+ start.step(stop, step) do |i|
237
+ value = leading_zeros ? sprintf("%02d", i) : i
238
+ tag_options = { :value => value }
239
+ tag_options[:selected] = "selected" if selected == i
240
+ select_options << content_tag(:option, value, tag_options)
241
+ end
242
+ select_options.join("\n") + "\n"
243
+ end
244
+
245
+ # Builds select tag from date type and html select options
246
+ # build_select(:month, "<option value="1">January</option>...")
247
+ # => "<select id="post_written_on_2i" name="post[written_on(2i)]">
248
+ # <option value="1">January</option>...
249
+ # </select>"
250
+ def build_select(type, select_options_as_html)
251
+ select_options = {
252
+ :id => input_id_from_type(type),
253
+ :name => input_name_from_type(type)
254
+ }.merge(@html_options)
255
+ select_options.merge!(:disabled => 'disabled') if @options[:disabled]
256
+
257
+ select_html = "\n"
258
+ select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank]
259
+ select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
260
+ select_html << select_options_as_html.to_s
261
+
262
+ content_tag(:select, select_html, select_options) + "\n"
263
+ end
264
+
265
+ # Builds a prompt option tag with supplied options or from default options
266
+ # prompt_option_tag(:month, :prompt => 'Select month')
267
+ # => "<option value="">Select month</option>"
268
+ def prompt_option_tag(type, options)
269
+ default_options = {:year => false, :month => false, :day => false, :hour => false, :minute => false, :second => false}
270
+
271
+ case options
272
+ when Hash
273
+ prompt = default_options.merge(options)[type.to_sym]
274
+ when String
275
+ prompt = options
276
+ else
277
+ prompt = I18n.translate(('datetime.prompts.' + type.to_s).to_sym, :locale => @options[:locale])
278
+ end
279
+
280
+ prompt ? content_tag(:option, prompt, :value => '') : ''
281
+ end
282
+
283
+ # Builds hidden input tag for date part and value
284
+ # build_hidden(:year, 2008)
285
+ # => "<input id="post_written_on_1i" name="post[written_on(1i)]" type="hidden" value="2008" />"
286
+ def build_hidden(type, value)
287
+ tag(:input, {
288
+ :type => "hidden",
289
+ :id => input_id_from_type(type),
290
+ :name => input_name_from_type(type),
291
+ :value => value
292
+ }) + "\n"
293
+ end
294
+
295
+ # Returns the name attribute for the input tag
296
+ # => post[written_on(1i)]
297
+ def input_name_from_type(type)
298
+ prefix = @options[:prefix] || DEFAULT_PREFIX
299
+ prefix += "[#{@options[:index]}]" if @options.has_key?(:index)
300
+
301
+ field_name = @options[:field_name] || type
302
+ if @options[:include_position]
303
+ field_name += "(#{POSITION[type]}i)"
304
+ end
305
+
306
+ @options[:discard_type] ? prefix : "#{prefix}[#{field_name}]"
307
+ end
308
+
309
+ # Returns the id attribute for the input tag
310
+ # => "post_written_on_1i"
311
+ def input_id_from_type(type)
312
+ input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
313
+ end
314
+
315
+ # Given an ordering of datetime components, create the selection HTML
316
+ # and join them with their appropriate separators.
317
+ def build_selects_from_types(order)
318
+ select = ''
319
+ order.reverse.each do |type|
320
+ separator = separator(type) unless type == order.first # don't add on last field
321
+ select.insert(0, separator.to_s + send("select_#{type}").to_s)
322
+ end
323
+ select
324
+ end
325
+
326
+ # Returns the separator for a given datetime component
327
+ def separator(type)
328
+ case type
329
+ when :month, :day
330
+ @options[:date_separator]
331
+ when :hour
332
+ (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator]
333
+ when :minute
334
+ @options[:time_separator]
335
+ when :second
336
+ @options[:include_seconds] ? @options[:time_separator] : ""
337
+ end
338
+ end
339
+ end
340
+ end