rademade_admin 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.eot +0 -0
  5. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.svg +228 -0
  6. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.ttf +0 -0
  7. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.woff +0 -0
  8. data/app/assets/images/rademade_admin/backgrounds/back-blue.jpg +0 -0
  9. data/app/assets/images/rademade_admin/backgrounds/back-green.jpg +0 -0
  10. data/app/assets/images/rademade_admin/backgrounds/back-orange.png +0 -0
  11. data/app/assets/images/rademade_admin/backgrounds/blueish.jpg +0 -0
  12. data/app/assets/images/rademade_admin/backgrounds/select-bg.png +0 -0
  13. data/app/assets/images/rademade_admin/datatables/back_disabled.png +0 -0
  14. data/app/assets/images/rademade_admin/datatables/back_enabled.png +0 -0
  15. data/app/assets/images/rademade_admin/datatables/back_enabled_hover.png +0 -0
  16. data/app/assets/images/rademade_admin/datatables/forward_disabled.png +0 -0
  17. data/app/assets/images/rademade_admin/datatables/forward_enabled.png +0 -0
  18. data/app/assets/images/rademade_admin/datatables/forward_enabled_hover.png +0 -0
  19. data/app/assets/images/rademade_admin/datatables/sort_asc.png +0 -0
  20. data/app/assets/images/rademade_admin/datatables/sort_asc_disabled.png +0 -0
  21. data/app/assets/images/rademade_admin/datatables/sort_both.png +0 -0
  22. data/app/assets/images/rademade_admin/datatables/sort_desc.png +0 -0
  23. data/app/assets/images/rademade_admin/datatables/sort_desc_disabled.png +0 -0
  24. data/app/assets/images/rademade_admin/icons/btn-attach.png +0 -0
  25. data/app/assets/images/rademade_admin/icons/btn-setting.png +0 -0
  26. data/app/assets/images/rademade_admin/icons/btn-shuffle.png +0 -0
  27. data/app/assets/images/rademade_admin/icons/btn-tool.png +0 -0
  28. data/app/assets/images/rademade_admin/icons/buble.png +0 -0
  29. data/app/assets/images/rademade_admin/icons/glyphicons-halflings-white.png +0 -0
  30. data/app/assets/images/rademade_admin/icons/glyphicons-halflings.png +0 -0
  31. data/app/assets/images/rademade_admin/icons/ico-arrow-black.png +0 -0
  32. data/app/assets/images/rademade_admin/icons/ico-gallery-edit.png +0 -0
  33. data/app/assets/images/rademade_admin/icons/ico-gallery-trash.png +0 -0
  34. data/app/assets/images/rademade_admin/icons/ico-mail.png +0 -0
  35. data/app/assets/images/rademade_admin/icons/ico-phone.png +0 -0
  36. data/app/assets/images/rademade_admin/icons/ico-table-delete.png +0 -0
  37. data/app/assets/images/rademade_admin/icons/ico-table-edit.png +0 -0
  38. data/app/assets/images/rademade_admin/icons/ico-table-new.png +0 -0
  39. data/app/assets/images/rademade_admin/icons/lens.png +0 -0
  40. data/app/assets/images/rademade_admin/icons/skin-nav-bullets.png +0 -0
  41. data/app/assets/images/rademade_admin/icons/table-icons.png +0 -0
  42. data/app/assets/images/rademade_admin/icons/table-img.png +0 -0
  43. data/app/assets/images/rademade_admin/jquery-ui/animated-overlay.gif +0 -0
  44. data/app/assets/images/rademade_admin/jquery-ui/slider-handler.png +0 -0
  45. data/app/assets/images/rademade_admin/jquery-ui/slider-handler2.png +0 -0
  46. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  47. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  48. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  49. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  50. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  51. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  52. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  53. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  54. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  55. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_222222_256x240.png +0 -0
  56. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  57. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  58. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  59. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  60. data/app/assets/images/rademade_admin/logos/logo-white.png +0 -0
  61. data/app/assets/images/rademade_admin/logos/logo.png +0 -0
  62. data/app/assets/images/rademade_admin/notifier-loader-clean.gif +0 -0
  63. data/app/assets/images/rademade_admin/notifier-loader-plastic.gif +0 -0
  64. data/app/assets/images/rademade_admin/placeholders/new-gallery-img.png +0 -0
  65. data/app/assets/images/rademade_admin/placeholders/no-img-gallery.png +0 -0
  66. data/app/assets/images/rademade_admin/select2/select2.png +0 -0
  67. data/app/assets/images/rademade_admin/select2/select2x2.png +0 -0
  68. data/app/assets/images/rademade_admin/select2/spinner.gif +0 -0
  69. data/app/assets/images/rademade_admin/uniform/bg-input-focus.png +0 -0
  70. data/app/assets/images/rademade_admin/uniform/bg-input.png +0 -0
  71. data/app/assets/images/rademade_admin/uniform/sprite.png +0 -0
  72. data/app/assets/javascripts/rademade_admin.coffee +14 -0
  73. data/app/assets/javascripts/rademade_admin/app/app.coffee +1 -0
  74. data/app/assets/javascripts/rademade_admin/app/common/dnd-sort.coffee +42 -0
  75. data/app/assets/javascripts/rademade_admin/app/common/pagination.coffee +6 -0
  76. data/app/assets/javascripts/rademade_admin/app/common/related-index.coffee +54 -0
  77. data/app/assets/javascripts/rademade_admin/app/common/relation-list.coffee +109 -0
  78. data/app/assets/javascripts/rademade_admin/app/common/sort-list.coffee +47 -0
  79. data/app/assets/javascripts/rademade_admin/app/common/uploader.coffee +53 -0
  80. data/app/assets/javascripts/rademade_admin/app/form-popup/collection.coffee +20 -0
  81. data/app/assets/javascripts/rademade_admin/app/form-popup/initializer.coffee +43 -0
  82. data/app/assets/javascripts/rademade_admin/app/form-popup/model.coffee +4 -0
  83. data/app/assets/javascripts/rademade_admin/app/form-popup/view.coffee +57 -0
  84. data/app/assets/javascripts/rademade_admin/app/forms/insert.coffee +7 -0
  85. data/app/assets/javascripts/rademade_admin/app/forms/login.coffee +4 -0
  86. data/app/assets/javascripts/rademade_admin/app/forms/remove.coffee +6 -0
  87. data/app/assets/javascripts/rademade_admin/app/notifier/initialize.js +31 -0
  88. data/app/assets/javascripts/rademade_admin/detail_admin/theme.js +56 -0
  89. data/app/assets/javascripts/rademade_admin/form/form-ajax-submit.coffee +153 -0
  90. data/app/assets/javascripts/rademade_admin/form/library/jquery.form-serialize.js +54 -0
  91. data/app/assets/javascripts/rademade_admin/form/library/jquery.form.js +1121 -0
  92. data/app/assets/javascripts/rademade_admin/form/library/jquery.formrestrict.js +27 -0
  93. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.js +1231 -0
  94. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.messages_ru.js +27 -0
  95. data/app/assets/javascripts/rademade_admin/library/backbone.js +1581 -0
  96. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.datepicker.js +989 -0
  97. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.js +1992 -0
  98. data/app/assets/javascripts/rademade_admin/library/ckeditor/config.js +12 -0
  99. data/app/assets/javascripts/rademade_admin/library/jquery/jquery-ui-1.10.4.custom.min.js +6 -0
  100. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.dataTables.js +12099 -0
  101. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.js +2960 -0
  102. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.resize.js +60 -0
  103. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.stack.js +188 -0
  104. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.knob.js +661 -0
  105. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.tablednd.js +1 -0
  106. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.uniform.min.js +1 -0
  107. data/app/assets/javascripts/rademade_admin/library/notifier.custom.js +431 -0
  108. data/app/assets/javascripts/rademade_admin/library/notifier.custom.min.js +15 -0
  109. data/app/assets/javascripts/rademade_admin/library/underscore.js +1276 -0
  110. data/app/assets/javascripts/rademade_admin/library/wysihtml5-0.3.0.js +9463 -0
  111. data/app/assets/stylesheets/rademade_admin.css +14 -0
  112. data/app/assets/stylesheets/rademade_admin/base.scss.erb +23 -0
  113. data/app/assets/stylesheets/rademade_admin/bootstrap/bootstrap-overrides.css.erb +341 -0
  114. data/app/assets/stylesheets/rademade_admin/bootstrap/bootstrap.css.erb +5911 -0
  115. data/app/assets/stylesheets/rademade_admin/bootstrap/main.scss.erb +78 -0
  116. data/app/assets/stylesheets/rademade_admin/detail_admin/chart-showcase.scss.erb +33 -0
  117. data/app/assets/stylesheets/rademade_admin/detail_admin/datatables.scss.erb +3 -0
  118. data/app/assets/stylesheets/rademade_admin/detail_admin/elements.scss.erb +665 -0
  119. data/app/assets/stylesheets/rademade_admin/detail_admin/error.scss.erb +19 -0
  120. data/app/assets/stylesheets/rademade_admin/detail_admin/form-showcase.scss.erb +87 -0
  121. data/app/assets/stylesheets/rademade_admin/detail_admin/form-wizard.scss.erb +261 -0
  122. data/app/assets/stylesheets/rademade_admin/detail_admin/gallery.scss.erb +106 -0
  123. data/app/assets/stylesheets/rademade_admin/detail_admin/grids.scss.erb +21 -0
  124. data/app/assets/stylesheets/rademade_admin/detail_admin/icons.scss.erb +115 -0
  125. data/app/assets/stylesheets/rademade_admin/detail_admin/index.scss.erb +290 -0
  126. data/app/assets/stylesheets/rademade_admin/detail_admin/layout.scss.erb +523 -0
  127. data/app/assets/stylesheets/rademade_admin/detail_admin/new-user.scss.erb +49 -0
  128. data/app/assets/stylesheets/rademade_admin/detail_admin/personal-info.scss.erb +144 -0
  129. data/app/assets/stylesheets/rademade_admin/detail_admin/popup.scss.erb +3 -0
  130. data/app/assets/stylesheets/rademade_admin/detail_admin/signin.scss.erb +128 -0
  131. data/app/assets/stylesheets/rademade_admin/detail_admin/tables.scss.erb +195 -0
  132. data/app/assets/stylesheets/rademade_admin/detail_admin/ui-elements.scss.erb +177 -0
  133. data/app/assets/stylesheets/rademade_admin/detail_admin/user-list.scss.erb +112 -0
  134. data/app/assets/stylesheets/rademade_admin/detail_admin/user-profile.scss.erb +169 -0
  135. data/app/assets/stylesheets/rademade_admin/detail_admin/web-app-icons.scss.erb +25 -0
  136. data/app/assets/stylesheets/rademade_admin/edit.css +7 -0
  137. data/app/assets/stylesheets/rademade_admin/file-upload.scss.erb +12 -0
  138. data/app/assets/stylesheets/rademade_admin/lib/bootstrap.datepicker.css.erb +302 -0
  139. data/app/assets/stylesheets/rademade_admin/lib/jquery-ui-1.10.2.custom.css.erb +544 -0
  140. data/app/assets/stylesheets/rademade_admin/lib/morris.css.erb +2 -0
  141. data/app/assets/stylesheets/rademade_admin/lib/select2.css.erb +513 -0
  142. data/app/assets/stylesheets/rademade_admin/lib/uniform.default.css.erb +366 -0
  143. data/app/assets/stylesheets/rademade_admin/notifier.custom.css.erb +661 -0
  144. data/app/assets/stylesheets/rademade_admin/scaffolds.scss.erb +32 -0
  145. data/app/controllers/rademade_admin/abstract_controller.rb +24 -0
  146. data/app/controllers/rademade_admin/admin_users_controller.rb +16 -0
  147. data/app/controllers/rademade_admin/application_controller.rb +7 -0
  148. data/app/controllers/rademade_admin/dashboard_controller.rb +16 -0
  149. data/app/controllers/rademade_admin/model_controller.rb +122 -0
  150. data/app/controllers/rademade_admin/sessions_controller.rb +22 -0
  151. data/app/helpers/rademade_admin/field_helper.rb +27 -0
  152. data/app/helpers/rademade_admin/form_helper.rb +63 -0
  153. data/app/helpers/rademade_admin/menu_helper.rb +45 -0
  154. data/app/helpers/rademade_admin/name_helper.rb +17 -0
  155. data/app/helpers/rademade_admin/upload_preview_helper.rb +59 -0
  156. data/app/helpers/rademade_admin/uri_helper.rb +104 -0
  157. data/app/inputs/rademade_admin/admin_file_input.rb +70 -0
  158. data/app/inputs/rademade_admin/admin_select_input.rb +81 -0
  159. data/app/inputs/rademade_admin/admin_textarea_input.rb +5 -0
  160. data/app/inputs/rademade_admin/boolean_input.rb +13 -0
  161. data/app/models/rademade_admin/ability.rb +39 -0
  162. data/app/models/rademade_admin/user.rb +6 -0
  163. data/app/serializers/autocomplete_serializer.rb +46 -0
  164. data/app/services/form_builder.rb +3 -0
  165. data/app/services/loader_service.rb +7 -0
  166. data/app/services/login.rb +18 -0
  167. data/app/services/login/error.rb +17 -0
  168. data/app/services/model_controller/instance_options.rb +38 -0
  169. data/app/services/model_controller/linker.rb +49 -0
  170. data/app/services/model_controller/model_options.rb +39 -0
  171. data/app/services/model_controller/notifier.rb +40 -0
  172. data/app/services/model_controller/templates.rb +27 -0
  173. data/app/services/saver.rb +69 -0
  174. data/app/services/search/conditions/abstract.rb +53 -0
  175. data/app/services/search/conditions/autocomplete.rb +44 -0
  176. data/app/services/search/conditions/list.rb +35 -0
  177. data/app/services/search/query_adapter/abstract.rb +54 -0
  178. data/app/services/search/query_adapter/active_record.rb +33 -0
  179. data/app/services/search/query_adapter/mongoid.rb +33 -0
  180. data/app/services/search/searcher.rb +19 -0
  181. data/app/services/sortable_service.rb +37 -0
  182. data/app/services/video_service.rb +22 -0
  183. data/app/views/layouts/rademade_admin.html.erb +13 -0
  184. data/app/views/rademade_admin/_blocks/_form_control.html.erb +5 -0
  185. data/app/views/rademade_admin/_blocks/_header.html.erb +30 -0
  186. data/app/views/rademade_admin/_blocks/_menu.html.erb +41 -0
  187. data/app/views/rademade_admin/_blocks/_pagination.html.erb +18 -0
  188. data/app/views/rademade_admin/_blocks/_sub_menu.html.erb +19 -0
  189. data/app/views/rademade_admin/_blocks/sub_menu/_link.html.erb +5 -0
  190. data/app/views/rademade_admin/_layouts/inner.html.erb +37 -0
  191. data/app/views/rademade_admin/_layouts/inner/form.html.erb +15 -0
  192. data/app/views/rademade_admin/_layouts/inner/index_table.html.erb +59 -0
  193. data/app/views/rademade_admin/_layouts/inner/related_index_table.html.erb +55 -0
  194. data/app/views/rademade_admin/abstract/_form.html.erb +10 -0
  195. data/app/views/rademade_admin/abstract/edit.html.erb +9 -0
  196. data/app/views/rademade_admin/abstract/form.html.erb +1 -0
  197. data/app/views/rademade_admin/abstract/index.html.erb +77 -0
  198. data/app/views/rademade_admin/abstract/new.html.erb +9 -0
  199. data/app/views/rademade_admin/abstract/related_index.html.erb +78 -0
  200. data/app/views/rademade_admin/dashboard/index.html.erb +9 -0
  201. data/app/views/rademade_admin/dashboard/login.html.erb +31 -0
  202. data/config/initializers/devise.rb +250 -0
  203. data/config/initializers/routes.rb +3 -0
  204. data/config/locales/devise.en.yml +59 -0
  205. data/config/routes.rb +17 -0
  206. data/lib/rademade_admin.rb +26 -0
  207. data/lib/rademade_admin/configuration.rb +17 -0
  208. data/lib/rademade_admin/engine.rb +22 -0
  209. data/lib/rademade_admin/file_info_formatter.rb +12 -0
  210. data/lib/rademade_admin/hrml_buffer.rb +14 -0
  211. data/lib/rademade_admin/model/configuration.rb +52 -0
  212. data/lib/rademade_admin/model/configuration/fields.rb +33 -0
  213. data/lib/rademade_admin/model/data_adapter.rb +59 -0
  214. data/lib/rademade_admin/model/data_adapter/active_record.rb +53 -0
  215. data/lib/rademade_admin/model/data_adapter/mongoid.rb +49 -0
  216. data/lib/rademade_admin/model/graph.rb +36 -0
  217. data/lib/rademade_admin/model/info.rb +106 -0
  218. data/lib/rademade_admin/model/reflection.rb +31 -0
  219. data/lib/rademade_admin/model/reflection/data.rb +47 -0
  220. data/lib/rademade_admin/model/reflection/uploader.rb +18 -0
  221. data/lib/rademade_admin/routing.rb +3 -0
  222. data/lib/rademade_admin/routing/mapper.rb +42 -0
  223. data/lib/rademade_admin/routing/resource.rb +6 -0
  224. data/lib/rademade_admin/sortable.rb +12 -0
  225. data/lib/rademade_admin/uploader/photo.rb +13 -0
  226. data/lib/rademade_admin/uploader/video.rb +11 -0
  227. data/lib/rademade_admin/user.rb +16 -0
  228. data/lib/rademade_admin/version.rb +3 -0
  229. data/lib/tasks/rademade_admin_tasks.rake +4 -0
  230. data/test/dummy/README.rdoc +28 -0
  231. data/test/dummy/Rakefile +6 -0
  232. data/test/dummy/app/assets/javascripts/application.js +13 -0
  233. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  234. data/test/dummy/app/controllers/application_controller.rb +5 -0
  235. data/test/dummy/app/controllers/rademade_admin/posts_controller.rb +9 -0
  236. data/test/dummy/app/controllers/rademade_admin/users_controller.rb +14 -0
  237. data/test/dummy/app/helpers/application_helper.rb +2 -0
  238. data/test/dummy/app/models/post.rb +9 -0
  239. data/test/dummy/app/models/user.rb +7 -0
  240. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  241. data/test/dummy/bin/bundle +3 -0
  242. data/test/dummy/bin/rails +4 -0
  243. data/test/dummy/bin/rake +4 -0
  244. data/test/dummy/config.ru +4 -0
  245. data/test/dummy/config/application.rb +29 -0
  246. data/test/dummy/config/boot.rb +5 -0
  247. data/test/dummy/config/environment.rb +5 -0
  248. data/test/dummy/config/environments/development.rb +29 -0
  249. data/test/dummy/config/environments/production.rb +80 -0
  250. data/test/dummy/config/environments/test.rb +36 -0
  251. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  252. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  253. data/test/dummy/config/initializers/inflections.rb +16 -0
  254. data/test/dummy/config/initializers/mime_types.rb +5 -0
  255. data/test/dummy/config/initializers/rademade_admin.rb +3 -0
  256. data/test/dummy/config/initializers/secret_token.rb +12 -0
  257. data/test/dummy/config/initializers/session_store.rb +3 -0
  258. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  259. data/test/dummy/config/locales/en.yml +23 -0
  260. data/test/dummy/config/mongoid.yml +6 -0
  261. data/test/dummy/config/routes.rb +8 -0
  262. data/test/dummy/db/development.sqlite3 +0 -0
  263. data/test/dummy/public/404.html +58 -0
  264. data/test/dummy/public/422.html +58 -0
  265. data/test/dummy/public/500.html +57 -0
  266. data/test/dummy/public/favicon.ico +0 -0
  267. data/test/integration/navigation_test.rb +10 -0
  268. data/test/rademade_admin_test.rb +7 -0
  269. data/test/test_helper.rb +15 -0
  270. metadata +691 -0
