webroar 0.6.1 → 0.7.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 (402) hide show
  1. data/CHANGELOG +7 -0
  2. data/README +1 -1
  3. data/doc/user-guide.html +125 -85
  4. data/doc/user-guide.txt +2 -2
  5. data/lib/constant.rb +23 -16
  6. data/lib/db_connect.rb +2 -3
  7. data/lib/installer.rb +17 -10
  8. data/lib/user_interaction.rb +21 -10
  9. data/lib/webroar_command.rb +21 -23
  10. data/src/admin_panel/Gemfile +8 -0
  11. data/src/admin_panel/Rakefile +2 -5
  12. data/src/admin_panel/app/controllers/application_controller.rb +1 -1
  13. data/src/admin_panel/app/controllers/exceptions_controller.rb +25 -26
  14. data/src/admin_panel/app/controllers/graph_controller.rb +2 -1
  15. data/src/admin_panel/app/helpers/admin_helper.rb +1 -1
  16. data/src/admin_panel/app/{models → mailers}/mailer.rb +5 -8
  17. data/src/admin_panel/app/models/app.rb +1 -1
  18. data/src/admin_panel/app/models/app_exception.rb +15 -11
  19. data/src/admin_panel/app/models/app_time_sample.rb +40 -10
  20. data/src/admin_panel/app/models/application_specification.rb +71 -41
  21. data/src/admin_panel/app/models/resource_usage.rb +76 -55
  22. data/src/admin_panel/app/models/url_breakup_time_sample.rb +6 -11
  23. data/src/admin_panel/app/models/url_time_sample.rb +57 -13
  24. data/src/admin_panel/app/views/admin/_application_table.html.erb +5 -5
  25. data/src/admin_panel/app/views/admin/_feedback_partial.html.erb +4 -4
  26. data/src/admin_panel/app/views/admin/_report_bug_partial.html.erb +5 -5
  27. data/src/admin_panel/app/views/admin/change_password_form.html.erb +3 -3
  28. data/src/admin_panel/app/views/admin/configuration.html.erb +6 -6
  29. data/src/admin_panel/app/views/admin/home.html.erb +4 -4
  30. data/src/admin_panel/app/views/admin/index.html.erb +5 -5
  31. data/src/admin_panel/app/views/application_specification/_application_specification_form.html.erb +15 -6
  32. data/src/admin_panel/app/views/exceptions/_add_and_list_exception_classes.html.erb +7 -6
  33. data/src/admin_panel/app/views/exceptions/_exception_backtrace_partial.html.erb +1 -1
  34. data/src/admin_panel/app/views/exceptions/_exception_environment_partial.html.erb +30 -30
  35. data/src/admin_panel/app/views/exceptions/_exception_list_partial.html.erb +11 -11
  36. data/src/admin_panel/app/views/exceptions/_show.html.erb +8 -8
  37. data/src/admin_panel/app/views/exceptions/index.html.erb +0 -1
  38. data/src/admin_panel/app/views/graph/_get_database_data.html.erb +1 -1
  39. data/src/admin_panel/app/views/graph/_get_resource_usage_data_app.html.erb +2 -2
  40. data/src/admin_panel/app/views/graph/_get_resource_usage_data_server.html.erb +2 -2
  41. data/src/admin_panel/app/views/graph/_get_throughput_data.html.erb +2 -2
  42. data/src/admin_panel/app/views/graph/_get_url_data.html.erb +4 -4
  43. data/src/admin_panel/app/views/graph/_pie.html.erb +2 -2
  44. data/src/admin_panel/app/views/graph/_query_date.html.erb +1 -1
  45. data/src/admin_panel/app/views/graph/_query_period.html.erb +1 -1
  46. data/src/admin_panel/app/views/graph/_slider_partial.html.erb +5 -4
  47. data/src/admin_panel/app/views/graph/index.html.erb +0 -1
  48. data/src/admin_panel/app/views/headers/_add_expires_text_box.html.erb +5 -5
  49. data/src/admin_panel/app/views/headers/_expires_by_type_form.html.erb +1 -1
  50. data/src/admin_panel/app/views/headers/_headers_table.html.erb +12 -12
  51. data/src/admin_panel/app/views/layouts/application.html.erb +71 -51
  52. data/src/admin_panel/app/views/mail_specification/_current_spec.html.erb +4 -4
  53. data/src/admin_panel/app/views/mail_specification/_sendmail_form.html.erb +3 -3
  54. data/src/admin_panel/app/views/mail_specification/_smtp_form.html.erb +3 -3
  55. data/src/admin_panel/app/views/server_specification/_add_div.html.erb +4 -4
  56. data/src/admin_panel/app/views/server_specification/_ssl_support_form.html.erb +3 -2
  57. data/src/admin_panel/config.ru +4 -0
  58. data/src/admin_panel/config/application.rb +46 -0
  59. data/src/admin_panel/config/boot.rb +4 -112
  60. data/src/admin_panel/config/environment.rb +4 -85
  61. data/src/admin_panel/config/environments/development.rb +20 -13
  62. data/src/admin_panel/config/environments/production.rb +44 -17
  63. data/src/admin_panel/config/environments/test.rb +31 -18
  64. data/src/admin_panel/config/initializers/application_constants.rb +13 -11
  65. data/src/admin_panel/config/initializers/secret_token.rb +7 -0
  66. data/src/admin_panel/config/initializers/session_store.rb +8 -0
  67. data/src/admin_panel/config/initializers/ssl.rb +6 -2
  68. data/src/admin_panel/config/routes.rb +15 -57
  69. data/src/admin_panel/doc/README_FOR_APP +1 -1
  70. data/src/admin_panel/doc/app/ActionView.html +229 -0
  71. data/src/admin_panel/doc/app/ActionView/Helpers.html +229 -0
  72. data/src/admin_panel/doc/app/ActionView/Helpers/AssetTagHelper.html +277 -0
  73. data/src/admin_panel/doc/app/AdminController.html +814 -0
  74. data/src/admin_panel/doc/app/AdminHelper.html +495 -0
  75. data/src/admin_panel/doc/app/Analytics.html +272 -0
  76. data/src/admin_panel/doc/app/Analytics/Database.html +401 -0
  77. data/src/admin_panel/doc/app/Analytics/ResourceUsage.html +683 -0
  78. data/src/admin_panel/doc/app/Analytics/Throughput.html +488 -0
  79. data/src/admin_panel/doc/app/Analytics/Url.html +484 -0
  80. data/src/admin_panel/doc/app/Analytics/UrlBreakup.html +537 -0
  81. data/src/admin_panel/doc/app/App.html +489 -0
  82. data/src/admin_panel/doc/app/AppException.html +710 -0
  83. data/src/admin_panel/doc/app/AppTimeSample.html +620 -0
  84. data/src/admin_panel/doc/app/ApplicationController.html +239 -0
  85. data/src/admin_panel/doc/app/ApplicationHelper.html +296 -0
  86. data/src/admin_panel/doc/app/ApplicationSpecification.html +876 -0
  87. data/src/admin_panel/doc/app/ApplicationSpecificationController.html +552 -0
  88. data/src/admin_panel/doc/app/ApplicationSpecificationHelper.html +219 -0
  89. data/src/admin_panel/doc/app/Control.html +431 -0
  90. data/src/admin_panel/doc/app/ExceptionDetail.html +227 -0
  91. data/src/admin_panel/doc/app/ExceptionsController.html +754 -0
  92. data/src/admin_panel/doc/app/ExceptionsHelper.html +219 -0
  93. data/src/admin_panel/doc/app/GraphController.html +1101 -0
  94. data/src/admin_panel/doc/app/GraphHelper.html +285 -0
  95. data/src/admin_panel/doc/app/Headers.html +549 -0
  96. data/src/admin_panel/doc/app/HeadersController.html +507 -0
  97. data/src/admin_panel/doc/app/HeadersHelper.html +219 -0
  98. data/src/admin_panel/doc/app/MailSpecification.html +685 -0
  99. data/src/admin_panel/doc/app/MailSpecificationController.html +541 -0
  100. data/src/admin_panel/doc/app/MailSpecificationHelper.html +219 -0
  101. data/src/admin_panel/doc/app/Mailer.html +589 -0
  102. data/src/admin_panel/doc/app/Object.html +240 -0
  103. data/src/admin_panel/doc/app/PseudoModel.html +354 -0
  104. data/src/admin_panel/doc/app/ResourceUsage.html +656 -0
  105. data/src/admin_panel/doc/app/SCGI.html +674 -0
  106. data/src/admin_panel/doc/app/ServerSpecification.html +479 -0
  107. data/src/admin_panel/doc/app/ServerSpecificationController.html +500 -0
  108. data/src/admin_panel/doc/app/ServerSpecificationHelper.html +219 -0
  109. data/src/admin_panel/doc/app/SignalHelper.html +287 -0
  110. data/src/admin_panel/doc/app/UrlBreakupTimeSample.html +287 -0
  111. data/src/admin_panel/doc/app/UrlTimeSample.html +986 -0
  112. data/src/admin_panel/doc/app/User.html +290 -0
  113. data/src/admin_panel/doc/app/YAMLConfig.html +247 -0
  114. data/src/admin_panel/doc/app/YAMLWriter.html +284 -0
  115. data/src/admin_panel/doc/app/app/controllers/admin_controller_rb.html +52 -0
  116. data/src/admin_panel/doc/app/app/controllers/application_controller_rb.html +54 -0
  117. data/src/admin_panel/doc/app/app/controllers/application_specification_controller_rb.html +52 -0
  118. data/src/admin_panel/doc/app/app/controllers/exceptions_controller_rb.html +52 -0
  119. data/src/admin_panel/doc/app/app/controllers/graph_controller_rb.html +52 -0
  120. data/src/admin_panel/doc/app/app/controllers/headers_controller_rb.html +52 -0
  121. data/src/admin_panel/doc/app/app/controllers/mail_specification_controller_rb.html +52 -0
  122. data/src/admin_panel/doc/app/app/controllers/server_specification_controller_rb.html +52 -0
  123. data/src/admin_panel/doc/app/app/helpers/admin_helper_rb.html +52 -0
  124. data/src/admin_panel/doc/app/app/helpers/application_helper_rb.html +52 -0
  125. data/src/admin_panel/doc/app/app/helpers/application_specification_helper_rb.html +52 -0
  126. data/src/admin_panel/doc/app/app/helpers/exceptions_helper_rb.html +52 -0
  127. data/src/admin_panel/doc/app/app/helpers/graph_helper_rb.html +52 -0
  128. data/src/admin_panel/doc/app/app/helpers/headers_helper_rb.html +52 -0
  129. data/src/admin_panel/doc/app/app/helpers/mail_specification_helper_rb.html +52 -0
  130. data/src/admin_panel/doc/app/app/helpers/server_specification_helper_rb.html +52 -0
  131. data/src/admin_panel/doc/app/app/mailers/mailer_rb.html +56 -0
  132. data/src/admin_panel/doc/app/app/models/app_exception_rb.html +52 -0
  133. data/src/admin_panel/doc/app/app/models/app_rb.html +54 -0
  134. data/src/admin_panel/doc/app/app/models/app_time_sample_rb.html +52 -0
  135. data/src/admin_panel/doc/app/app/models/application_specification_rb.html +52 -0
  136. data/src/admin_panel/doc/app/app/models/exception_detail_rb.html +52 -0
  137. data/src/admin_panel/doc/app/app/models/headers_rb.html +52 -0
  138. data/src/admin_panel/doc/app/app/models/mail_specification_rb.html +52 -0
  139. data/src/admin_panel/doc/app/app/models/pseudo_model_rb.html +52 -0
  140. data/src/admin_panel/doc/app/app/models/resource_usage_rb.html +52 -0
  141. data/src/admin_panel/doc/app/app/models/server_specification_rb.html +52 -0
  142. data/src/admin_panel/doc/app/app/models/url_breakup_time_sample_rb.html +52 -0
  143. data/src/admin_panel/doc/app/app/models/url_time_sample_rb.html +52 -0
  144. data/src/admin_panel/doc/app/app/models/user_rb.html +52 -0
  145. data/src/admin_panel/doc/app/created.rid +42 -1
  146. data/src/admin_panel/doc/app/doc/README_FOR_APP.html +172 -0
  147. data/src/admin_panel/doc/app/images/brick.png +0 -0
  148. data/src/admin_panel/doc/app/images/brick_link.png +0 -0
  149. data/src/admin_panel/doc/app/images/bug.png +0 -0
  150. data/src/admin_panel/doc/app/images/bullet_black.png +0 -0
  151. data/src/admin_panel/doc/app/images/bullet_toggle_minus.png +0 -0
  152. data/src/admin_panel/doc/app/images/bullet_toggle_plus.png +0 -0
  153. data/src/admin_panel/doc/app/images/date.png +0 -0
  154. data/src/admin_panel/doc/app/images/find.png +0 -0
  155. data/src/admin_panel/doc/app/images/loadingAnimation.gif +0 -0
  156. data/src/admin_panel/doc/app/images/macFFBgHack.png +0 -0
  157. data/src/admin_panel/doc/app/images/package.png +0 -0
  158. data/src/admin_panel/doc/app/images/page_green.png +0 -0
  159. data/src/admin_panel/doc/app/images/page_white_text.png +0 -0
  160. data/src/admin_panel/doc/app/images/page_white_width.png +0 -0
  161. data/src/admin_panel/doc/app/images/plugin.png +0 -0
  162. data/src/admin_panel/doc/app/images/ruby.png +0 -0
  163. data/src/admin_panel/doc/app/images/tag_green.png +0 -0
  164. data/src/admin_panel/doc/app/images/wrench.png +0 -0
  165. data/src/admin_panel/doc/app/images/wrench_orange.png +0 -0
  166. data/src/admin_panel/doc/app/images/zoom.png +0 -0
  167. data/src/admin_panel/doc/app/index.html +564 -20
  168. data/src/admin_panel/doc/app/js/darkfish.js +116 -0
  169. data/src/admin_panel/doc/app/js/jquery.js +32 -0
  170. data/src/admin_panel/doc/app/js/quicksearch.js +114 -0
  171. data/src/admin_panel/doc/app/js/thickbox-compressed.js +10 -0
  172. data/src/admin_panel/doc/app/lib/asset_tag_helper_ext_rb.html +52 -0
  173. data/src/admin_panel/doc/app/lib/control_rb.html +58 -0
  174. data/src/admin_panel/doc/app/lib/graph_controller_extensions/database_analytics_rb.html +52 -0
  175. data/src/admin_panel/doc/app/lib/graph_controller_extensions/resource_usage_analytics_rb.html +52 -0
  176. data/src/admin_panel/doc/app/lib/graph_controller_extensions/throughput_analytics_rb.html +52 -0
  177. data/src/admin_panel/doc/app/lib/graph_controller_extensions/url_analytics_rb.html +52 -0
  178. data/src/admin_panel/doc/app/lib/graph_controller_extensions/url_breakup_analytics_rb.html +52 -0
  179. data/src/admin_panel/doc/app/lib/helper_rb.html +52 -0
  180. data/src/admin_panel/doc/app/lib/scgi_rb.html +54 -0
  181. data/src/admin_panel/doc/app/lib/yaml_writer_rb.html +52 -0
  182. data/src/admin_panel/doc/app/rdoc.css +763 -0
  183. data/src/admin_panel/lib/helper.rb +6 -2
  184. data/src/admin_panel/public/stylesheets/other/login.css +8 -4
  185. data/src/admin_panel/public/stylesheets/other/style.css +21 -17
  186. data/src/admin_panel/script/rails +6 -0
  187. data/src/admin_panel/test/test_helper.rb +2 -2
  188. data/src/admin_panel/vendor/plugins/calendar_date_select/History.txt +281 -0
  189. data/src/admin_panel/vendor/plugins/calendar_date_select/MIT-LICENSE +20 -0
  190. data/src/admin_panel/vendor/plugins/calendar_date_select/Manifest.txt +42 -0
  191. data/src/admin_panel/vendor/plugins/calendar_date_select/README.txt +17 -0
  192. data/src/admin_panel/vendor/plugins/calendar_date_select/Rakefile +37 -0
  193. data/src/admin_panel/vendor/plugins/calendar_date_select/VERSION +1 -0
  194. data/src/admin_panel/vendor/plugins/calendar_date_select/calendar_date_select.gemspec +95 -0
  195. data/src/admin_panel/vendor/plugins/calendar_date_select/init.rb +1 -0
  196. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/functional/cds_test.html +376 -0
  197. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/functional/format_iso_date_test.html +52 -0
  198. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/prototype.js +4184 -0
  199. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/test.css +40 -0
  200. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/unit/cds_helper_methods.html +46 -0
  201. data/src/admin_panel/vendor/plugins/calendar_date_select/js_test/unittest.js +564 -0
  202. data/src/admin_panel/vendor/plugins/calendar_date_select/lib/calendar_date_select.rb +33 -0
  203. data/src/admin_panel/vendor/plugins/calendar_date_select/lib/calendar_date_select/calendar_date_select.rb +122 -0
  204. data/src/admin_panel/vendor/plugins/calendar_date_select/lib/calendar_date_select/form_helpers.rb +237 -0
  205. data/src/admin_panel/vendor/plugins/calendar_date_select/lib/calendar_date_select/includes_helper.rb +29 -0
  206. data/src/admin_panel/vendor/plugins/calendar_date_select/public/blank_iframe.html +2 -0
  207. data/src/admin_panel/vendor/plugins/calendar_date_select/public/images/calendar_date_select/calendar.gif +0 -0
  208. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/calendar_date_select.js +459 -0
  209. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_american.js +35 -0
  210. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_danish.js +31 -0
  211. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_db.js +27 -0
  212. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_euro_24hr.js +7 -0
  213. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_euro_24hr_ymd.js +7 -0
  214. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_finnish.js +32 -0
  215. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_hyphen_ampm.js +37 -0
  216. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_iso_date.js +29 -0
  217. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/format_italian.js +24 -0
  218. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/ar.js +10 -0
  219. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/cs.js +11 -0
  220. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/da.js +11 -0
  221. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/de.js +11 -0
  222. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/es.js +11 -0
  223. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/fi.js +10 -0
  224. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/fr.js +11 -0
  225. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/hu.js +11 -0
  226. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/it.js +9 -0
  227. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/ja.js +11 -0
  228. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/nl.js +11 -0
  229. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/pl.js +11 -0
  230. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/pt.js +11 -0
  231. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/ru.js +10 -0
  232. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/sl.js +11 -0
  233. data/src/admin_panel/vendor/plugins/calendar_date_select/public/javascripts/calendar_date_select/locale/sv.js +9 -0
  234. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/blue.css +130 -0
  235. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/default.css +135 -0
  236. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/green.css +142 -0
  237. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/plain.css +128 -0
  238. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/red.css +135 -0
  239. data/src/admin_panel/vendor/plugins/calendar_date_select/public/stylesheets/calendar_date_select/silver.css +133 -0
  240. data/src/admin_panel/vendor/plugins/calendar_date_select/spec/calendar_date_select/calendar_date_select_spec.rb +14 -0
  241. data/src/admin_panel/vendor/plugins/calendar_date_select/spec/calendar_date_select/form_helpers_spec.rb +189 -0
  242. data/src/admin_panel/vendor/plugins/calendar_date_select/spec/calendar_date_select/includes_helper_spec.rb +46 -0
  243. data/src/admin_panel/vendor/plugins/calendar_date_select/spec/spec_helper.rb +26 -0
  244. data/src/admin_panel/vendor/plugins/open_flash_chart_2_plugin/install.rb +2 -2
  245. data/src/admin_panel/vendor/plugins/open_flash_chart_2_plugin/uninstall.rb +2 -2
  246. data/src/admin_panel/vendor/plugins/prototype_legacy_helper/README.markdown +13 -0
  247. data/src/admin_panel/vendor/plugins/prototype_legacy_helper/init.rb +1 -0
  248. data/src/admin_panel/vendor/plugins/prototype_legacy_helper/lib/prototype_legacy_helper.rb +432 -0
  249. data/src/admin_panel/vendor/plugins/prototype_legacy_helper/test/test_prototype_helper.rb +297 -0
  250. data/src/helper/wr_config.c +1 -1
  251. data/src/ruby_lib/analyzer/message_analyzer.rb +1 -0
  252. data/src/ruby_lib/analyzer/webroar_analyzer.rb +2 -2
  253. data/src/ruby_lib/profiler/message_dispatcher.rb +1 -1
  254. data/src/ruby_lib/ruby_interface/version.rb +2 -2
  255. data/src/ruby_lib/webroar_app_loader.rb +1 -1
  256. data/tasks/gem.rake +5 -7
  257. data/tasks/test.rake +1 -0
  258. data/test/spec/analytics_spec.rb +25 -24
  259. data/test/spec/test_app/README +142 -129
  260. data/test/spec/test_app/Rakefile +2 -5
  261. data/test/spec/test_app/app/controllers/application_controller.rb +3 -8
  262. data/test/spec/test_app/app/controllers/test_controller.rb +3 -3
  263. data/test/spec/test_app/app/controllers/users_controller.rb +8 -8
  264. data/test/spec/test_app/app/helpers/application_helper.rb +2 -1
  265. data/test/spec/test_app/app/helpers/test_helper.rb +2 -0
  266. data/test/spec/test_app/app/helpers/users_helper.rb +2 -0
  267. data/test/spec/test_app/app/models/user.rb +2 -0
  268. data/test/spec/test_app/app/views/layouts/{users.html.erb → application.html.erb} +6 -9
  269. data/test/spec/test_app/app/views/test/post_data.html.erb +2 -2
  270. data/test/spec/test_app/app/views/test/upload_file.html.erb +1 -1
  271. data/test/spec/test_app/{db/migrate/20090602102438_create_users.rb → app/views/users/_form.html.erb} +22 -11
  272. data/test/spec/test_app/app/views/users/edit.html.erb +19 -28
  273. data/test/spec/test_app/app/views/users/index.html.erb +23 -19
  274. data/test/spec/test_app/app/views/users/new.html.erb +19 -28
  275. data/test/spec/test_app/app/views/users/show.html.erb +21 -18
  276. data/test/spec/test_app/config/application.rb +45 -0
  277. data/test/spec/test_app/config/boot.rb +4 -112
  278. data/test/spec/test_app/config/database.yml +1 -1
  279. data/test/spec/test_app/config/environment.rb +4 -41
  280. data/test/spec/test_app/config/environments/development.rb +22 -13
  281. data/test/spec/test_app/config/environments/production.rb +41 -20
  282. data/test/spec/test_app/config/environments/test.rb +35 -28
  283. data/test/spec/test_app/config/initializers/backtrace_silencers.rb +2 -2
  284. data/test/spec/test_app/config/initializers/inflections.rb +1 -1
  285. data/test/spec/test_app/config/initializers/secret_token.rb +7 -0
  286. data/test/spec/test_app/config/initializers/session_store.rb +3 -10
  287. data/test/spec/test_app/config/locales/en.yml +5 -0
  288. data/test/spec/test_app/config/routes.rb +37 -22
  289. data/test/spec/test_app/db/migrate/20110906113329_create_users.rb +13 -0
  290. data/test/spec/test_app/db/seeds.rb +7 -0
  291. data/test/spec/test_app/public/404.html +15 -19
  292. data/test/spec/test_app/public/422.html +15 -19
  293. data/test/spec/test_app/public/500.html +14 -18
  294. data/test/spec/test_app/public/index.html +41 -77
  295. data/test/spec/test_app/public/javascripts/controls.js +5 -3
  296. data/test/spec/test_app/public/javascripts/dragdrop.js +7 -6
  297. data/test/spec/test_app/public/javascripts/effects.js +8 -13
  298. data/test/spec/test_app/public/javascripts/prototype.js +3381 -1700
  299. data/test/spec/test_app/public/javascripts/rails.js +191 -0
  300. data/test/spec/test_app/public/stylesheets/scaffold.css +15 -13
  301. data/test/spec/test_app/script/rails +6 -0
  302. metadata +340 -163
  303. data/src/admin_panel/Gemfile.lock +0 -79
  304. data/src/admin_panel/doc/app/classes/ActionView.html +0 -111
  305. data/src/admin_panel/doc/app/classes/ActionView/Helpers.html +0 -111
  306. data/src/admin_panel/doc/app/classes/ActionView/Helpers/AssetTagHelper.html +0 -149
  307. data/src/admin_panel/doc/app/classes/AdminController.html +0 -628
  308. data/src/admin_panel/doc/app/classes/AdminHelper.html +0 -482
  309. data/src/admin_panel/doc/app/classes/Analytics.html +0 -138
  310. data/src/admin_panel/doc/app/classes/Analytics/Database.html +0 -245
  311. data/src/admin_panel/doc/app/classes/Analytics/ResourceUsage.html +0 -478
  312. data/src/admin_panel/doc/app/classes/Analytics/Throughput.html +0 -316
  313. data/src/admin_panel/doc/app/classes/Analytics/Url.html +0 -314
  314. data/src/admin_panel/doc/app/classes/Analytics/UrlBreakup.html +0 -372
  315. data/src/admin_panel/doc/app/classes/App.html +0 -298
  316. data/src/admin_panel/doc/app/classes/AppException.html +0 -330
  317. data/src/admin_panel/doc/app/classes/AppTimeSample.html +0 -427
  318. data/src/admin_panel/doc/app/classes/ApplicationController.html +0 -118
  319. data/src/admin_panel/doc/app/classes/ApplicationHelper.html +0 -172
  320. data/src/admin_panel/doc/app/classes/ApplicationSpecification.html +0 -641
  321. data/src/admin_panel/doc/app/classes/ApplicationSpecificationController.html +0 -354
  322. data/src/admin_panel/doc/app/classes/Control.html +0 -273
  323. data/src/admin_panel/doc/app/classes/ExceptionsController.html +0 -612
  324. data/src/admin_panel/doc/app/classes/ExceptionsHelper.html +0 -105
  325. data/src/admin_panel/doc/app/classes/GraphController.html +0 -804
  326. data/src/admin_panel/doc/app/classes/GraphHelper.html +0 -164
  327. data/src/admin_panel/doc/app/classes/MailSpecification.html +0 -357
  328. data/src/admin_panel/doc/app/classes/MailSpecificationController.html +0 -304
  329. data/src/admin_panel/doc/app/classes/PseudoModel.html +0 -206
  330. data/src/admin_panel/doc/app/classes/ResourceUsage.html +0 -425
  331. data/src/admin_panel/doc/app/classes/SCGI.html +0 -406
  332. data/src/admin_panel/doc/app/classes/ServerSpecification.html +0 -325
  333. data/src/admin_panel/doc/app/classes/ServerSpecificationController.html +0 -273
  334. data/src/admin_panel/doc/app/classes/UrlBreakupTimeSample.html +0 -169
  335. data/src/admin_panel/doc/app/classes/UrlTimeSample.html +0 -708
  336. data/src/admin_panel/doc/app/classes/User.html +0 -165
  337. data/src/admin_panel/doc/app/classes/YAMLWriter.html +0 -159
  338. data/src/admin_panel/doc/app/files/app/controllers/admin_controller_rb.html +0 -101
  339. data/src/admin_panel/doc/app/files/app/controllers/application_controller_rb.html +0 -108
  340. data/src/admin_panel/doc/app/files/app/controllers/application_specification_controller_rb.html +0 -101
  341. data/src/admin_panel/doc/app/files/app/controllers/exceptions_controller_rb.html +0 -101
  342. data/src/admin_panel/doc/app/files/app/controllers/graph_controller_rb.html +0 -101
  343. data/src/admin_panel/doc/app/files/app/controllers/mail_specification_controller_rb.html +0 -101
  344. data/src/admin_panel/doc/app/files/app/controllers/server_specification_controller_rb.html +0 -101
  345. data/src/admin_panel/doc/app/files/app/helpers/admin_helper_rb.html +0 -101
  346. data/src/admin_panel/doc/app/files/app/helpers/application_helper_rb.html +0 -101
  347. data/src/admin_panel/doc/app/files/app/helpers/exceptions_helper_rb.html +0 -101
  348. data/src/admin_panel/doc/app/files/app/helpers/graph_helper_rb.html +0 -101
  349. data/src/admin_panel/doc/app/files/app/models/app_exception_rb.html +0 -101
  350. data/src/admin_panel/doc/app/files/app/models/app_rb.html +0 -108
  351. data/src/admin_panel/doc/app/files/app/models/app_time_sample_rb.html +0 -101
  352. data/src/admin_panel/doc/app/files/app/models/application_specification_rb.html +0 -101
  353. data/src/admin_panel/doc/app/files/app/models/mail_specification_rb.html +0 -101
  354. data/src/admin_panel/doc/app/files/app/models/pseudo_model_rb.html +0 -101
  355. data/src/admin_panel/doc/app/files/app/models/resource_usage_rb.html +0 -101
  356. data/src/admin_panel/doc/app/files/app/models/server_specification_rb.html +0 -101
  357. data/src/admin_panel/doc/app/files/app/models/url_breakup_time_sample_rb.html +0 -101
  358. data/src/admin_panel/doc/app/files/app/models/url_time_sample_rb.html +0 -101
  359. data/src/admin_panel/doc/app/files/app/models/user_rb.html +0 -101
  360. data/src/admin_panel/doc/app/files/doc/README_FOR_APP.html +0 -109
  361. data/src/admin_panel/doc/app/files/lib/asset_tag_helper_ext_rb.html +0 -101
  362. data/src/admin_panel/doc/app/files/lib/control_rb.html +0 -110
  363. data/src/admin_panel/doc/app/files/lib/graph_controller_extensions/database_analytics_rb.html +0 -101
  364. data/src/admin_panel/doc/app/files/lib/graph_controller_extensions/resource_usage_analytics_rb.html +0 -101
  365. data/src/admin_panel/doc/app/files/lib/graph_controller_extensions/throughput_analytics_rb.html +0 -101
  366. data/src/admin_panel/doc/app/files/lib/graph_controller_extensions/url_analytics_rb.html +0 -101
  367. data/src/admin_panel/doc/app/files/lib/graph_controller_extensions/url_breakup_analytics_rb.html +0 -101
  368. data/src/admin_panel/doc/app/files/lib/scgi_rb.html +0 -101
  369. data/src/admin_panel/doc/app/files/lib/yaml_writer_rb.html +0 -101
  370. data/src/admin_panel/doc/app/fr_class_index.html +0 -60
  371. data/src/admin_panel/doc/app/fr_file_index.html +0 -58
  372. data/src/admin_panel/doc/app/fr_method_index.html +0 -206
  373. data/src/admin_panel/doc/app/rdoc-style.css +0 -208
  374. data/src/admin_panel/public/dispatch.cgi +0 -10
  375. data/src/admin_panel/public/dispatch.fcgi +0 -24
  376. data/src/admin_panel/public/dispatch.rb +0 -10
  377. data/src/admin_panel/script/about +0 -4
  378. data/src/admin_panel/script/console +0 -3
  379. data/src/admin_panel/script/dbconsole +0 -3
  380. data/src/admin_panel/script/destroy +0 -3
  381. data/src/admin_panel/script/generate +0 -3
  382. data/src/admin_panel/script/performance/benchmarker +0 -3
  383. data/src/admin_panel/script/performance/profiler +0 -3
  384. data/src/admin_panel/script/performance/request +0 -3
  385. data/src/admin_panel/script/plugin +0 -3
  386. data/src/admin_panel/script/process/inspector +0 -3
  387. data/src/admin_panel/script/process/reaper +0 -3
  388. data/src/admin_panel/script/process/spawner +0 -3
  389. data/src/admin_panel/script/runner +0 -3
  390. data/src/admin_panel/script/server +0 -3
  391. data/test/spec/test_app/config/initializers/new_rails_defaults.rb +0 -19
  392. data/test/spec/test_app/script/about +0 -4
  393. data/test/spec/test_app/script/console +0 -3
  394. data/test/spec/test_app/script/dbconsole +0 -3
  395. data/test/spec/test_app/script/destroy +0 -3
  396. data/test/spec/test_app/script/generate +0 -3
  397. data/test/spec/test_app/script/performance/benchmarker +0 -3
  398. data/test/spec/test_app/script/performance/profiler +0 -3
  399. data/test/spec/test_app/script/plugin +0 -3
  400. data/test/spec/test_app/script/runner +0 -3
  401. data/test/spec/test_app/script/server +0 -3
  402. data/test/spec/test_app/vendor/.placeholder +0 -0