@@ -0,0 +1,989 @@
1
+ /* =========================================================
2
+ * bootstrap-datepicker.js
3
+ * http://www.eyecon.ro/bootstrap-datepicker
4
+ * =========================================================
5
+ * Copyright 2012 Stefan Petre
6
+ * Improvements by Andrew Rowls
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ * ========================================================= */
20
+
21
+ !function( $ ) {
22
+
23
+ function UTCDate(){
24
+ return new Date(Date.UTC.apply(Date, arguments));
25
+ }
26
+ function UTCToday(){
27
+ var today = new Date();
28
+ return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate());
29
+ }
30
+
31
+ // Picker object
32
+
33
+ var Datepicker = function(element, options) {
34
+ var that = this;
35
+
36
+ this.element = $(element);
37
+ this.language = options.language||this.element.data('date-language')||"en";
38
+ this.language = this.language in dates ? this.language : this.language.split('-')[0]; //Check if "de-DE" style date is available, if not language should fallback to 2 letter code eg "de"
39
+ this.language = this.language in dates ? this.language : "en";
40
+ this.isRTL = dates[this.language].rtl||false;
41
+ this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||dates[this.language].format||'mm/dd/yyyy');
42
+ this.isInline = false;
43
+ this.isInput = this.element.is('input');
44
+ this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
45
+ this.hasInput = this.component && this.element.find('input').length;
46
+ if(this.component && this.component.length === 0)
47
+ this.component = false;
48
+
49
+ this._attachEvents();
50
+
51
+ this.forceParse = true;
52
+ if ('forceParse' in options) {
53
+ this.forceParse = options.forceParse;
54
+ } else if ('dateForceParse' in this.element.data()) {
55
+ this.forceParse = this.element.data('date-force-parse');
56
+ }
57
+
58
+
59
+ this.picker = $(DPGlobal.template)
60
+ .appendTo(this.isInline ? this.element : 'body')
61
+ .on({
62
+ click: $.proxy(this.click, this),
63
+ mousedown: $.proxy(this.mousedown, this)
64
+ });
65
+
66
+ if(this.isInline) {
67
+ this.picker.addClass('datepicker-inline');
68
+ } else {
69
+ this.picker.addClass('datepicker-dropdown dropdown-menu');
70
+ }
71
+ if (this.isRTL){
72
+ this.picker.addClass('datepicker-rtl');
73
+ this.picker.find('.prev i, .next i')
74
+ .toggleClass('icon-arrow-left icon-arrow-right');
75
+ }
76
+ $(document).on('mousedown', function (e) {
77
+ // Clicked outside the datepicker, hide it
78
+ if ($(e.target).closest('.datepicker.datepicker-inline, .datepicker.datepicker-dropdown').length === 0) {
79
+ that.hide();
80
+ }
81
+ });
82
+
83
+ this.autoclose = false;
84
+ if ('autoclose' in options) {
85
+ this.autoclose = options.autoclose;
86
+ } else if ('dateAutoclose' in this.element.data()) {
87
+ this.autoclose = this.element.data('date-autoclose');
88
+ }
89
+
90
+ this.keyboardNavigation = true;
91
+ if ('keyboardNavigation' in options) {
92
+ this.keyboardNavigation = options.keyboardNavigation;
93
+ } else if ('dateKeyboardNavigation' in this.element.data()) {
94
+ this.keyboardNavigation = this.element.data('date-keyboard-navigation');
95
+ }
96
+
97
+ this.viewMode = this.startViewMode = 0;
98
+ switch(options.startView || this.element.data('date-start-view')){
99
+ case 2:
100
+ case 'decade':
101
+ this.viewMode = this.startViewMode = 2;
102
+ break;
103
+ case 1:
104
+ case 'year':
105
+ this.viewMode = this.startViewMode = 1;
106
+ break;
107
+ }
108
+
109
+ this.todayBtn = (options.todayBtn||this.element.data('date-today-btn')||false);
110
+ this.todayHighlight = (options.todayHighlight||this.element.data('date-today-highlight')||false);
111
+
112
+ this.calendarWeeks = false;
113
+ if ('calendarWeeks' in options) {
114
+ this.calendarWeeks = options.calendarWeeks;
115
+ } else if ('dateCalendarWeeks' in this.element.data()) {
116
+ this.calendarWeeks = this.element.data('date-calendar-weeks');
117
+ }
118
+ if (this.calendarWeeks)
119
+ this.picker.find('tfoot th.today')
120
+ .attr('colspan', function(i, val){
121
+ return parseInt(val) + 1;
122
+ });
123
+
124
+ this.weekStart = ((options.weekStart||this.element.data('date-weekstart')||dates[this.language].weekStart||0) % 7);
125
+ this.weekEnd = ((this.weekStart + 6) % 7);
126
+ this.startDate = -Infinity;
127
+ this.endDate = Infinity;
128
+ this.daysOfWeekDisabled = [];
129
+ this.setStartDate(options.startDate||this.element.data('date-startdate'));
130
+ this.setEndDate(options.endDate||this.element.data('date-enddate'));
131
+ this.setDaysOfWeekDisabled(options.daysOfWeekDisabled||this.element.data('date-days-of-week-disabled'));
132
+ this.fillDow();
133
+ this.fillMonths();
134
+ this.update();
135
+ this.showMode();
136
+
137
+ if(this.isInline) {
138
+ this.show();
139
+ }
140
+ };
141
+
142
+ Datepicker.prototype = {
143
+ constructor: Datepicker,
144
+
145
+ _events: [],
146
+ _attachEvents: function(){
147
+ this._detachEvents();
148
+ if (this.isInput) { // single input
149
+ this._events = [
150
+ [this.element, {
151
+ // focus: $.proxy(this.show, this),
152
+ keyup: $.proxy(this.update, this),
153
+ keydown: $.proxy(this.keydown, this),
154
+ click: $.proxy(this.show, this)
155
+ }]
156
+ ];
157
+ }
158
+ else if (this.component && this.hasInput){ // component: input + button
159
+ this._events = [
160
+ // For components that are not readonly, allow keyboard nav
161
+ [this.element.find('input'), {
162
+ focus: $.proxy(this.show, this),
163
+ keyup: $.proxy(this.update, this),
164
+ keydown: $.proxy(this.keydown, this)
165
+ }],
166
+ [this.component, {
167
+ click: $.proxy(this.show, this)
168
+ }]
169
+ ];
170
+ }
171
+ else if (this.element.is('div')) { // inline datepicker
172
+ this.isInline = true;
173
+ }
174
+ else {
175
+ this._events = [
176
+ [this.element, {
177
+ click: $.proxy(this.show, this)
178
+ }]
179
+ ];
180
+ }
181
+ for (var i=0, el, ev; i<this._events.length; i++){
182
+ el = this._events[i][0];
183
+ ev = this._events[i][1];
184
+ el.on(ev);
185
+ }
186
+ },
187
+ _detachEvents: function(){
188
+ for (var i=0, el, ev; i<this._events.length; i++){
189
+ el = this._events[i][0];
190
+ ev = this._events[i][1];
191
+ el.off(ev);
192
+ }
193
+ this._events = [];
194
+ },
195
+
196
+ show: function(e) {
197
+ this.picker.show();
198
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
199
+ this.update();
200
+ this.place();
201
+ $(window).on('resize', $.proxy(this.place, this));
202
+ if (e ) {
203
+ e.stopPropagation();
204
+ e.preventDefault();
205
+ }
206
+ this.element.trigger({
207
+ type: 'show',
208
+ date: this.date
209
+ });
210
+ },
211
+
212
+ hide: function(e){
213
+ if(this.isInline) return;
214
+ if (!this.picker.is(':visible')) return;
215
+ this.picker.hide();
216
+ $(window).off('resize', this.place);
217
+ this.viewMode = this.startViewMode;
218
+ this.showMode();
219
+ if (!this.isInput) {
220
+ $(document).off('mousedown', this.hide);
221
+ }
222
+
223
+ if (
224
+ this.forceParse &&
225
+ (
226
+ this.isInput && this.element.val() ||
227
+ this.hasInput && this.element.find('input').val()
228
+ )
229
+ )
230
+ this.setValue();
231
+ this.element.trigger({
232
+ type: 'hide',
233
+ date: this.date
234
+ });
235
+ },
236
+
237
+ remove: function() {
238
+ this._detachEvents();
239
+ this.picker.remove();
240
+ delete this.element.data().datepicker;
241
+ },
242
+
243
+ getDate: function() {
244
+ var d = this.getUTCDate();
245
+ return new Date(d.getTime() + (d.getTimezoneOffset()*60000));
246
+ },
247
+
248
+ getUTCDate: function() {
249
+ return this.date;
250
+ },
251
+
252
+ setDate: function(d) {
253
+ this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset()*60000)));
254
+ },
255
+
256
+ setUTCDate: function(d) {
257
+ this.date = d;
258
+ this.setValue();
259
+ },
260
+
261
+ setValue: function() {
262
+ var formatted = this.getFormattedDate();
263
+ if (!this.isInput) {
264
+ if (this.component){
265
+ this.element.find('input').val(formatted);
266
+ }
267
+ this.element.data('date', formatted);
268
+ } else {
269
+ this.element.val(formatted);
270
+ }
271
+ },
272
+
273
+ getFormattedDate: function(format) {
274
+ if (format === undefined)
275
+ format = this.format;
276
+ return DPGlobal.formatDate(this.date, format, this.language);
277
+ },
278
+
279
+ setStartDate: function(startDate){
280
+ this.startDate = startDate||-Infinity;
281
+ if (this.startDate !== -Infinity) {
282
+ this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language);
283
+ }
284
+ this.update();
285
+ this.updateNavArrows();
286
+ },
287
+
288
+ setEndDate: function(endDate){
289
+ this.endDate = endDate||Infinity;
290
+ if (this.endDate !== Infinity) {
291
+ this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language);
292
+ }
293
+ this.update();
294
+ this.updateNavArrows();
295
+ },
296
+
297
+ setDaysOfWeekDisabled: function(daysOfWeekDisabled){
298
+ this.daysOfWeekDisabled = daysOfWeekDisabled||[];
299
+ if (!$.isArray(this.daysOfWeekDisabled)) {
300
+ this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
301
+ }
302
+ this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
303
+ return parseInt(d, 10);
304
+ });
305
+ this.update();
306
+ this.updateNavArrows();
307
+ },
308
+
309
+ place: function(){
310
+ if(this.isInline) return;
311
+ var zIndex = parseInt(this.element.parents().filter(function() {
312
+ return $(this).css('z-index') != 'auto';
313
+ }).first().css('z-index'))+10;
314
+ var offset = this.component ? this.component.offset() : this.element.offset();
315
+ var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(true);
316
+ this.picker.css({
317
+ top: offset.top + height,
318
+ left: offset.left,
319
+ zIndex: zIndex
320
+ });
321
+ },
322
+
323
+ update: function(){
324
+ var date, fromArgs = false;
325
+ if(arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
326
+ date = arguments[0];
327
+ fromArgs = true;
328
+ } else {
329
+ date = this.isInput ? this.element.val() : this.element.data('date') || this.element.find('input').val();
330
+ }
331
+
332
+ this.date = DPGlobal.parseDate(date, this.format, this.language);
333
+
334
+ if(fromArgs) this.setValue();
335
+
336
+ if (this.date < this.startDate) {
337
+ this.viewDate = new Date(this.startDate);
338
+ } else if (this.date > this.endDate) {
339
+ this.viewDate = new Date(this.endDate);
340
+ } else {
341
+ this.viewDate = new Date(this.date);
342
+ }
343
+ this.fill();
344
+ },
345
+
346
+ fillDow: function(){
347
+ var dowCnt = this.weekStart,
348
+ html = '<tr>';
349
+ if(this.calendarWeeks){
350
+ var cell = '<th class="cw">&nbsp;</th>';
351
+ html += cell;
352
+ this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
353
+ }
354
+ while (dowCnt < this.weekStart + 7) {
355
+ html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
356
+ }
357
+ html += '</tr>';
358
+ this.picker.find('.datepicker-days thead').append(html);
359
+ },
360
+
361
+ fillMonths: function(){
362
+ var html = '',
363
+ i = 0;
364
+ while (i < 12) {
365
+ html += '<span class="month">'+dates[this.language].monthsShort[i++]+'</span>';
366
+ }
367
+ this.picker.find('.datepicker-months td').html(html);
368
+ },
369
+
370
+ fill: function() {
371
+ var d = new Date(this.viewDate),
372
+ year = d.getUTCFullYear(),
373
+ month = d.getUTCMonth(),
374
+ startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,
375
+ startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
376
+ endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
377
+ endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
378
+ currentDate = this.date && this.date.valueOf(),
379
+ today = new Date();
380
+ this.picker.find('.datepicker-days thead th.switch')
381
+ .text(dates[this.language].months[month]+' '+year);
382
+ this.picker.find('tfoot th.today')
383
+ .text(dates[this.language].today)
384
+ .toggle(this.todayBtn !== false);
385
+ this.updateNavArrows();
386
+ this.fillMonths();
387
+ var prevMonth = UTCDate(year, month-1, 28,0,0,0,0),
388
+ day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
389
+ prevMonth.setUTCDate(day);
390
+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7)%7);
391
+ var nextMonth = new Date(prevMonth);
392
+ nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
393
+ nextMonth = nextMonth.valueOf();
394
+ var html = [];
395
+ var clsName;
396
+ while(prevMonth.valueOf() < nextMonth) {
397
+ if (prevMonth.getUTCDay() == this.weekStart) {
398
+ html.push('<tr>');
399
+ if(this.calendarWeeks){
400
+ // ISO 8601: First week contains first thursday.
401
+ // ISO also states week starts on Monday, but we can be more abstract here.
402
+ var
403
+ // Start of current week: based on weekstart/current date
404
+ ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
405
+ // Thursday of this week
406
+ th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
407
+ // First Thursday of year, year from thursday
408
+ yth = new Date(+(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
409
+ // Calendar week: ms between thursdays, div ms per day, div 7 days
410
+ calWeek = (th - yth) / 864e5 / 7 + 1;
411
+ html.push('<td class="cw">'+ calWeek +'</td>');
412
+
413
+ }
414
+ }
415
+ clsName = '';
416
+ if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
417
+ clsName += ' old';
418
+ } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) {
419
+ clsName += ' new';
420
+ }
421
+ // Compare internal UTC date with local today, not UTC today
422
+ if (this.todayHighlight &&
423
+ prevMonth.getUTCFullYear() == today.getFullYear() &&
424
+ prevMonth.getUTCMonth() == today.getMonth() &&
425
+ prevMonth.getUTCDate() == today.getDate()) {
426
+ clsName += ' today';
427
+ }
428
+ if (currentDate && prevMonth.valueOf() == currentDate) {
429
+ clsName += ' active';
430
+ }
431
+ if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate ||
432
+ $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {
433
+ clsName += ' disabled';
434
+ }
435
+ html.push('<td class="day'+clsName+'">'+prevMonth.getUTCDate() + '</td>');
436
+ if (prevMonth.getUTCDay() == this.weekEnd) {
437
+ html.push('</tr>');
438
+ }
439
+ prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
440
+ }
441
+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
442
+ var currentYear = this.date && this.date.getUTCFullYear();
443
+
444
+ var months = this.picker.find('.datepicker-months')
445
+ .find('th:eq(1)')
446
+ .text(year)
447
+ .end()
448
+ .find('span').removeClass('active');
449
+ if (currentYear && currentYear == year) {
450
+ months.eq(this.date.getUTCMonth()).addClass('active');
451
+ }
452
+ if (year < startYear || year > endYear) {
453
+ months.addClass('disabled');
454
+ }
455
+ if (year == startYear) {
456
+ months.slice(0, startMonth).addClass('disabled');
457
+ }
458
+ if (year == endYear) {
459
+ months.slice(endMonth+1).addClass('disabled');
460
+ }
461
+
462
+ html = '';
463
+ year = parseInt(year/10, 10) * 10;
464
+ var yearCont = this.picker.find('.datepicker-years')
465
+ .find('th:eq(1)')
466
+ .text(year + '-' + (year + 9))
467
+ .end()
468
+ .find('td');
469
+ year -= 1;
470
+ for (var i = -1; i < 11; i++) {
471
+ html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' active' : '')+(year < startYear || year > endYear ? ' disabled' : '')+'">'+year+'</span>';
472
+ year += 1;
473
+ }
474
+ yearCont.html(html);
475
+ },
476
+
477
+ updateNavArrows: function() {
478
+ var d = new Date(this.viewDate),
479
+ year = d.getUTCFullYear(),
480
+ month = d.getUTCMonth();
481
+ switch (this.viewMode) {
482
+ case 0:
483
+ if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth()) {
484
+ this.picker.find('.prev').css({visibility: 'hidden'});
485
+ } else {
486
+ this.picker.find('.prev').css({visibility: 'visible'});
487
+ }
488
+ if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth()) {
489
+ this.picker.find('.next').css({visibility: 'hidden'});
490
+ } else {
491
+ this.picker.find('.next').css({visibility: 'visible'});
492
+ }
493
+ break;
494
+ case 1:
495
+ case 2:
496
+ if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {
497
+ this.picker.find('.prev').css({visibility: 'hidden'});
498
+ } else {
499
+ this.picker.find('.prev').css({visibility: 'visible'});
500
+ }
501
+ if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {
502
+ this.picker.find('.next').css({visibility: 'hidden'});
503
+ } else {
504
+ this.picker.find('.next').css({visibility: 'visible'});
505
+ }
506
+ break;
507
+ }
508
+ },
509
+
510
+ click: function(e) {
511
+ e.stopPropagation();
512
+ e.preventDefault();
513
+ var target = $(e.target).closest('span, td, th');
514
+ if (target.length == 1) {
515
+ switch(target[0].nodeName.toLowerCase()) {
516
+ case 'th':
517
+ switch(target[0].className) {
518
+ case 'switch':
519
+ this.showMode(1);
520
+ break;
521
+ case 'prev':
522
+ case 'next':
523
+ var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);
524
+ switch(this.viewMode){
525
+ case 0:
526
+ this.viewDate = this.moveMonth(this.viewDate, dir);
527
+ break;
528
+ case 1:
529
+ case 2:
530
+ this.viewDate = this.moveYear(this.viewDate, dir);
531
+ break;
532
+ }
533
+ this.fill();
534
+ break;
535
+ case 'today':
536
+ var date = new Date();
537
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
538
+
539
+ this.showMode(-2);
540
+ var which = this.todayBtn == 'linked' ? null : 'view';
541
+ this._setDate(date, which);
542
+ break;
543
+ }
544
+ break;
545
+ case 'span':
546
+ if (!target.is('.disabled')) {
547
+ this.viewDate.setUTCDate(1);
548
+ if (target.is('.month')) {
549
+ var month = target.parent().find('span').index(target);
550
+ this.viewDate.setUTCMonth(month);
551
+ this.element.trigger({
552
+ type: 'changeMonth',
553
+ date: this.viewDate
554
+ });
555
+ } else {
556
+ var year = parseInt(target.text(), 10)||0;
557
+ this.viewDate.setUTCFullYear(year);
558
+ this.element.trigger({
559
+ type: 'changeYear',
560
+ date: this.viewDate
561
+ });
562
+ }
563
+ this.showMode(-1);
564
+ this.fill();
565
+ }
566
+ break;
567
+ case 'td':
568
+ if (target.is('.day') && !target.is('.disabled')){
569
+ var day = parseInt(target.text(), 10)||1;
570
+ var year = this.viewDate.getUTCFullYear(),
571
+ month = this.viewDate.getUTCMonth();
572
+ if (target.is('.old')) {
573
+ if (month === 0) {
574
+ month = 11;
575
+ year -= 1;
576
+ } else {
577
+ month -= 1;
578
+ }
579
+ } else if (target.is('.new')) {
580
+ if (month == 11) {
581
+ month = 0;
582
+ year += 1;
583
+ } else {
584
+ month += 1;
585
+ }
586
+ }
587
+ this._setDate(UTCDate(year, month, day,0,0,0,0));
588
+ }
589
+ break;
590
+ }
591
+ }
592
+ },
593
+
594
+ _setDate: function(date, which){
595
+ if (!which || which == 'date')
596
+ this.date = date;
597
+ if (!which || which == 'view')
598
+ this.viewDate = date;
599
+ this.fill();
600
+ this.setValue();
601
+ this.element.trigger({
602
+ type: 'changeDate',
603
+ date: this.date
604
+ });
605
+ var element;
606
+ if (this.isInput) {
607
+ element = this.element;
608
+ } else if (this.component){
609
+ element = this.element.find('input');
610
+ }
611
+ if (element) {
612
+ element.change();
613
+ if (this.autoclose && (!which || which == 'date')) {
614
+ this.hide();
615
+ }
616
+ }
617
+ },
618
+
619
+ moveMonth: function(date, dir){
620
+ if (!dir) return date;
621
+ var new_date = new Date(date.valueOf()),
622
+ day = new_date.getUTCDate(),
623
+ month = new_date.getUTCMonth(),
624
+ mag = Math.abs(dir),
625
+ new_month, test;
626
+ dir = dir > 0 ? 1 : -1;
627
+ if (mag == 1){
628
+ test = dir == -1
629
+ // If going back one month, make sure month is not current month
630
+ // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
631
+ ? function(){ return new_date.getUTCMonth() == month; }
632
+ // If going forward one month, make sure month is as expected
633
+ // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
634
+ : function(){ return new_date.getUTCMonth() != new_month; };
635
+ new_month = month + dir;
636
+ new_date.setUTCMonth(new_month);
637
+ // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
638
+ if (new_month < 0 || new_month > 11)
639
+ new_month = (new_month + 12) % 12;
640
+ } else {
641
+ // For magnitudes >1, move one month at a time...
642
+ for (var i=0; i<mag; i++)
643
+ // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
644
+ new_date = this.moveMonth(new_date, dir);
645
+ // ...then reset the day, keeping it in the new month
646
+ new_month = new_date.getUTCMonth();
647
+ new_date.setUTCDate(day);
648
+ test = function(){ return new_month != new_date.getUTCMonth(); };
649
+ }
650
+ // Common date-resetting loop -- if date is beyond end of month, make it
651
+ // end of month
652
+ while (test()){
653
+ new_date.setUTCDate(--day);
654
+ new_date.setUTCMonth(new_month);
655
+ }
656
+ return new_date;
657
+ },
658
+
659
+ moveYear: function(date, dir){
660
+ return this.moveMonth(date, dir*12);
661
+ },
662
+
663
+ dateWithinRange: function(date){
664
+ return date >= this.startDate && date <= this.endDate;
665
+ },
666
+
667
+ keydown: function(e){
668
+ if (this.picker.is(':not(:visible)')){
669
+ if (e.keyCode == 27) // allow escape to hide and re-show picker
670
+ this.show();
671
+ return;
672
+ }
673
+ var dateChanged = false,
674
+ dir, day, month,
675
+ newDate, newViewDate;
676
+ switch(e.keyCode){
677
+ case 27: // escape
678
+ this.hide();
679
+ e.preventDefault();
680
+ break;
681
+ case 37: // left
682
+ case 39: // right
683
+ if (!this.keyboardNavigation) break;
684
+ dir = e.keyCode == 37 ? -1 : 1;
685
+ if (e.ctrlKey){
686
+ newDate = this.moveYear(this.date, dir);
687
+ newViewDate = this.moveYear(this.viewDate, dir);
688
+ } else if (e.shiftKey){
689
+ newDate = this.moveMonth(this.date, dir);
690
+ newViewDate = this.moveMonth(this.viewDate, dir);
691
+ } else {
692
+ newDate = new Date(this.date);
693
+ newDate.setUTCDate(this.date.getUTCDate() + dir);
694
+ newViewDate = new Date(this.viewDate);
695
+ newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir);
696
+ }
697
+ if (this.dateWithinRange(newDate)){
698
+ this.date = newDate;
699
+ this.viewDate = newViewDate;
700
+ this.setValue();
701
+ this.update();
702
+ e.preventDefault();
703
+ dateChanged = true;
704
+ }
705
+ break;
706
+ case 38: // up
707
+ case 40: // down
708
+ if (!this.keyboardNavigation) break;
709
+ dir = e.keyCode == 38 ? -1 : 1;
710
+ if (e.ctrlKey){
711
+ newDate = this.moveYear(this.date, dir);
712
+ newViewDate = this.moveYear(this.viewDate, dir);
713
+ } else if (e.shiftKey){
714
+ newDate = this.moveMonth(this.date, dir);
715
+ newViewDate = this.moveMonth(this.viewDate, dir);
716
+ } else {
717
+ newDate = new Date(this.date);
718
+ newDate.setUTCDate(this.date.getUTCDate() + dir * 7);
719
+ newViewDate = new Date(this.viewDate);
720
+ newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7);
721
+ }
722
+ if (this.dateWithinRange(newDate)){
723
+ this.date = newDate;
724
+ this.viewDate = newViewDate;
725
+ this.setValue();
726
+ this.update();
727
+ e.preventDefault();
728
+ dateChanged = true;
729
+ }
730
+ break;
731
+ case 13: // enter
732
+ this.hide();
733
+ e.preventDefault();
734
+ break;
735
+ case 9: // tab
736
+ this.hide();
737
+ break;
738
+ }
739
+ if (dateChanged){
740
+ this.element.trigger({
741
+ type: 'changeDate',
742
+ date: this.date
743
+ });
744
+ var element;
745
+ if (this.isInput) {
746
+ element = this.element;
747
+ } else if (this.component){
748
+ element = this.element.find('input');
749
+ }
750
+ if (element) {
751
+ element.change();
752
+ }
753
+ }
754
+ },
755
+
756
+ showMode: function(dir) {
757
+ if (dir) {
758
+ this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
759
+ }
760
+ /*
761
+ vitalets: fixing bug of very special conditions:
762
+ jquery 1.7.1 + webkit + show inline datepicker in bootstrap popover.
763
+ Method show() does not set display css correctly and datepicker is not shown.
764
+ Changed to .css('display', 'block') solve the problem.
765
+ See https://github.com/vitalets/x-editable/issues/37
766
+
767
+ In jquery 1.7.2+ everything works fine.
768
+ */
769
+ //this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
770
+ this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
771
+ this.updateNavArrows();
772
+ }
773
+ };
774
+
775
+ $.fn.datepicker = function ( option ) {
776
+ var args = Array.apply(null, arguments);
777
+ args.shift();
778
+ return this.each(function () {
779
+ var $this = $(this),
780
+ data = $this.data('datepicker'),
781
+ options = typeof option == 'object' && option;
782
+ if (!data) {
783
+ $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
784
+ }
785
+ if (typeof option == 'string' && typeof data[option] == 'function') {
786
+ data[option].apply(data, args);
787
+ }
788
+ });
789
+ };
790
+
791
+ $.fn.datepicker.defaults = {
792
+ };
793
+ $.fn.datepicker.Constructor = Datepicker;
794
+ var dates = $.fn.datepicker.dates = {
795
+ en: {
796
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
797
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
798
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
799
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
800
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
801
+ today: "Today"
802
+ }
803
+ };
804
+
805
+ var DPGlobal = {
806
+ modes: [
807
+ {
808
+ clsName: 'days',
809
+ navFnc: 'Month',
810
+ navStep: 1
811
+ },
812
+ {
813
+ clsName: 'months',
814
+ navFnc: 'FullYear',
815
+ navStep: 1
816
+ },
817
+ {
818
+ clsName: 'years',
819
+ navFnc: 'FullYear',
820
+ navStep: 10
821
+ }],
822
+ isLeapYear: function (year) {
823
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
824
+ },
825
+ getDaysInMonth: function (year, month) {
826
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
827
+ },
828
+ validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
829
+ nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
830
+ parseFormat: function(format){
831
+ // IE treats \0 as a string end in inputs (truncating the value),
832
+ // so it's a bad format delimiter, anyway
833
+ var separators = format.replace(this.validParts, '\0').split('\0'),
834
+ parts = format.match(this.validParts);
835
+ if (!separators || !separators.length || !parts || parts.length === 0){
836
+ throw new Error("Invalid date format.");
837
+ }
838
+ return {separators: separators, parts: parts};
839
+ },
840
+ parseDate: function(date, format, language) {
841
+ if (date instanceof Date) return date;
842
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
843
+ var part_re = /([\-+]\d+)([dmwy])/,
844
+ parts = date.match(/([\-+]\d+)([dmwy])/g),
845
+ part, dir;
846
+ date = new Date();
847
+ for (var i=0; i<parts.length; i++) {
848
+ part = part_re.exec(parts[i]);
849
+ dir = parseInt(part[1]);
850
+ switch(part[2]){
851
+ case 'd':
852
+ date.setUTCDate(date.getUTCDate() + dir);
853
+ break;
854
+ case 'm':
855
+ date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
856
+ break;
857
+ case 'w':
858
+ date.setUTCDate(date.getUTCDate() + dir * 7);
859
+ break;
860
+ case 'y':
861
+ date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
862
+ break;
863
+ }
864
+ }
865
+ return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
866
+ }
867
+ var parts = date && date.match(this.nonpunctuation) || [],
868
+ date = new Date(),
869
+ parsed = {},
870
+ setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
871
+ setters_map = {
872
+ yyyy: function(d,v){ return d.setUTCFullYear(v); },
873
+ yy: function(d,v){ return d.setUTCFullYear(2000+v); },
874
+ m: function(d,v){
875
+ v -= 1;
876
+ while (v<0) v += 12;
877
+ v %= 12;
878
+ d.setUTCMonth(v);
879
+ while (d.getUTCMonth() != v)
880
+ d.setUTCDate(d.getUTCDate()-1);
881
+ return d;
882
+ },
883
+ d: function(d,v){ return d.setUTCDate(v); }
884
+ },
885
+ val, filtered, part;
886
+ setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
887
+ setters_map['dd'] = setters_map['d'];
888
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
889
+ var fparts = format.parts.slice();
890
+ // Remove noop parts
891
+ if (parts.length != fparts.length) {
892
+ fparts = $(fparts).filter(function(i,p){
893
+ return $.inArray(p, setters_order) !== -1;
894
+ }).toArray();
895
+ }
896
+ // Process remainder
897
+ if (parts.length == fparts.length) {
898
+ for (var i=0, cnt = fparts.length; i < cnt; i++) {
899
+ val = parseInt(parts[i], 10);
900
+ part = fparts[i];
901
+ if (isNaN(val)) {
902
+ switch(part) {
903
+ case 'MM':
904
+ filtered = $(dates[language].months).filter(function(){
905
+ var m = this.slice(0, parts[i].length),
906
+ p = parts[i].slice(0, m.length);
907
+ return m == p;
908
+ });
909
+ val = $.inArray(filtered[0], dates[language].months) + 1;
910
+ break;
911
+ case 'M':
912
+ filtered = $(dates[language].monthsShort).filter(function(){
913
+ var m = this.slice(0, parts[i].length),
914
+ p = parts[i].slice(0, m.length);
915
+ return m == p;
916
+ });
917
+ val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
918
+ break;
919
+ }
920
+ }
921
+ parsed[part] = val;
922
+ }
923
+ for (var i=0, s; i<setters_order.length; i++){
924
+ s = setters_order[i];
925
+ if (s in parsed && !isNaN(parsed[s]))
926
+ setters_map[s](date, parsed[s]);
927
+ }
928
+ }
929
+ return date;
930
+ },
931
+ formatDate: function(date, format, language){
932
+ var val = {
933
+ d: date.getUTCDate(),
934
+ D: dates[language].daysShort[date.getUTCDay()],
935
+ DD: dates[language].days[date.getUTCDay()],
936
+ m: date.getUTCMonth() + 1,
937
+ M: dates[language].monthsShort[date.getUTCMonth()],
938
+ MM: dates[language].months[date.getUTCMonth()],
939
+ yy: date.getUTCFullYear().toString().substring(2),
940
+ yyyy: date.getUTCFullYear()
941
+ };
942
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
943
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
944
+ var date = [],
945
+ seps = $.extend([], format.separators);
946
+ for (var i=0, cnt = format.parts.length; i < cnt; i++) {
947
+ if (seps.length)
948
+ date.push(seps.shift());
949
+ date.push(val[format.parts[i]]);
950
+ }
951
+ return date.join('');
952
+ },
953
+ headTemplate: '<thead>'+
954
+ '<tr>'+
955
+ '<th class="prev"><i class="icon-arrow-left"/></th>'+
956
+ '<th colspan="5" class="switch"></th>'+
957
+ '<th class="next"><i class="icon-arrow-right"/></th>'+
958
+ '</tr>'+
959
+ '</thead>',
960
+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
961
+ footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
962
+ };
963
+ DPGlobal.template = '<div class="datepicker">'+
964
+ '<div class="datepicker-days">'+
965
+ '<table class=" table-condensed">'+
966
+ DPGlobal.headTemplate+
967
+ '<tbody></tbody>'+
968
+ DPGlobal.footTemplate+
969
+ '</table>'+
970
+ '</div>'+
971
+ '<div class="datepicker-months">'+
972
+ '<table class="table-condensed">'+
973
+ DPGlobal.headTemplate+
974
+ DPGlobal.contTemplate+
975
+ DPGlobal.footTemplate+
976
+ '</table>'+
977
+ '</div>'+
978
+ '<div class="datepicker-years">'+
979
+ '<table class="table-condensed">'+
980
+ DPGlobal.headTemplate+
981
+ DPGlobal.contTemplate+
982
+ DPGlobal.footTemplate+
983
+ '</table>'+
984
+ '</div>'+
985
+ '</div>';
986
+
987
+ $.fn.datepicker.DPGlobal = DPGlobal;
988
+
989
+ }( window.jQuery );