@@ -0,0 +1,33 @@
1
+ require "calendar_date_select/calendar_date_select.rb"
2
+ require "calendar_date_select/form_helpers.rb"
3
+ require "calendar_date_select/includes_helper.rb"
4
+
5
+ if Object.const_defined?(:Rails) && File.directory?(Rails.root.to_s + "/public")
6
+ ActionView::Helpers::FormHelper.send(:include, CalendarDateSelect::FormHelpers)
7
+ ActionView::Base.send(:include, CalendarDateSelect::FormHelpers)
8
+ ActionView::Base.send(:include, CalendarDateSelect::IncludesHelper)
9
+
10
+ # Filthy backwards compatibility hooks... grumble
11
+ if ([Rails::VERSION::MAJOR, Rails::VERSION::MINOR] <=> [2, 2]) == -1
12
+ ActionView::Helpers::InstanceTag.class_eval do
13
+ def self.new_with_backwards_compatibility(object_name, method_name, template_object, object = nil)
14
+ new(object_name, method_name, template_object, nil, object)
15
+ end
16
+ end
17
+
18
+ else
19
+ ActionView::Helpers::InstanceTag.class_eval do
20
+ class << self; alias new_with_backwards_compatibility new; end
21
+ end
22
+ end
23
+
24
+ # install files
25
+ unless File.exists?(Rails.root.to_s + '/public/javascripts/calendar_date_select/calendar_date_select.js')
26
+ ['/public', '/public/javascripts/calendar_date_select', '/public/stylesheets/calendar_date_select', '/public/images/calendar_date_select', '/public/javascripts/calendar_date_select/locale'].each do |dir|
27
+ source = File.dirname(__FILE__) + "/../#{dir}"
28
+ dest = Rails.root.to_s + dir
29
+ FileUtils.mkdir_p(dest)
30
+ FileUtils.cp(Dir.glob(source+'/*.*'), dest)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,122 @@
1
+ module CalendarDateSelect
2
+ VERSION = '1.16.2'
3
+
4
+ FORMATS = {
5
+ :natural => {
6
+ :date => "%B %d, %Y",
7
+ :time => " %I:%M %p"
8
+ },
9
+ :hyphen_ampm => {
10
+ :date => "%Y-%m-%d",
11
+ :time => " %I:%M %p",
12
+ :javascript_include => "format_hyphen_ampm"
13
+ },
14
+ :iso_date => {
15
+ :date => "%Y-%m-%d",
16
+ :time => " %H:%M",
17
+ :javascript_include => "format_iso_date"
18
+ },
19
+ :finnish => {
20
+ :date => "%d.%m.%Y",
21
+ :time => " %H:%M",
22
+ :javascript_include => "format_finnish"
23
+ },
24
+ :danish => {
25
+ :date => "%d/%m/%Y",
26
+ :time => " %H:%M",
27
+ :javascript_include => "format_danish"
28
+ },
29
+ :american => {
30
+ :date => "%m/%d/%Y",
31
+ :time => " %I:%M %p",
32
+ :javascript_include => "format_american"
33
+ },
34
+ :euro_24hr => {
35
+ :date => "%d %B %Y",
36
+ :time => " %H:%M",
37
+ :javascript_include => "format_euro_24hr"
38
+ },
39
+ :euro_24hr_ymd => {
40
+ :date => "%Y.%m.%d",
41
+ :time => " %H:%M",
42
+ :javascript_include => "format_euro_24hr_ymd"
43
+ },
44
+ :italian => {
45
+ :date => "%d/%m/%Y",
46
+ :time => " %H:%M",
47
+ :javascript_include => "format_italian"
48
+ },
49
+ :db => {
50
+ :date => "%Y-%m-%d",
51
+ :time => " %H:%M",
52
+ :javascript_include => "format_db"
53
+ }
54
+ }
55
+
56
+ # Returns the default_options hash. These options are by default provided to every calendar_date_select control, unless otherwise overrided.
57
+ #
58
+ # Example:
59
+ # # At the bottom of config/environment.rb:
60
+ # CalendarDateSelect.default_options.update(
61
+ # :popup => "force",
62
+ # :month_year => "label",
63
+ # :image => "custom_calendar_picker.png"
64
+ # )
65
+ def self.default_options
66
+ @calendar_date_select_default_options ||= { :image => "calendar_date_select/calendar.gif" }
67
+ end
68
+
69
+ # Set the picker image. Provide the image url the same way you would provide it to image_tag
70
+ def self.image=(value)
71
+ default_options[:image] = value
72
+ end
73
+
74
+ # Returns the options for the given format
75
+ #
76
+ # Example:
77
+ # CalendarDateSelect.format = :italian
78
+ # puts CalendarDateSelect.format[:date]
79
+ # => "%d/%m/%Y"
80
+ def self.format
81
+ @calendar_date_select_format ||= FORMATS[:natural]
82
+ end
83
+
84
+ # Set the format. To see a list of available formats, CalendarDateSelect::FORMATS.keys, or open lib/calendar_date_select/calendar_date_select.rb
85
+ #
86
+ # (e.g. CalendarDateSelect.format = :italian)
87
+ def self.format=(format)
88
+ raise "CalendarDateSelect: Unrecognized format specification: #{format}" unless FORMATS.has_key?(format)
89
+ @calendar_date_select_format = FORMATS[format]
90
+ end
91
+
92
+ def self.date_format_string(time = false)
93
+ format[:date] + (time ? format[:time] : "")
94
+ end
95
+
96
+ def self.format_date(date)
97
+ if date.is_a?(Date)
98
+ date.strftime(date_format_string(false))
99
+ else
100
+ date.strftime(date_format_string(true))
101
+ end
102
+ end
103
+
104
+ def self.format_time(value, options = {})
105
+ return value unless value.respond_to?("strftime")
106
+ if options[:time]
107
+ format_date(value)
108
+ else
109
+ format_date(value.to_date)
110
+ end
111
+ end
112
+
113
+ # Detects the presence of time in a date, string
114
+ def self.has_time?(value)
115
+ case value
116
+ when DateTime, Time then true
117
+ when Date then false
118
+ else
119
+ /[0-9]:[0-9]{2}/.match(value.to_s) ? true : false
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,237 @@
1
+ # Various helpers available for use in your view
2
+ module CalendarDateSelect::FormHelpers
3
+
4
+ # Similar to text_field_tag, but adds a calendar picker, naturally.
5
+ #
6
+ # == Arguments
7
+ #
8
+ # +name+ - the html name of the tag
9
+ # +value+ - When specified as a string, uses value verbatim. When Date, DateTime, Time, it converts it to a string basd off the format set by CalendarDateSelect#format=
10
+ # +options+ - ...
11
+ #
12
+ # == Options
13
+ #
14
+ # === :embedded
15
+ #
16
+ # Put the calendar straight into the form, rather than using a popup type of form.
17
+ #
18
+ # <%= calendar_date_select_tag "name", "2007-01-01", :embedded => true %>
19
+ #
20
+ # === :hidden
21
+ #
22
+ # Use a hidden element instead of a text box for a pop up calendar. Not compatible with :embedded => true. You'll probably want to use an onchange callback to do something with the value.
23
+ #
24
+ # <span id='cds_value' />
25
+ # <%= calendar_date_select_tag "hidden_date_selector", "", :hidden => "true", :onchange => "$('cds_value').update($F(this));" %>
26
+ #
27
+ # === :image
28
+ #
29
+ # Specify an alternative icon to use for the date picker.
30
+ #
31
+ # To use /images/groovy.png:
32
+ #
33
+ # <%= calendar_date_select_tag "altered_image", "", :image => "groovy.png" %>
34
+ #
35
+ # === :minute_interval
36
+ #
37
+ # Specifies the minute interval used in the hour/minute selector. Default is 5.
38
+ #
39
+ # <%= calendar_date_select_tag "month_year_selector_label", "", :minute_interval => 15 %>
40
+ #
41
+ # === :month_year
42
+ #
43
+ # Customize the month and year selectors at the top of the control.
44
+ #
45
+ # Valid values:
46
+ # * "dropdowns" (default) - Use a separate dropdown control for both the month and year
47
+ # * "label" - Use static text to show the month and the year.
48
+ #
49
+ # <%= calendar_date_select_tag "month_year_selector_label", "", :month_year => "label" %>
50
+ #
51
+ # === :popup => 'force'
52
+ #
53
+ # Forces the user to use the popup calendar by making it's text-box read-only and causing calendar_date_select to override it's default behavior of not allowing selection of a date on a target element that is read-only.
54
+ #
55
+ # <%= calendar_date_select_tag "name", "2007-01-01", :popup => "force" %>
56
+ #
57
+ # === :time
58
+ #
59
+ # Show time in the controls. There's three options:
60
+ #
61
+ # * +true+ - show an hour/minute selector.
62
+ # * +false+ - don't show an hour/minute selector.
63
+ # * +"mixed"+ - Show an hour/minute selector, but include a "all day" option - allowing them to choose whether or not to specify a time.
64
+ #
65
+ # === :year_range
66
+ #
67
+ # Limit the year range. You can pass in an array or range of ruby Date/Time objects or FixNum's.
68
+ #
69
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => 10.years.ago..0.years.from_now %>
70
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => [0.years.ago, 10.years.from_now] %>
71
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => 2000..2007 %>
72
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => [2000, 2007] %>
73
+ #
74
+ # == CALLBACKS
75
+ #
76
+ # The following callbacks are available:
77
+ #
78
+ # * before_show / after_show
79
+ # * before_close / after_close
80
+ # * after_navigate - Called when navigating to a different month. Passes first parameter as a date object refering to the current month viewed
81
+ # * onchange - Called when the form input value changes
82
+ #
83
+ # <%= calendar_date_select_tag "event_demo", "",
84
+ # :before_show => "log('Calendar Showing');" ,
85
+ # :after_show => "log('Calendar Shown');" ,
86
+ # :before_close => "log('Calendar closing');" ,
87
+ # :after_close => "log('Calendar closed');",
88
+ # :after_navigate => "log('Current month is ' + (param.getMonth()+1) + '/' + (param.getFullYear()));",
89
+ # :onchange => "log('value changed to - ' + $F(this));" %>
90
+ #
91
+ # }}}
92
+ #
93
+ # All callbacks are executed within the context of the target input element. If you'd like to access the CalendarDateSelect object itself, you can access it via "this.calendar_date_select".
94
+ #
95
+ # For example:
96
+ #
97
+ # <%= calendar_date_select_tag "event_demo", "", :after_navigate => "alert('The current selected month is ' + this.calendar_date_select.selected_date.getMonth());" ,
98
+ def calendar_date_select_tag( name, value = nil, options = {})
99
+ image, options, javascript_options = calendar_date_select_process_options(options)
100
+ value = CalendarDateSelect.format_time(value, javascript_options)
101
+
102
+ javascript_options.delete(:format)
103
+
104
+ options[:id] ||= name
105
+ tag = javascript_options[:hidden] || javascript_options[:embedded] ?
106
+ hidden_field_tag(name, value, options) :
107
+ text_field_tag(name, value, options)
108
+
109
+ calendar_date_select_output(tag, image, options, javascript_options)
110
+ end
111
+
112
+ # Similar to the difference between +text_field_tag+ and +text_field+, this method behaves like +text_field+
113
+ #
114
+ # It receives the same options as +calendar_date_select_tag+. Need for time selection is automatically detected by checking the corresponding column meta information of Model#columns_hash
115
+ def calendar_date_select(object, method, options={})
116
+ obj = options[:object] || instance_variable_get("@#{object}")
117
+
118
+ if !options.include?(:time) && obj.class.respond_to?("columns_hash")
119
+ column_type = obj.class.columns_hash[method.to_s].type if obj.class.columns_hash.include?(method.to_s)
120
+ options[:time] = true if column_type == :datetime
121
+ end
122
+
123
+ use_time = options[:time]
124
+
125
+ if options[:time].to_s=="mixed"
126
+ use_time = false if Date===(obj.respond_to?(method) && obj.send(method))
127
+ end
128
+
129
+ image, options, javascript_options = calendar_date_select_process_options(options)
130
+
131
+ options[:value] ||=
132
+ if(obj.respond_to?(method) && obj.send(method).respond_to?(:strftime))
133
+ obj.send(method).strftime(CalendarDateSelect.date_format_string(use_time))
134
+ elsif obj.respond_to?("#{method}_before_type_cast")
135
+ obj.send("#{method}_before_type_cast")
136
+ elsif obj.respond_to?(method)
137
+ obj.send(method).to_s
138
+ else
139
+ begin
140
+ obj.send(method).strftime(CalendarDateSelect.date_format_string(use_time))
141
+ rescue
142
+ nil
143
+ end
144
+ end
145
+
146
+ tag = ActionView::Helpers::InstanceTag.new_with_backwards_compatibility(object, method, self, options.delete(:object))
147
+ calendar_date_select_output(
148
+ tag.to_input_field_tag( (javascript_options[:hidden] || javascript_options[:embedded]) ? "hidden" : "text", options),
149
+ image,
150
+ options,
151
+ javascript_options
152
+ )
153
+ end
154
+
155
+ private
156
+ # extracts any options passed into calendar date select, appropriating them to either the Javascript call or the html tag.
157
+ def calendar_date_select_process_options(options)
158
+ options, javascript_options = CalendarDateSelect.default_options.merge(options), {}
159
+ image = options.delete(:image)
160
+ callbacks = [:before_show, :before_close, :after_show, :after_close, :after_navigate]
161
+ for key in [:default_time, :time, :valid_date_check, :embedded, :buttons, :clear_button, :format, :year_range, :month_year, :popup, :hidden, :minute_interval] + callbacks
162
+ javascript_options[key] = options.delete(key) if options.has_key?(key)
163
+ end
164
+
165
+ if (default_time = javascript_options[:default_time])
166
+ if default_time.respond_to?(:strftime)
167
+ javascript_options[:default_time] = "new Date('#{default_time.strftime(CalendarDateSelect.date_format_string(true))}')"
168
+ else
169
+ javascript_options[:default_time] = "function() { return #{default_time} }"
170
+ end
171
+ end
172
+
173
+ # if passing in mixed, pad it with single quotes
174
+ javascript_options[:time] = "'mixed'" if javascript_options[:time].to_s=="mixed"
175
+ javascript_options[:month_year] = "'#{javascript_options[:month_year]}'" if javascript_options[:month_year]
176
+
177
+ # if we are forcing the popup, automatically set the readonly property on the input control.
178
+ if javascript_options[:popup].to_s == "force"
179
+ javascript_options[:popup] = "'force'"
180
+ options[:readonly] = true
181
+ end
182
+
183
+ if (vdc=javascript_options.delete(:valid_date_check))
184
+ if vdc.include?(";") || vdc.include?("function")
185
+ raise ArgumentError, ":valid_date_check function is missing a 'return' statement. Try something like: :valid_date_check => 'if (date > new(Date)) return true; else return false;'" unless vdc.include?("return");
186
+ end
187
+
188
+ vdc = "return(#{vdc})" unless vdc.include?("return")
189
+ vdc = "function(date) { #{vdc} }" unless vdc.include?("function")
190
+ javascript_options[:valid_date_check] = vdc
191
+ end
192
+
193
+ javascript_options[:popup_by] ||= "this" if javascript_options[:hidden]
194
+
195
+ # surround any callbacks with a function, if not already done so
196
+ for key in callbacks
197
+ javascript_options[key] = "function(param) { #{javascript_options[key]} }" unless javascript_options[key].include?("function") if javascript_options[key]
198
+ end
199
+
200
+ javascript_options[:year_range] = format_year_range(javascript_options[:year_range] || 10)
201
+ [image, options, javascript_options]
202
+ end
203
+
204
+ def calendar_date_select_output(input, image, options = {}, javascript_options = {})
205
+ out = input
206
+ if javascript_options[:embedded]
207
+ uniq_id = "cds_placeholder_#{(rand*100000).to_i}"
208
+ # we need to be able to locate the target input element, so lets stick an invisible span tag here we can easily locate
209
+ out << content_tag(:span, nil, :style => "display: none; position: absolute;", :id => uniq_id)
210
+ out << javascript_tag("new CalendarDateSelect( $('#{uniq_id}').previous(), #{options_for_javascript(javascript_options)} ); ")
211
+ else
212
+ out << " "
213
+ out << image_tag(image,
214
+ :onclick => "new CalendarDateSelect( $(this).previous(), #{options_for_javascript(javascript_options)} );",
215
+ :style => 'border:0px; cursor:pointer;',
216
+ :class=>'calendar_date_select_popup_icon')
217
+ end
218
+ out
219
+ end
220
+
221
+ def format_year_range(year) # nodoc
222
+ return year unless year.respond_to?(:first)
223
+ return "[#{year.first}, #{year.last}]" unless year.first.respond_to?(:strftime)
224
+ return "[#{year.first.year}, #{year.last.year}]"
225
+ end
226
+ end
227
+
228
+ # Helper method for form builders
229
+ module ActionView
230
+ module Helpers
231
+ class FormBuilder
232
+ def calendar_date_select(method, options = {})
233
+ @template.calendar_date_select(@object_name, method, options.merge(:object => @object))
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,29 @@
1
+ module CalendarDateSelect::IncludesHelper
2
+ # returns the selected calendar_date_select stylesheet (not an array)
3
+ def calendar_date_select_stylesheets(options = {})
4
+ options.assert_valid_keys(:style)
5
+ "calendar_date_select/#{options[:style] || "default"}"
6
+ end
7
+
8
+ # returns an array of javascripts needed for the selected locale, date_format, and calendar control itself.
9
+ def calendar_date_select_javascripts(options = {})
10
+ options.assert_valid_keys(:locale)
11
+ files = ["calendar_date_select/calendar_date_select"]
12
+ files << "calendar_date_select/locale/#{options[:locale]}" if options[:locale]
13
+ files << "calendar_date_select/#{CalendarDateSelect.format[:javascript_include]}" if CalendarDateSelect.format[:javascript_include]
14
+ files
15
+ end
16
+
17
+ # returns html necessary to load javascript and css to make calendar_date_select work
18
+ def calendar_date_select_includes(*args)
19
+ return "" if @cds_already_included
20
+ @cds_already_included=true
21
+
22
+ options = (Hash === args.last) ? args.pop : {}
23
+ options.assert_valid_keys(:style, :locale)
24
+ options[:style] ||= args.shift
25
+
26
+ javascript_include_tag(*calendar_date_select_javascripts(:locale => options[:locale])) + "\n" +
27
+ stylesheet_link_tag(*calendar_date_select_stylesheets(:style => options[:style])) + "\n"
28
+ end
29
+ end
@@ -0,0 +1,2 @@
1
+ <!-- Nothing here; part of the calendar_date_select plugin -->
2
+ <html><head></head><body></body></html>
@@ -0,0 +1,459 @@
1
+ // CalendarDateSelect version 1.16.3 - a prototype based date picker
2
+ // Questions, comments, bugs? - see the project page: http://code.google.com/p/calendardateselect
3
+ if (typeof Prototype == 'undefined') alert("CalendarDateSelect Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (.g. <%= javascript_include_tag :defaults %>) *before* it includes calendar_date_select.js (.g. <%= calendar_date_select_includes %>).");
4
+ if (Prototype.Version < "1.6") alert("Prototype 1.6.0 is required. If using earlier version of prototype, please use calendar_date_select version 1.8.3");
5
+
6
+ Element.addMethods({
7
+ purgeChildren: function(element) { $A(element.childNodes).each(function(e){$(e).remove();}); },
8
+ build: function(element, type, options, style) {
9
+ var newElement = Element.buildAndAppend(type, options, style);
10
+ element.appendChild(newElement);
11
+ return newElement;
12
+ }
13
+ });
14
+
15
+ Element.buildAndAppend = function(type, options, style)
16
+ {
17
+ var e = $(document.createElement(type));
18
+ $H(options).each(function(pair) { e[pair.key] = pair.value });
19
+ if (style) e.setStyle(style);
20
+ return e;
21
+ };
22
+ nil = null;
23
+
24
+ Date.one_day = 24*60*60*1000;
25
+ Date.weekdays = $w("S M T W T F S");
26
+ Date.first_day_of_week = 0;
27
+ Date.months = $w("January February March April May June July August September October November December" );
28
+ Date.padded2 = function(hour) { var padded2 = parseInt(hour, 10); if (hour < 10) padded2 = "0" + padded2; return padded2; }
29
+ Date.prototype.getPaddedMinutes = function() { return Date.padded2(this.getMinutes()); }
30
+ Date.prototype.getAMPMHour = function() { var hour = this.getHours(); return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
31
+ Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "AM" : "PM"; }
32
+ Date.prototype.stripTime = function() { return new Date(this.getFullYear(), this.getMonth(), this.getDate());};
33
+ Date.prototype.daysDistance = function(compare_date) { return Math.round((compare_date - this) / Date.one_day); };
34
+ Date.prototype.toFormattedString = function(include_time){
35
+ var hour, str;
36
+ str = Date.months[this.getMonth()] + " " + this.getDate() + ", " + this.getFullYear();
37
+
38
+ if (include_time) { hour = this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
39
+ return str;
40
+ }
41
+ Date.parseFormattedString = function(string) { return new Date(string);}
42
+ Math.floor_to_interval = function(n, i) { return Math.floor(n/i) * i;}
43
+ window.f_height = function() { return( [window.innerHeight ? window.innerHeight : null, document.documentElement ? document.documentElement.clientHeight : null, document.body ? document.body.clientHeight : null].select(function(x){return x>0}).first()||0); }
44
+ window.f_scrollTop = function() { return ([window.pageYOffset ? window.pageYOffset : null, document.documentElement ? document.documentElement.scrollTop : null, document.body ? document.body.scrollTop : null].select(function(x){return x>0}).first()||0 ); }
45
+
46
+ _translations = {
47
+ "OK": "OK",
48
+ "Now": "Now",
49
+ "Today": "Today",
50
+ "Clear": "Clear"
51
+ }
52
+ SelectBox = Class.create();
53
+ SelectBox.prototype = {
54
+ initialize: function(parent_element, values, html_options, style_options) {
55
+ this.element = $(parent_element).build("select", html_options, style_options);
56
+ this.populate(values);
57
+ },
58
+ populate: function(values) {
59
+ this.element.purgeChildren();
60
+ var that = this; $A(values).each(function(pair) { if (typeof(pair)!="object") {pair = [pair, pair]}; that.element.build("option", { value: pair[1], innerHTML: pair[0]}) });
61
+ },
62
+ setValue: function(value) {
63
+ var e = this.element;
64
+ var matched = false;
65
+ $R(0, e.options.length - 1 ).each(function(i) { if(e.options[i].value==value.toString()) {e.selectedIndex = i; matched = true;}; } );
66
+ return matched;
67
+ },
68
+ getValue: function() { return $F(this.element)}
69
+ }
70
+ CalendarDateSelect = Class.create();
71
+ CalendarDateSelect.prototype = {
72
+ initialize: function(target_element, options) {
73
+ this.target_element = $(target_element); // make sure it's an element, not a string
74
+ if (!this.target_element) { alert("Target element " + target_element + " not found!"); return false;}
75
+ if (this.target_element.tagName != "INPUT") this.target_element = this.target_element.down("INPUT")
76
+
77
+ this.target_element.calendar_date_select = this;
78
+ this.last_click_at = 0;
79
+ // initialize the date control
80
+ this.options = $H({
81
+ embedded: false,
82
+ popup: nil,
83
+ time: false,
84
+ buttons: true,
85
+ clear_button: true,
86
+ year_range: 10,
87
+ close_on_click: nil,
88
+ minute_interval: 5,
89
+ popup_by: this.target_element,
90
+ month_year: "dropdowns",
91
+ onchange: function(target_element)
92
+ { return function()
93
+ { if(target_element.dispatchEvent)
94
+ { var event=document.createEvent('HTMLEvents');
95
+ event.initEvent('change', true, true);
96
+ target_element.dispatchEvent(event);
97
+ }
98
+ else
99
+ { var event=document.createEventObject();
100
+ event.type='onChange';
101
+ target_element.fireEvent('onChange', event);
102
+ }
103
+ };
104
+ }(this.target_element),
105
+ valid_date_check: nil
106
+ }).merge(options || {});
107
+ this.use_time = this.options.get("time");
108
+ this.parseDate();
109
+ this.callback("before_show")
110
+ this.initCalendarDiv();
111
+ if(!this.options.get("embedded")) {
112
+ this.positionCalendarDiv()
113
+ // set the click handler to check if a user has clicked away from the document
114
+ Event.observe(document, "mousedown", this.closeIfClickedOut_handler = this.closeIfClickedOut.bindAsEventListener(this));
115
+ Event.observe(document, "keypress", this.keyPress_handler = this.keyPress.bindAsEventListener(this));
116
+ }
117
+ this.callback("after_show")
118
+ },
119
+ positionCalendarDiv: function() {
120
+ var above = false;
121
+ var c_pos = this.calendar_div.cumulativeOffset(), c_left = c_pos[0], c_top = c_pos[1], c_dim = this.calendar_div.getDimensions(), c_height = c_dim.height, c_width = c_dim.width;
122
+ var w_top = window.f_scrollTop(), w_height = window.f_height();
123
+ var e_dim = $(this.options.get("popup_by")).cumulativeOffset(), e_top = e_dim[1], e_left = e_dim[0], e_height = $(this.options.get("popup_by")).getDimensions().height, e_bottom = e_top + e_height;
124
+
125
+ if ( (( e_bottom + c_height ) > (w_top + w_height)) && ( e_bottom - c_height > w_top )) above = true;
126
+ var left_px = e_left.toString() + "px", top_px = (above ? (e_top - c_height ) : ( e_top + e_height )).toString() + "px";
127
+
128
+ this.calendar_div.style.left = left_px; this.calendar_div.style.top = top_px;
129
+
130
+ this.calendar_div.setStyle({visibility:""});
131
+
132
+ // draw an iframe behind the calendar -- ugly hack to make IE 6 happy
133
+ if(navigator.appName=="Microsoft Internet Explorer") this.iframe = $(document.body).build("iframe", {src: "javascript:false", className: "ie6_blocker"}, { left: left_px, top: top_px, height: c_height.toString()+"px", width: c_width.toString()+"px", border: "0px"})
134
+ },
135
+ initCalendarDiv: function() {
136
+ if (this.options.get("embedded")) {
137
+ var parent = this.target_element.parentNode;
138
+ var style = {}
139
+ } else {
140
+ var parent = document.body
141
+ var style = { position:"absolute", visibility: "hidden", left:0, top:0 }
142
+ }
143
+ this.calendar_div = $(parent).build('div', {className: "calendar_date_select"}, style);
144
+
145
+ var that = this;
146
+ // create the divs
147
+ $w("top header body buttons footer bottom").each(function(name) {
148
+ eval("var " + name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: 'cds_"+name+"' }, { clear: 'left'} ); ");
149
+ });
150
+
151
+ this.initHeaderDiv();
152
+ this.initButtonsDiv();
153
+ this.initCalendarGrid();
154
+ this.updateFooter("&#160;");
155
+
156
+ this.refresh();
157
+ this.setUseTime(this.use_time);
158
+ },
159
+ initHeaderDiv: function() {
160
+ var header_div = this.header_div;
161
+ this.close_button = header_div.build("a", { innerHTML: "x", href:"#", onclick:function () { this.close(); return false; }.bindAsEventListener(this), className: "close" });
162
+ this.next_month_button = header_div.build("a", { innerHTML: "&gt;", href:"#", onclick:function () { this.navMonth(this.date.getMonth() + 1 ); return false; }.bindAsEventListener(this), className: "next" });
163
+ this.prev_month_button = header_div.build("a", { innerHTML: "&lt;", href:"#", onclick:function () { this.navMonth(this.date.getMonth() - 1 ); return false; }.bindAsEventListener(this), className: "prev" });
164
+
165
+ if (this.options.get("month_year")=="dropdowns") {
166
+ this.month_select = new SelectBox(header_div, $R(0,11).map(function(m){return [Date.months[m], m]}), {className: "month", onchange: function () { this.navMonth(this.month_select.getValue()) }.bindAsEventListener(this)});
167
+ this.year_select = new SelectBox(header_div, [], {className: "year", onchange: function () { this.navYear(this.year_select.getValue()) }.bindAsEventListener(this)});
168
+ this.populateYearRange();
169
+ } else {
170
+ this.month_year_label = header_div.build("span")
171
+ }
172
+ },
173
+ initCalendarGrid: function() {
174
+ var body_div = this.body_div;
175
+ this.calendar_day_grid = [];
176
+ var days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" })
177
+ // make the weekdays!
178
+ var weekdays_row = days_table.build("thead").build("tr");
179
+ Date.weekdays.each( function(weekday) {
180
+ weekdays_row.build("th", {innerHTML: weekday});
181
+ });
182
+
183
+ var days_tbody = days_table.build("tbody")
184
+ // Make the days!
185
+ var row_number = 0, weekday;
186
+ for(var cell_index = 0; cell_index<42; cell_index++)
187
+ {
188
+ weekday = (cell_index+Date.first_day_of_week ) % 7;
189
+ if ( cell_index % 7==0 ) days_row = days_tbody.build("tr", {className: 'row_'+row_number++});
190
+ (this.calendar_day_grid[cell_index] = days_row.build("td", {
191
+ calendar_date_select: this,
192
+ onmouseover: function () { this.calendar_date_select.dayHover(this); },
193
+ onmouseout: function () { this.calendar_date_select.dayHoverOut(this) },
194
+ onclick: function() { this.calendar_date_select.updateSelectedDate(this, true); },
195
+ className: (weekday==0) || (weekday==6) ? " weekend" : "" //clear the class
196
+ },
197
+ { cursor: "pointer" }
198
+ )).build("div");
199
+ this.calendar_day_grid[cell_index];
200
+ }
201
+ },
202
+ initButtonsDiv: function()
203
+ {
204
+ var buttons_div = this.buttons_div;
205
+ if (this.options.get("time"))
206
+ {
207
+ var blank_time = $A(this.options.get("time")=="mixed" ? [[" - ", ""]] : []);
208
+ buttons_div.build("span", {innerHTML:"@", className: "at_sign"});
209
+
210
+ var t = new Date();
211
+ this.hour_select = new SelectBox(buttons_div,
212
+ blank_time.concat($R(0,23).map(function(x) {t.setHours(x); return $A([t.getAMPMHour()+ " " + t.getAMPM(),x])} )),
213
+ {
214
+ calendar_date_select: this,
215
+ onchange: function() { this.calendar_date_select.updateSelectedDate( { hour: this.value });},
216
+ className: "hour"
217
+ }
218
+ );
219
+ buttons_div.build("span", {innerHTML:":", className: "seperator"});
220
+ var that = this;
221
+ this.minute_select = new SelectBox(buttons_div,
222
+ blank_time.concat($R(0,59).select(function(x){return (x % that.options.get('minute_interval')==0)}).map(function(x){ return $A([ Date.padded2(x), x]); } ) ),
223
+ {
224
+ calendar_date_select: this,
225
+ onchange: function() { this.calendar_date_select.updateSelectedDate( {minute: this.value }) },
226
+ className: "minute"
227
+ }
228
+ );
229
+
230
+ } else if (! this.options.get("buttons")) buttons_div.remove();
231
+
232
+ if (this.options.get("buttons")) {
233
+ buttons_div.build("span", {innerHTML: "&#160;"});
234
+ if (this.options.get("time")=="mixed" || !this.options.get("time")) b = buttons_div.build("a", {
235
+ innerHTML: _translations["Today"],
236
+ href: "#",
237
+ onclick: function() {this.today(false); return false;}.bindAsEventListener(this)
238
+ });
239
+
240
+ if (this.options.get("time")=="mixed") buttons_div.build("span", {innerHTML: "&#160;|&#160;", className:"button_seperator"})
241
+
242
+ if (this.options.get("time")) b = buttons_div.build("a", {
243
+ innerHTML: _translations["Now"],
244
+ href: "#",
245
+ onclick: function() {this.today(true); return false}.bindAsEventListener(this)
246
+ });
247
+
248
+ if (!this.options.get("embedded") && !this.closeOnClick())
249
+ {
250
+ buttons_div.build("span", {innerHTML: "&#160;|&#160;", className:"button_seperator"})
251
+ buttons_div.build("a", { innerHTML: _translations["OK"], href: "#", onclick: function() {this.close(); return false;}.bindAsEventListener(this) });
252
+ }
253
+ if (this.options.get('clear_button')) {
254
+ buttons_div.build("span", {innerHTML: "&#160;|&#160;", className:"button_seperator"})
255
+ buttons_div.build("a", { innerHTML: _translations["Clear"], href: "#", onclick: function() {this.clearDate(); if (!this.options.get("embedded")) this.close(); return false;}.bindAsEventListener(this) });
256
+ }
257
+ }
258
+ },
259
+ refresh: function ()
260
+ {
261
+ this.refreshMonthYear();
262
+ this.refreshCalendarGrid();
263
+
264
+ this.setSelectedClass();
265
+ this.updateFooter();
266
+ },
267
+ refreshCalendarGrid: function () {
268
+ this.beginning_date = new Date(this.date).stripTime();
269
+ this.beginning_date.setDate(1);
270
+ this.beginning_date.setHours(12); // Prevent daylight savings time boundaries from showing a duplicate day
271
+ var pre_days = this.beginning_date.getDay() // draw some days before the fact
272
+ if (pre_days < 3) pre_days += 7;
273
+ this.beginning_date.setDate(1 - pre_days + Date.first_day_of_week);
274
+
275
+ var iterator = new Date(this.beginning_date);
276
+
277
+ var today = new Date().stripTime();
278
+ var this_month = this.date.getMonth();
279
+ vdc = this.options.get("valid_date_check");
280
+ for (var cell_index = 0;cell_index<42; cell_index++)
281
+ {
282
+ day = iterator.getDate(); month = iterator.getMonth();
283
+ cell = this.calendar_day_grid[cell_index];
284
+ Element.remove(cell.childNodes[0]); div = cell.build("div", {innerHTML:day});
285
+ if (month!=this_month) div.className = "other";
286
+ cell.day = day; cell.month = month; cell.year = iterator.getFullYear();
287
+ if (vdc) { if (vdc(iterator.stripTime())) cell.removeClassName("disabled"); else cell.addClassName("disabled") };
288
+ iterator.setDate( day + 1);
289
+ }
290
+
291
+ if (this.today_cell) this.today_cell.removeClassName("today");
292
+
293
+ if ( $R( 0, 41 ).include(days_until = this.beginning_date.stripTime().daysDistance(today)) ) {
294
+ this.today_cell = this.calendar_day_grid[days_until];
295
+ this.today_cell.addClassName("today");
296
+ }
297
+ },
298
+ refreshMonthYear: function() {
299
+ var m = this.date.getMonth();
300
+ var y = this.date.getFullYear();
301
+ // set the month
302
+ if (this.options.get("month_year") == "dropdowns")
303
+ {
304
+ this.month_select.setValue(m, false);
305
+
306
+ var e = this.year_select.element;
307
+ if (this.flexibleYearRange() && (!(this.year_select.setValue(y, false)) || e.selectedIndex <= 1 || e.selectedIndex >= e.options.length - 2 )) this.populateYearRange();
308
+
309
+ this.year_select.setValue(y);
310
+
311
+ } else {
312
+ this.month_year_label.update().insert(Date.months[m] + " " + y.toString());
313
+ }
314
+ },
315
+ populateYearRange: function() {
316
+ this.year_select.populate(this.yearRange().toArray());
317
+ },
318
+ yearRange: function() {
319
+ if (!this.flexibleYearRange())
320
+ return $R(this.options.get("year_range")[0], this.options.get("year_range")[1]);
321
+
322
+ var y = this.date.getFullYear();
323
+ return $R(y - this.options.get("year_range"), y + this.options.get("year_range"));
324
+ },
325
+ flexibleYearRange: function() { return (typeof(this.options.get("year_range")) == "number"); },
326
+ validYear: function(year) { if (this.flexibleYearRange()) { return true;} else { return this.yearRange().include(year);} },
327
+ dayHover: function(element) {
328
+ var hover_date = new Date(this.selected_date);
329
+ hover_date.setFullYear(element.year, element.month, element.day);
330
+ this.updateFooter(hover_date.toFormattedString(this.use_time));
331
+ },
332
+ dayHoverOut: function(element) { this.updateFooter(); },
333
+ clearSelectedClass: function() {if (this.selected_cell) this.selected_cell.removeClassName("selected");},
334
+ setSelectedClass: function() {
335
+ if (!this.selection_made) return;
336
+ this.clearSelectedClass()
337
+ if ($R(0,42).include( days_until = this.beginning_date.stripTime().daysDistance(this.selected_date.stripTime()) )) {
338
+ this.selected_cell = this.calendar_day_grid[days_until];
339
+ this.selected_cell.addClassName("selected");
340
+ }
341
+ },
342
+ reparse: function() { this.parseDate(); this.refresh(); },
343
+ dateString: function() {
344
+ return (this.selection_made) ? this.selected_date.toFormattedString(this.use_time) : "&#160;";
345
+ },
346
+ parseDate: function()
347
+ {
348
+ var value = $F(this.target_element).strip()
349
+ var default_time = this.options.get("default_time");
350
+ this.selection_made = (value != "" || default_time);
351
+ this.date = value=="" ? NaN : Date.parseFormattedString(this.options.get("date") || value);
352
+ if (isNaN(this.date) && !default_time)
353
+ this.date = new Date();
354
+ else if (isNaN(this.date) && default_time)
355
+ this.date = (Object.prototype.toString.apply(default_time) === '[object Function]') ? default_time() : default_time;
356
+
357
+ if (!this.validYear(this.date.getFullYear())) this.date.setYear( (this.date.getFullYear() < this.yearRange().start) ? this.yearRange().start : this.yearRange().end);
358
+ this.selected_date = new Date(this.date);
359
+ this.use_time = /[0-9]:[0-9]{2}/.exec(value) ? true : false;
360
+ this.date.setDate(1);
361
+ },
362
+ updateFooter:function(text) { if (!text) text = this.dateString(); this.footer_div.purgeChildren(); this.footer_div.build("span", {innerHTML: text }); },
363
+ clearDate:function() {
364
+ if ((this.target_element.disabled || this.target_element.readOnly) && this.options.get("popup") != "force") return false;
365
+ var last_value = this.target_element.value;
366
+ this.target_element.value = "";
367
+ this.clearSelectedClass();
368
+ this.updateFooter('&#160;');
369
+ if (last_value!=this.target_element.value) this.callback("onchange");
370
+ },
371
+ updateSelectedDate:function(partsOrElement, via_click) {
372
+ var parts = $H(partsOrElement);
373
+ if ((this.target_element.disabled || this.target_element.readOnly) && this.options.get("popup") != "force") return false;
374
+ if (parts.get("day")) {
375
+ var t_selected_date = this.selected_date, vdc = this.options.get("valid_date_check");
376
+ t_selected_date.setFullYear(parts.get("year"), parts.get("month"), parts.get("day"));
377
+
378
+ if (vdc && ! vdc(t_selected_date.stripTime())) { return false; }
379
+ this.selected_date = t_selected_date;
380
+ this.selection_made = true;
381
+ }
382
+
383
+ if (!isNaN(parts.get("hour"))) this.selected_date.setHours(parts.get("hour"));
384
+ if (!isNaN(parts.get("minute"))) this.selected_date.setMinutes( Math.floor_to_interval(parts.get("minute"), this.options.get("minute_interval")) );
385
+ if (parts.get("hour") === "" || parts.get("minute") === "")
386
+ this.setUseTime(false);
387
+ else if (!isNaN(parts.get("hour")) || !isNaN(parts.get("minute")))
388
+ this.setUseTime(true);
389
+
390
+ this.updateFooter();
391
+ this.setSelectedClass();
392
+
393
+ if (this.selection_made) this.updateValue();
394
+ if (this.closeOnClick()) { this.close(); }
395
+ if (via_click && !this.options.get("embedded")) {
396
+ if ((new Date() - this.last_click_at) < 333) this.close();
397
+ this.last_click_at = new Date();
398
+ }
399
+ },
400
+ closeOnClick: function() {
401
+ if (this.options.get("embedded")) return false;
402
+ if (this.options.get("close_on_click")===nil )
403
+ return (this.options.get("time")) ? false : true
404
+ else
405
+ return (this.options.get("close_on_click"))
406
+ },
407
+ navMonth: function(month) { (target_date = new Date(this.date)).setMonth(month); return (this.navTo(target_date)); },
408
+ navYear: function(year) { (target_date = new Date(this.date)).setYear(year); return (this.navTo(target_date)); },
409
+ navTo: function(date) {
410
+ if (!this.validYear(date.getFullYear())) return false;
411
+ this.date = date;
412
+ this.date.setDate(1);
413
+ this.refresh();
414
+ this.callback("after_navigate", this.date);
415
+ return true;
416
+ },
417
+ setUseTime: function(turn_on) {
418
+ this.use_time = this.options.get("time") && (this.options.get("time")=="mixed" ? turn_on : true) // force use_time to true if time==true && time!="mixed"
419
+ if (this.use_time && this.selected_date) { // only set hour/minute if a date is already selected
420
+ var minute = Math.floor_to_interval(this.selected_date.getMinutes(), this.options.get("minute_interval"));
421
+ var hour = this.selected_date.getHours();
422
+
423
+ this.hour_select.setValue(hour);
424
+ this.minute_select.setValue(minute)
425
+ } else if (this.options.get("time")=="mixed") {
426
+ this.hour_select.setValue(""); this.minute_select.setValue("");
427
+ }
428
+ },
429
+ updateValue: function() {
430
+ var last_value = this.target_element.value;
431
+ this.target_element.value = this.dateString();
432
+ if (last_value!=this.target_element.value) this.callback("onchange");
433
+ },
434
+ today: function(now) {
435
+ var d = new Date(); this.date = new Date();
436
+ var o = $H({ day: d.getDate(), month: d.getMonth(), year: d.getFullYear(), hour: d.getHours(), minute: d.getMinutes()});
437
+ if ( ! now ) o = o.merge({hour: "", minute:""});
438
+ this.updateSelectedDate(o, true);
439
+ this.refresh();
440
+ },
441
+ close: function() {
442
+ if (this.closed) return false;
443
+ this.callback("before_close");
444
+ this.target_element.calendar_date_select = nil;
445
+ Event.stopObserving(document, "mousedown", this.closeIfClickedOut_handler);
446
+ Event.stopObserving(document, "keypress", this.keyPress_handler);
447
+ this.calendar_div.remove(); this.closed = true;
448
+ if (this.iframe) this.iframe.remove();
449
+ if (this.target_element.type != "hidden" && ! this.target_element.disabled) this.target_element.focus();
450
+ this.callback("after_close");
451
+ },
452
+ closeIfClickedOut: function(e) {
453
+ if (! $(Event.element(e)).descendantOf(this.calendar_div) ) this.close();
454
+ },
455
+ keyPress: function(e) {
456
+ if (e.keyCode==Event.KEY_ESC) this.close();
457
+ },
458
+ callback: function(name, param) { if (this.options.get(name)) { this.options.get(name).bind(this.target_element)(param); } }
459
+ }