assets-rails 0.1.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 (322) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +65 -0
  8. data/Rakefile +2 -0
  9. data/assets-rails.gemspec +25 -0
  10. data/lib/assets-rails.rb +7 -0
  11. data/lib/assets-rails/engine.rb +9 -0
  12. data/lib/assets-rails/version.rb +5 -0
  13. data/vendor/assets/fonts/bootstrap/v3.2.0/glyphicons-halflings-regular.eot +0 -0
  14. data/vendor/assets/fonts/bootstrap/v3.2.0/glyphicons-halflings-regular.svg +229 -0
  15. data/vendor/assets/fonts/bootstrap/v3.2.0/glyphicons-halflings-regular.ttf +0 -0
  16. data/vendor/assets/fonts/bootstrap/v3.2.0/glyphicons-halflings-regular.woff +0 -0
  17. data/vendor/assets/fonts/bootstrap/v3.3.0/glyphicons-halflings-regular.eot +0 -0
  18. data/vendor/assets/fonts/bootstrap/v3.3.0/glyphicons-halflings-regular.svg +229 -0
  19. data/vendor/assets/fonts/bootstrap/v3.3.0/glyphicons-halflings-regular.ttf +0 -0
  20. data/vendor/assets/fonts/bootstrap/v3.3.0/glyphicons-halflings-regular.woff +0 -0
  21. data/vendor/assets/fonts/font-awesome/v4.2.0/FontAwesome.otf +0 -0
  22. data/vendor/assets/fonts/font-awesome/v4.2.0/fontawesome-webfont.eot +0 -0
  23. data/vendor/assets/fonts/font-awesome/v4.2.0/fontawesome-webfont.svg +520 -0
  24. data/vendor/assets/fonts/font-awesome/v4.2.0/fontawesome-webfont.ttf +0 -0
  25. data/vendor/assets/fonts/font-awesome/v4.2.0/fontawesome-webfont.woff +0 -0
  26. data/vendor/assets/fonts/jquery.flexslider/flexslider-icon.eot +0 -0
  27. data/vendor/assets/fonts/jquery.flexslider/flexslider-icon.svg +19 -0
  28. data/vendor/assets/fonts/jquery.flexslider/flexslider-icon.ttf +0 -0
  29. data/vendor/assets/fonts/jquery.flexslider/flexslider-icon.woff +0 -0
  30. data/vendor/assets/images/fancybox/blank.gif +0 -0
  31. data/vendor/assets/images/fancybox/fancybox_buttons.png +0 -0
  32. data/vendor/assets/images/fancybox/fancybox_loading.gif +0 -0
  33. data/vendor/assets/images/fancybox/fancybox_loading@2x.gif +0 -0
  34. data/vendor/assets/images/fancybox/fancybox_overlay.png +0 -0
  35. data/vendor/assets/images/fancybox/fancybox_sprite.png +0 -0
  36. data/vendor/assets/images/fancybox/fancybox_sprite@2x.png +0 -0
  37. data/vendor/assets/images/jquery.colorbox/v1.5.14/example1/border.png +0 -0
  38. data/vendor/assets/images/jquery.colorbox/v1.5.14/example1/controls.png +0 -0
  39. data/vendor/assets/images/jquery.colorbox/v1.5.14/example1/loading.gif +0 -0
  40. data/vendor/assets/images/jquery.colorbox/v1.5.14/example1/loading_background.png +0 -0
  41. data/vendor/assets/images/jquery.colorbox/v1.5.14/example1/overlay.png +0 -0
  42. data/vendor/assets/images/jquery.colorbox/v1.5.14/example2/controls.png +0 -0
  43. data/vendor/assets/images/jquery.colorbox/v1.5.14/example2/loading.gif +0 -0
  44. data/vendor/assets/images/jquery.colorbox/v1.5.14/example3/controls.png +0 -0
  45. data/vendor/assets/images/jquery.colorbox/v1.5.14/example3/loading.gif +0 -0
  46. data/vendor/assets/images/jquery.colorbox/v1.5.14/example4/border1.png +0 -0
  47. data/vendor/assets/images/jquery.colorbox/v1.5.14/example4/border2.png +0 -0
  48. data/vendor/assets/images/jquery.colorbox/v1.5.14/example4/loading.gif +0 -0
  49. data/vendor/assets/images/jquery.colorbox/v1.5.14/example5/border.png +0 -0
  50. data/vendor/assets/images/jquery.colorbox/v1.5.14/example5/controls.png +0 -0
  51. data/vendor/assets/images/jquery.colorbox/v1.5.14/example5/loading.gif +0 -0
  52. data/vendor/assets/images/jquery.colorbox/v1.5.14/example5/loading_background.png +0 -0
  53. data/vendor/assets/images/jquery.flexslider/bg_play_pause.png +0 -0
  54. data/vendor/assets/images/jquery.owlcarousel/AjaxLoader.gif +0 -0
  55. data/vendor/assets/images/jquery.owlcarousel/grabbing.png +0 -0
  56. data/vendor/assets/images/zebra_datepicker/calendar-disabled.png +0 -0
  57. data/vendor/assets/images/zebra_datepicker/calendar.png +0 -0
  58. data/vendor/assets/images/zebra_datepicker/metallic/default-date.png +0 -0
  59. data/vendor/assets/images/zebra_datepicker/metallic/disabled-date.png +0 -0
  60. data/vendor/assets/images/zebra_datepicker/metallic/header.png +0 -0
  61. data/vendor/assets/images/zebra_datepicker/metallic/selected-date.png +0 -0
  62. data/vendor/assets/javascripts/bootstrap/v3.2.0.js +12 -0
  63. data/vendor/assets/javascripts/bootstrap/v3.2.0/affix.js +142 -0
  64. data/vendor/assets/javascripts/bootstrap/v3.2.0/alert.js +92 -0
  65. data/vendor/assets/javascripts/bootstrap/v3.2.0/button.js +110 -0
  66. data/vendor/assets/javascripts/bootstrap/v3.2.0/carousel.js +223 -0
  67. data/vendor/assets/javascripts/bootstrap/v3.2.0/collapse.js +170 -0
  68. data/vendor/assets/javascripts/bootstrap/v3.2.0/dropdown.js +151 -0
  69. data/vendor/assets/javascripts/bootstrap/v3.2.0/modal.js +280 -0
  70. data/vendor/assets/javascripts/bootstrap/v3.2.0/popover.js +113 -0
  71. data/vendor/assets/javascripts/bootstrap/v3.2.0/scrollspy.js +170 -0
  72. data/vendor/assets/javascripts/bootstrap/v3.2.0/tab.js +128 -0
  73. data/vendor/assets/javascripts/bootstrap/v3.2.0/tooltip.js +457 -0
  74. data/vendor/assets/javascripts/bootstrap/v3.2.0/transition.js +59 -0
  75. data/vendor/assets/javascripts/bootstrap/v3.3.0/affix.js +162 -0
  76. data/vendor/assets/javascripts/bootstrap/v3.3.0/alert.js +94 -0
  77. data/vendor/assets/javascripts/bootstrap/v3.3.0/button.js +116 -0
  78. data/vendor/assets/javascripts/bootstrap/v3.3.0/carousel.js +239 -0
  79. data/vendor/assets/javascripts/bootstrap/v3.3.0/collapse.js +211 -0
  80. data/vendor/assets/javascripts/bootstrap/v3.3.0/dropdown.js +161 -0
  81. data/vendor/assets/javascripts/bootstrap/v3.3.0/modal.js +281 -0
  82. data/vendor/assets/javascripts/bootstrap/v3.3.0/popover.js +119 -0
  83. data/vendor/assets/javascripts/bootstrap/v3.3.0/scrollspy.js +175 -0
  84. data/vendor/assets/javascripts/bootstrap/v3.3.0/tab.js +153 -0
  85. data/vendor/assets/javascripts/bootstrap/v3.3.0/tooltip.js +478 -0
  86. data/vendor/assets/javascripts/bootstrap/v3.3.0/transition.js +59 -0
  87. data/vendor/assets/javascripts/draggabilly/v1.1.1.js +2 -0
  88. data/vendor/assets/javascripts/draggabilly/v1.1.1/draggabilly.js +615 -0
  89. data/vendor/assets/javascripts/imagesloaded/v3.1.8.js +2 -0
  90. data/vendor/assets/javascripts/imagesloaded/v3.1.8/imagesloaded.js +335 -0
  91. data/vendor/assets/javascripts/isotope/v2.0.1.js +1 -0
  92. data/vendor/assets/javascripts/isotope/v2.0.1/isotope.js +628 -0
  93. data/vendor/assets/javascripts/jquery.collageplus/v0.3.3.js +2 -0
  94. data/vendor/assets/javascripts/jquery.collageplus/v0.3.3/jquery.collagecaption.js +143 -0
  95. data/vendor/assets/javascripts/jquery.collageplus/v0.3.3/jquery.collageplus.js +401 -0
  96. data/vendor/assets/javascripts/jquery.collageplus/v0.3.3/remove_whitespace.js +13 -0
  97. data/vendor/assets/javascripts/jquery.colorbox/v1.5.14.js +2 -0
  98. data/vendor/assets/javascripts/jquery.colorbox/v1.5.14/jquery.colorbox.js +1090 -0
  99. data/vendor/assets/javascripts/jquery.expander/v1.4.12.js +1 -0
  100. data/vendor/assets/javascripts/jquery.expander/v1.4.12/jquery.expander.js +453 -0
  101. data/vendor/assets/javascripts/jquery.fakecrop.js +1 -0
  102. data/vendor/assets/javascripts/jquery.fakecrop/jquery.fakecrop.js +153 -0
  103. data/vendor/assets/javascripts/jquery.fancybox/v2.1.5.js +4 -0
  104. data/vendor/assets/javascripts/jquery.fancybox/v2.1.5/jquery.fancybox-buttons.js +122 -0
  105. data/vendor/assets/javascripts/jquery.fancybox/v2.1.5/jquery.fancybox-media.js +199 -0
  106. data/vendor/assets/javascripts/jquery.fancybox/v2.1.5/jquery.fancybox-thumbs.js +162 -0
  107. data/vendor/assets/javascripts/jquery.fancybox/v2.1.5/jquery.fancybox.js +2020 -0
  108. data/vendor/assets/javascripts/jquery.flexslider/v2.2.2.js +1 -0
  109. data/vendor/assets/javascripts/jquery.flexslider/v2.2.2/jquery.flexslider.js +1157 -0
  110. data/vendor/assets/javascripts/jquery.infinitescroll/v2.0.2.js +2 -0
  111. data/vendor/assets/javascripts/jquery.infinitescroll/v2.0.2/jquery.infinitescroll.js +821 -0
  112. data/vendor/assets/javascripts/jquery.nivo.slider/v3.2.js +2 -0
  113. data/vendor/assets/javascripts/jquery.nivo.slider/v3.2/jquery.nivo.slider.js +662 -0
  114. data/vendor/assets/javascripts/jquery.owlcarousel/v1.3.3.js +2 -0
  115. data/vendor/assets/javascripts/jquery.owlcarousel/v1.3.3/jquery.owlcarousel.js +1517 -0
  116. data/vendor/assets/javascripts/jquery.pageless.js +2 -0
  117. data/vendor/assets/javascripts/jquery.pageless/jquery.pageless.js +251 -0
  118. data/vendor/assets/javascripts/jquery.render/v1.1.0.js +2 -0
  119. data/vendor/assets/javascripts/jquery.render/v1.1.0/jquery.render.js +56 -0
  120. data/vendor/assets/javascripts/jquery.scrollto/v1.4.13.js +2 -0
  121. data/vendor/assets/javascripts/jquery.scrollto/v1.4.13/jquery.scrollto.js +187 -0
  122. data/vendor/assets/javascripts/jquery.timeago/v1.4.1.js +1 -0
  123. data/vendor/assets/javascripts/jquery.timeago/v1.4.1/jquery.timeago.js +214 -0
  124. data/vendor/assets/javascripts/jquery.turbolinks/v2.1.0.js +1 -0
  125. data/vendor/assets/javascripts/jquery.turbolinks/v2.1.0/jquery.turbolinks.js +49 -0
  126. data/vendor/assets/javascripts/jquery/v1.11.1.js +1 -0
  127. data/vendor/assets/javascripts/jquery/v1.11.1/jquery.js +10308 -0
  128. data/vendor/assets/javascripts/jquery/v2.1.1.js +1 -0
  129. data/vendor/assets/javascripts/jquery/v2.1.1/jquery.js +9190 -0
  130. data/vendor/assets/javascripts/masonry/v3.1.5.js +2 -0
  131. data/vendor/assets/javascripts/masonry/v3.1.5/masonry.js +205 -0
  132. data/vendor/assets/javascripts/nprogress/v0.1.6.js +2 -0
  133. data/vendor/assets/javascripts/nprogress/v0.1.6/nprogress-ajax.js +4 -0
  134. data/vendor/assets/javascripts/nprogress/v0.1.6/nprogress-turbolinks.js +5 -0
  135. data/vendor/assets/javascripts/nprogress/v0.1.6/nprogress.js +475 -0
  136. data/vendor/assets/javascripts/responsiveCarousel/v1.2.0.js +2 -0
  137. data/vendor/assets/javascripts/responsiveCarousel/v1.2.0/responsiveCarousel.js +410 -0
  138. data/vendor/assets/javascripts/responsiveslides/v1.54.js +2 -0
  139. data/vendor/assets/javascripts/responsiveslides/v1.54/responsiveslides.js +391 -0
  140. data/vendor/assets/javascripts/zebra_datepicker/v1.8.9.js +2 -0
  141. data/vendor/assets/javascripts/zebra_datepicker/v1.8.9/zebra_datepicker.js +2965 -0
  142. data/vendor/assets/stylesheets/bootstrap/_v3.2.0.scss +52 -0
  143. data/vendor/assets/stylesheets/bootstrap/_v3.3.0.scss +52 -0
  144. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_alerts.scss +68 -0
  145. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_badges.scss +57 -0
  146. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_bootstrap-sprockets.scss +7 -0
  147. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_breadcrumbs.scss +26 -0
  148. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_button-groups.scss +240 -0
  149. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_buttons.scss +157 -0
  150. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_carousel.scss +243 -0
  151. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_close.scss +35 -0
  152. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_code.scss +68 -0
  153. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_component-animations.scss +35 -0
  154. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_dropdowns.scss +215 -0
  155. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_forms.scss +538 -0
  156. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_glyphicons.scss +237 -0
  157. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_grid.scss +84 -0
  158. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_input-groups.scss +166 -0
  159. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_jumbotron.scss +48 -0
  160. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_labels.scss +66 -0
  161. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_list-group.scss +131 -0
  162. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_media.scss +56 -0
  163. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_mixins.scss +39 -0
  164. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_modals.scss +150 -0
  165. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_navbar.scss +659 -0
  166. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_navs.scss +242 -0
  167. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_normalize.scss +425 -0
  168. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_pager.scss +55 -0
  169. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_pagination.scss +88 -0
  170. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_panels.scss +243 -0
  171. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_popovers.scss +133 -0
  172. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_print.scss +101 -0
  173. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_progress-bars.scss +105 -0
  174. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_responsive-embed.scss +34 -0
  175. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_responsive-utilities.scss +174 -0
  176. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_scaffolding.scss +150 -0
  177. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_tables.scss +233 -0
  178. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_theme.scss +258 -0
  179. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_thumbnails.scss +38 -0
  180. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_tooltip.scss +95 -0
  181. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_type.scss +304 -0
  182. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_utilities.scss +57 -0
  183. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_variables.scss +854 -0
  184. data/vendor/assets/stylesheets/bootstrap/v3.2.0/_wells.scss +29 -0
  185. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_alerts.scss +14 -0
  186. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_background-variant.scss +11 -0
  187. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_border-radius.scss +18 -0
  188. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_buttons.scss +50 -0
  189. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_center-block.scss +7 -0
  190. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_clearfix.scss +22 -0
  191. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_forms.scss +84 -0
  192. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_gradients.scss +58 -0
  193. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_grid-framework.scss +81 -0
  194. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_grid.scss +122 -0
  195. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_hide-text.scss +21 -0
  196. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_image.scss +34 -0
  197. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_labels.scss +12 -0
  198. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_list-group.scss +31 -0
  199. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_nav-divider.scss +10 -0
  200. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_nav-vertical-align.scss +9 -0
  201. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_opacity.scss +8 -0
  202. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_pagination.scss +23 -0
  203. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_panels.scss +24 -0
  204. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_progress-bar.scss +10 -0
  205. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_reset-filter.scss +8 -0
  206. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_resize.scss +6 -0
  207. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_responsive-visibility.scss +21 -0
  208. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_size.scss +10 -0
  209. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_tab-focus.scss +9 -0
  210. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_table-row.scss +28 -0
  211. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_text-emphasis.scss +11 -0
  212. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_text-overflow.scss +8 -0
  213. data/vendor/assets/stylesheets/bootstrap/v3.2.0/mixins/_vendor-prefixes.scss +219 -0
  214. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_alerts.scss +68 -0
  215. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_badges.scss +57 -0
  216. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_bootstrap-sprockets.scss +7 -0
  217. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_breadcrumbs.scss +26 -0
  218. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_button-groups.scss +247 -0
  219. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_buttons.scss +160 -0
  220. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_carousel.scss +267 -0
  221. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_close.scss +35 -0
  222. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_code.scss +69 -0
  223. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_component-animations.scss +38 -0
  224. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_dropdowns.scss +213 -0
  225. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_forms.scss +561 -0
  226. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_glyphicons.scss +234 -0
  227. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_grid.scss +84 -0
  228. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_input-groups.scss +166 -0
  229. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_jumbotron.scss +48 -0
  230. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_labels.scss +66 -0
  231. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_list-group.scss +132 -0
  232. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_media.scss +47 -0
  233. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_mixins.scss +39 -0
  234. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_modals.scss +149 -0
  235. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_navbar.scss +661 -0
  236. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_navs.scss +244 -0
  237. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_normalize.scss +427 -0
  238. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_pager.scss +54 -0
  239. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_pagination.scss +88 -0
  240. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_panels.scss +261 -0
  241. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_popovers.scss +134 -0
  242. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_print.scss +107 -0
  243. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_progress-bars.scss +87 -0
  244. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_responsive-embed.scss +35 -0
  245. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_responsive-utilities.scss +174 -0
  246. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_scaffolding.scss +150 -0
  247. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_tables.scss +234 -0
  248. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_theme.scss +260 -0
  249. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_thumbnails.scss +38 -0
  250. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_tooltip.scss +95 -0
  251. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_type.scss +298 -0
  252. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_utilities.scss +56 -0
  253. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_variables.scss +864 -0
  254. data/vendor/assets/stylesheets/bootstrap/v3.3.0/_wells.scss +29 -0
  255. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_alerts.scss +14 -0
  256. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_background-variant.scss +11 -0
  257. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_border-radius.scss +18 -0
  258. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_buttons.scss +52 -0
  259. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_center-block.scss +7 -0
  260. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_clearfix.scss +22 -0
  261. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_forms.scss +88 -0
  262. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_gradients.scss +58 -0
  263. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_grid-framework.scss +81 -0
  264. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_grid.scss +122 -0
  265. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_hide-text.scss +21 -0
  266. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_image.scss +33 -0
  267. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_labels.scss +12 -0
  268. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_list-group.scss +31 -0
  269. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_nav-divider.scss +10 -0
  270. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_nav-vertical-align.scss +9 -0
  271. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_opacity.scss +8 -0
  272. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_pagination.scss +23 -0
  273. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_panels.scss +24 -0
  274. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_progress-bar.scss +10 -0
  275. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_reset-filter.scss +8 -0
  276. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_resize.scss +6 -0
  277. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_responsive-visibility.scss +21 -0
  278. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_size.scss +10 -0
  279. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_tab-focus.scss +9 -0
  280. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_table-row.scss +28 -0
  281. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_text-emphasis.scss +11 -0
  282. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_text-overflow.scss +8 -0
  283. data/vendor/assets/stylesheets/bootstrap/v3.3.0/mixins/_vendor-prefixes.scss +222 -0
  284. data/vendor/assets/stylesheets/font-awesome/v4.2.0.css +3 -0
  285. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_bordered-pulled.scss +16 -0
  286. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_core.scss +11 -0
  287. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_extras.scss +44 -0
  288. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_fixed-width.scss +6 -0
  289. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_icons.scss +552 -0
  290. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_larger.scss +13 -0
  291. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_list.scss +19 -0
  292. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_mixins.scss +25 -0
  293. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_path.scss +14 -0
  294. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_rotated-flipped.scss +20 -0
  295. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_spinning.scss +29 -0
  296. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_stacked.scss +20 -0
  297. data/vendor/assets/stylesheets/font-awesome/v4.2.0/_variables.scss +561 -0
  298. data/vendor/assets/stylesheets/font-awesome/v4.2.0/font-awesome.scss +17 -0
  299. data/vendor/assets/stylesheets/jquery.colorbox/v1.5.14/example1.css.scss +70 -0
  300. data/vendor/assets/stylesheets/jquery.colorbox/v1.5.14/example2.css.scss +50 -0
  301. data/vendor/assets/stylesheets/jquery.colorbox/v1.5.14/example3.css.scss +45 -0
  302. data/vendor/assets/stylesheets/jquery.colorbox/v1.5.14/example4.css.scss +66 -0
  303. data/vendor/assets/stylesheets/jquery.colorbox/v1.5.14/example5.css.scss +58 -0
  304. data/vendor/assets/stylesheets/jquery.fancybox/v2.1.5.css +5 -0
  305. data/vendor/assets/stylesheets/jquery.fancybox/v2.1.5/jquery.fancybox-buttons.css.erb +97 -0
  306. data/vendor/assets/stylesheets/jquery.fancybox/v2.1.5/jquery.fancybox-thumbs.css +55 -0
  307. data/vendor/assets/stylesheets/jquery.fancybox/v2.1.5/jquery.fancybox.css.erb +274 -0
  308. data/vendor/assets/stylesheets/jquery.flexslider/v2.2.2.css +3 -0
  309. data/vendor/assets/stylesheets/jquery.flexslider/v2.2.2/jquery.flexslider.scss +96 -0
  310. data/vendor/assets/stylesheets/jquery.nivo.slider/v3.2.css +3 -0
  311. data/vendor/assets/stylesheets/jquery.nivo.slider/v3.2/jquery.nivo.slider.css +113 -0
  312. data/vendor/assets/stylesheets/jquery.owlcarousel/v1.3.3/jquery.owlcarousel.scss +71 -0
  313. data/vendor/assets/stylesheets/jquery.owlcarousel/v1.3.3/theme.scss +79 -0
  314. data/vendor/assets/stylesheets/jquery.owlcarousel/v1.3.3/transitions.scss +163 -0
  315. data/vendor/assets/stylesheets/nprogress/v0.1.6/nprogress-bootstrap.css +4 -0
  316. data/vendor/assets/stylesheets/nprogress/v0.1.6/nprogress.css.scss +77 -0
  317. data/vendor/assets/stylesheets/responsiveslides/v1.54.css +3 -0
  318. data/vendor/assets/stylesheets/responsiveslides/v1.54/responsiveslides.css +33 -0
  319. data/vendor/assets/stylesheets/zebra_datepicker/v1.8.9/bootstrap.scss +95 -0
  320. data/vendor/assets/stylesheets/zebra_datepicker/v1.8.9/default.scss +102 -0
  321. data/vendor/assets/stylesheets/zebra_datepicker/v1.8.9/metallic.scss +106 -0
  322. metadata +407 -0
@@ -0,0 +1,2 @@
1
+ // https://github.com/stefangabos/Zebra_Datepicker
2
+ //= require zebra_datepicker/v1.8.9/zebra_datepicker.js
@@ -0,0 +1,2965 @@
1
+ /**
2
+ * Zebra_DatePicker
3
+ *
4
+ * Zebra_DatePicker is a small, compact and highly configurable date picker plugin for jQuery
5
+ *
6
+ * Visit {@link http://stefangabos.ro/jquery/zebra-datepicker/} for more information.
7
+ *
8
+ * For more resources visit {@link http://stefangabos.ro/}
9
+ *
10
+ * @author Stefan Gabos <contact@stefangabos.ro>
11
+ * @version 1.8.9 (last revision: August 16, 2014)
12
+ * @copyright (c) 2011 - 2014 Stefan Gabos
13
+ * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE
14
+ * @package Zebra_DatePicker
15
+ */
16
+ ;(function($) {
17
+
18
+ 'use strict';
19
+
20
+ $.Zebra_DatePicker = function(element, options) {
21
+
22
+ var defaults = {
23
+
24
+ // setting this property to a jQuery element, will result in the date picker being always visible, the indicated
25
+ // element being the date picker's container;
26
+ always_visible: false,
27
+
28
+ // days of the week; Sunday to Saturday
29
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
30
+
31
+ // by default, the abbreviated name of a day consists of the first 2 letters from the day's full name;
32
+ // while this is common for most languages, there are also exceptions for languages like Thai, Loa, Myanmar,
33
+ // etc. where this is not correct; for these cases, specify an array with the abbreviations to be used for
34
+ // the 7 days of the week; leave it FALSE to use the first 2 letters of a day's name as the abbreviation.
35
+ //
36
+ // default is FALSE
37
+ days_abbr: false,
38
+
39
+ // the position of the date picker relative to the element it is attached to. note that, regardless of this
40
+ // setting, the date picker's position will be automatically adjusted to fit in the viewport, if needed.
41
+ //
42
+ // possible values are "above" and "below"
43
+ //
44
+ // default is "above"
45
+ default_position: 'above',
46
+
47
+ // direction of the calendar
48
+ //
49
+ // a positive or negative integer: n (a positive integer) creates a future-only calendar beginning at n days
50
+ // after today; -n (a negative integer); if n is 0, the calendar has no restrictions. use boolean true for
51
+ // a future-only calendar starting with today and use boolean false for a past-only calendar ending today.
52
+ //
53
+ // you may also set this property to an array with two elements in the following combinations:
54
+ //
55
+ // - first item is boolean TRUE (calendar starts today), an integer > 0 (calendar starts n days after
56
+ // today), or a valid date given in the format defined by the "format" attribute, using English for
57
+ // month names (calendar starts at the specified date), and the second item is boolean FALSE (the calendar
58
+ // has no ending date), an integer > 0 (calendar ends n days after the starting date), or a valid date
59
+ // given in the format defined by the "format" attribute, using English for month names, and which occurs
60
+ // after the starting date (calendar ends at the specified date)
61
+ //
62
+ // - first item is boolean FALSE (calendar ends today), an integer < 0 (calendar ends n days before today),
63
+ // or a valid date given in the format defined by the "format" attribute, using English for month names
64
+ // (calendar ends at the specified date), and the second item is an integer > 0 (calendar ends n days
65
+ // before the ending date), or a valid date given in the format defined by the "format" attribute, using
66
+ // English for month names and which occurs before the starting date (calendar starts at the specified
67
+ // date)
68
+ //
69
+ // [1, 7] - calendar starts tomorrow and ends seven days after that
70
+ // [true, 7] - calendar starts today and ends seven days after that
71
+ // ['2013-01-01', false] - calendar starts on January 1st 2013 and has no ending date ("format" is YYYY-MM-DD)
72
+ // [false, '2012-01-01'] - calendar ends today and starts on January 1st 2012 ("format" is YYYY-MM-DD)
73
+ //
74
+ // note that "disabled_dates" property will still apply!
75
+ //
76
+ // default is 0 (no restrictions)
77
+ direction: 0,
78
+
79
+ // an array of disabled dates in the following format: 'day month year weekday' where "weekday" is optional
80
+ // and can be 0-6 (Saturday to Sunday); the syntax is similar to cron's syntax: the values are separated by
81
+ // spaces and may contain * (asterisk) - (dash) and , (comma) delimiters:
82
+ //
83
+ // ['1 1 2012'] would disable January 1, 2012;
84
+ // ['* 1 2012'] would disable all days in January 2012;
85
+ // ['1-10 1 2012'] would disable January 1 through 10 in 2012;
86
+ // ['1,10 1 2012'] would disable January 1 and 10 in 2012;
87
+ // ['1-10,20,22,24 1-3 *'] would disable 1 through 10, plus the 22nd and 24th of January through March for every year;
88
+ // ['* * * 0,6'] would disable all Saturdays and Sundays;
89
+ // ['01 07 2012', '02 07 2012', '* 08 2012'] would disable 1st and 2nd of July 2012, and all of August of 2012
90
+ //
91
+ // default is FALSE, no disabled dates
92
+ disabled_dates: false,
93
+
94
+ // an array of enabled dates in the same format as required for "disabled_dates" property.
95
+ // to be used together with the "disabled_dates" property by first setting the "disabled_dates" property to
96
+ // something like "[* * * *]" (which will disable everything) and the setting the "enabled_dates" property to,
97
+ // say, "[* * * 0,6]" to enable just weekends.
98
+ enabled_dates: false,
99
+
100
+ // week's starting day
101
+ //
102
+ // valid values are 0 to 6, Sunday to Saturday
103
+ //
104
+ // default is 1, Monday
105
+ first_day_of_week: 1,
106
+
107
+ // format of the returned date
108
+ //
109
+ // accepts the following characters for date formatting: d, D, j, l, N, w, S, F, m, M, n, Y, y borrowing
110
+ // syntax from PHP's "date" function.
111
+ //
112
+ // note that when setting a date format without days ('d', 'j'), the users will be able to select only years
113
+ // and months, and when setting a format without months and days ('F', 'm', 'M', 'n', 'd', 'j'), the
114
+ // users will be able to select only years; likewise, when setting a date format with just months ('F', 'm',
115
+ // 'M', 'n') or just years ('Y', 'y'), users will be able to select only months and years, respectively.
116
+ //
117
+ // also note that the value of the "view" property (see below) may be overridden if it is the case: a value of
118
+ // "days" for the "view" property makes no sense if the date format doesn't allow the selection of days.
119
+ //
120
+ // default is Y-m-d
121
+ format: 'Y-m-d',
122
+
123
+ // captions in the datepicker's header, for the 3 possible views: days, months, years
124
+ //
125
+ // for each of the 3 views the following special characters may be used borrowing from PHP's "date" function's
126
+ // syntax: m, n, F, M, y and Y; any of these will be replaced at runtime with the appropriate date fragment,
127
+ // depending on the currently viewed date. two more special characters are also available Y1 and Y2 (upper
128
+ // case representing years with 4 digits, lowercase representing years with 2 digits) which represent
129
+ // "currently selected year - 7" and "currently selected year + 4" and which only make sense used in the
130
+ // "years" view.
131
+ //
132
+ // even though any of these special characters may be used in any of the 3 views, you should use m, n, F, M
133
+ // for the "days" view and y, Y, Y1, Y2, y1, y2 for the "months" and "years" view or you may get unexpected
134
+ // results!
135
+ //
136
+ // Text and HTML can also be used, and will be rendered as it is, as in the example below (the library is
137
+ // smart enough to not replace special characters when used in words or HTML tags):
138
+ //
139
+ // header_captions: {
140
+ // 'days': 'Departure:<br>F, Y',
141
+ // 'months': 'Departure:<br>Y',
142
+ // 'years': 'Departure:<br>Y1 - Y2'
143
+ // }
144
+ //
145
+ // Default is
146
+ //
147
+ // header_captions: {
148
+ // 'days': 'F, Y',
149
+ // 'months': 'Y',
150
+ // 'years': 'Y1 - Y2'
151
+ // }
152
+ header_captions: {
153
+ 'days': 'F, Y',
154
+ 'months': 'Y',
155
+ 'years': 'Y1 - Y2'
156
+ },
157
+
158
+ // HTML to be used for the previous month/next month buttons
159
+ //
160
+ // default is ['&#171;','&#187;']
161
+ header_navigation: ['&#171;', '&#187;'],
162
+
163
+ // should the icon for opening the datepicker be inside the element?
164
+ // if set to FALSE, the icon will be placed to the right of the parent element, while if set to TRUE it will
165
+ // be placed to the right of the parent element, but *inside* the element itself
166
+ //
167
+ // default is TRUE
168
+ inside: true,
169
+
170
+ // the caption for the "Clear" button
171
+ lang_clear_date: 'Clear date',
172
+
173
+ // months names
174
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
175
+
176
+ // by default, the abbreviated name of a month consists of the first 3 letters from the month's full name;
177
+ // while this is common for most languages, there are also exceptions for languages like Thai, Loa, Myanmar,
178
+ // etc. where this is not correct; for these cases, specify an array with the abbreviations to be used for
179
+ // the months of the year; leave it FALSE to use the first 3 letters of a month's name as the abbreviation.
180
+ //
181
+ // default is FALSE
182
+ months_abbr: false,
183
+
184
+ // the offset, in pixels (x, y), to shift the date picker's position relative to the top-right of the icon
185
+ // that toggles the date picker or, if the icon is disabled, relative to the top-right corner of the element
186
+ // the plugin is attached to.
187
+ //
188
+ // note that this only applies if the position of element relative to the browser's viewport doesn't require
189
+ // the date picker to be placed automatically so that it is visible!
190
+ //
191
+ // default is [5, -5]
192
+ offset: [5, -5],
193
+
194
+ // if set as a jQuery element with a Zebra_DatePicker attached, that particular date picker will use the
195
+ // current date picker's value as starting date
196
+ // note that the rules set in the "direction" property will still apply, only that the reference date will
197
+ // not be the current system date but the value selected in the current date picker
198
+ // default is FALSE (not paired with another date picker)
199
+ pair: false,
200
+
201
+ // should the element the calendar is attached to, be read-only?
202
+ // if set to TRUE, a date can be set only through the date picker and cannot be entered manually
203
+ //
204
+ // default is TRUE
205
+ readonly_element: true,
206
+
207
+ // should days from previous and/or next month be selectable when visible?
208
+ // note that if the value of this property is set to TRUE, the value of "show_other_months" will be considered
209
+ // TRUE regardless of the actual value!
210
+ //
211
+ // default is FALSE
212
+ select_other_months: false,
213
+
214
+ // should the "Clear date" button be visible?
215
+ //
216
+ // accepted values are:
217
+ //
218
+ // - 0 (zero) - the button for clearing a previously selected date is shown only if a previously selected date
219
+ // already exists; this means that if the input the date picker is attached to is empty, and the user selects
220
+ // a date for the first time, this button will not be visible; once the user picked a date and opens the date
221
+ // picker again, this time the button will be visible.
222
+ //
223
+ // - TRUE will make the button visible all the time
224
+ //
225
+ // - FALSE will disable the button
226
+ //
227
+ // default is "0" (without quotes)
228
+ show_clear_date: 0,
229
+
230
+ // should a calendar icon be added to the elements the plugin is attached to?
231
+ //
232
+ // default is TRUE
233
+ show_icon: true,
234
+
235
+ // should days from previous and/or next month be visible?
236
+ //
237
+ // default is TRUE
238
+ show_other_months: true,
239
+
240
+ // should the "Today" button be visible?
241
+ // setting it to anything but boolean FALSE will enable the button and will use the property's value as
242
+ // caption for the button; setting it to FALSE will disable the button
243
+ //
244
+ // default is "Today"
245
+ show_select_today: 'Today',
246
+
247
+ // should an extra column be shown, showing the number of each week?
248
+ // anything other than FALSE will enable this feature, and use the given value as column title
249
+ // i.e. show_week_number: 'Wk' would enable this feature and have "Wk" as the column's title
250
+ //
251
+ // default is FALSE
252
+ show_week_number: false,
253
+
254
+ // a default date to start the date picker with
255
+ // must be specified in the format defined by the "format" property, or it will be ignored!
256
+ // note that this value is used only if there is no value in the field the date picker is attached to!
257
+ start_date: false,
258
+
259
+ // should default values, in the input field the date picker is attached to, be deleted if they are not valid
260
+ // according to "direction" and/or "disabled_dates"?
261
+ //
262
+ // default is FALSE
263
+ strict: false,
264
+
265
+ // how should the date picker start; valid values are "days", "months" and "years"
266
+ // note that the date picker is always cycling days-months-years when clicking in the date picker's header,
267
+ // and years-months-days when selecting dates (unless one or more of the views are missing due to the date's
268
+ // format)
269
+ //
270
+ // also note that the value of the "view" property may be overridden if the date's format requires so! (i.e.
271
+ // "days" for the "view" property makes no sense if the date format doesn't allow the selection of days)
272
+ //
273
+ // default is "days"
274
+ view: 'days',
275
+
276
+ // days of the week that are considered "weekend days"
277
+ // valid values are 0 to 6, Sunday to Saturday
278
+ //
279
+ // default values are 0 and 6 (Saturday and Sunday)
280
+ weekend_days: [0, 6],
281
+
282
+ // when set to TRUE, day numbers < 10 will be prefixed with 0; set to FALSE if you don't want that
283
+ //
284
+ // default is TRUE
285
+ zero_pad: false,
286
+
287
+ // callback function to be executed whenever the user changes the view (days/months/years), as well as when
288
+ // the user navigates by clicking on the "next"/"previous" icons in any of the views;
289
+ //
290
+ // the callback function called by this event takes 3 arguments - the first argument represents the current
291
+ // view (can be "days", "months" or "years"), the second argument represents an array containing the "active"
292
+ // elements (not disabled) from the view, as jQuery elements, allowing for easy customization and interaction
293
+ // with particular cells in the date picker's view, while the third argument is a reference to the element
294
+ // the date picker is attached to, as a jQuery object (deprecated - use the "this" keyword inside the callback
295
+ // function to refer to the element the date picker is attached to)
296
+ //
297
+ // for simplifying searching for particular dates, each element in the second argument will also have a
298
+ // "date" data attribute whose format depends on the value of the "view" argument:
299
+ // - YYYY-MM-DD for elements in the "days" view
300
+ // - YYYY-MM for elements in the "months" view
301
+ // - YYYY for elements in the "years" view
302
+ //
303
+ // the "this" keyword inside the callback function refers to the element the date picker is attached to!
304
+ onChange: null,
305
+
306
+ // callback function to be executed when the user clicks the "Clear" button
307
+ // the callback function takes a single argument:
308
+ // - a reference to the element the date picker is attached to, as a jQuery object (deprecated - use the
309
+ // "this" keyword inside the callback function to refer to the element the date picker is attached to)
310
+ //
311
+ // the "this" keyword inside the callback function refers to the element the date picker is attached to!
312
+ onClear: null,
313
+
314
+ // callback function to be executed when the date picker is shown
315
+ // the callback function takes a single argument:
316
+ // - a reference to the element the date picker is attached to, as a jQuery object (deprecated - use the
317
+ // "this" keyword inside the callback function to refer to the element the date picker is attached to)
318
+ //
319
+ // the "this" keyword inside the callback function refers to the element the date picker is attached to!
320
+ onOpen: null,
321
+
322
+ // callback function to be executed when a date is selected
323
+ // the callback function takes 5 arguments:
324
+ // - the date in the format specified by the "format" attribute;
325
+ // - the date in YYYY-MM-DD format
326
+ // - the date as a JavaScript Date object
327
+ // - a reference to the element the date picker is attached to, as a jQuery object (deprecated - use the
328
+ // "this" keyword inside the callback function to refer to the element the date picker is attached to)
329
+ // - the ISO 8601 week number of the selected date
330
+ //
331
+ // the "this" keyword inside the callback function refers to the element the date picker is attached to!
332
+ onSelect: null
333
+
334
+ };
335
+
336
+ // private properties
337
+ var view, datepicker, icon, header, daypicker, monthpicker, yearpicker, cleardate, current_system_month, current_system_year,
338
+ current_system_day, first_selectable_month, first_selectable_year, first_selectable_day, selected_month, selected_year,
339
+ default_day, default_month, default_year, enabled_dates, disabled_dates, shim, start_date, end_date, last_selectable_day,
340
+ last_selectable_year, last_selectable_month, daypicker_cells, monthpicker_cells, yearpicker_cells, views, clickables,
341
+ selecttoday, footer, show_select_today, timeout;
342
+
343
+ var plugin = this;
344
+
345
+ plugin.settings = {};
346
+
347
+ // the jQuery version of the element
348
+ // "element" (without the $) will point to the DOM element
349
+ var $element = $(element);
350
+
351
+ /**
352
+ * Constructor method. Initializes the date picker.
353
+ *
354
+ * @return void
355
+ */
356
+ var init = function(update) {
357
+
358
+ // unless we're just updating settings
359
+ if (!update) {
360
+
361
+ // merge default settings with user-settings (
362
+ plugin.settings = $.extend({}, defaults, options);
363
+
364
+ // iterate through the element's data attributes (if any)
365
+ for (var data in $element.data())
366
+
367
+ // if data attribute's name starts with "zdp_"
368
+ if (data.indexOf('zdp_') === 0) {
369
+
370
+ // remove the "zdp_" prefix
371
+ data = data.replace(/^zdp\_/, '');
372
+
373
+ // if such a property exists
374
+ if (undefined !== defaults[data])
375
+
376
+ // update the property's value
377
+ // (note that for the "pair" property we need to convert the property to an element)
378
+ plugin.settings[data] = (data == 'pair' ? $($element.data('zdp_' + data)) : $element.data('zdp_' + data));
379
+
380
+ }
381
+
382
+ }
383
+
384
+ // if the element should be read-only, set the "readonly" attribute
385
+ if (plugin.settings.readonly_element) $element.attr('readonly', 'readonly');
386
+
387
+ // determine the views the user can cycle through, depending on the format
388
+ // that is, if the format doesn't contain the day, the user will be able to cycle only through years and months,
389
+ // whereas if the format doesn't contain months nor days, the user will only be able to select years
390
+
391
+ var
392
+
393
+ // the characters that may be present in the date format and that represent days, months and years
394
+ date_chars = {
395
+ days: ['d', 'j', 'D'],
396
+ months: ['F', 'm', 'M', 'n', 't'],
397
+ years: ['o', 'Y', 'y']
398
+ },
399
+
400
+ // some defaults
401
+ has_days = false,
402
+ has_months = false,
403
+ has_years = false,
404
+ type = null;
405
+
406
+ // iterate through all the character blocks
407
+ for (type in date_chars)
408
+
409
+ // iterate through the characters of each block
410
+ $.each(date_chars[type], function(index, character) {
411
+
412
+ // if current character exists in the "format" property
413
+ if (plugin.settings.format.indexOf(character) > -1)
414
+
415
+ // set to TRUE the appropriate flag
416
+ if (type == 'days') has_days = true;
417
+ else if (type == 'months') has_months = true;
418
+ else if (type == 'years') has_years = true;
419
+
420
+ });
421
+
422
+ // if user can cycle through all the views, set the flag accordingly
423
+ if (has_days && has_months && has_years) views = ['years', 'months', 'days'];
424
+
425
+ // if user can cycle only through year and months, set the flag accordingly
426
+ else if (!has_days && has_months && has_years) views = ['years', 'months'];
427
+
428
+ // if user can cycle only through months and days, set the flag accordingly
429
+ else if (has_days && has_months && !has_years) views = ['months', 'days'];
430
+
431
+ // if user can only see the year picker, set the flag accordingly
432
+ else if (!has_days && !has_months && has_years) views = ['years'];
433
+
434
+ // if user can only see the month picker, set the flag accordingly
435
+ else if (!has_days && has_months && !has_years) views = ['months'];
436
+
437
+ // if invalid format (no days, no months, no years) use the default where the user is able to cycle through
438
+ // all the views
439
+ else views = ['years', 'months', 'days'];
440
+
441
+ // if the starting view is not amongst the views the user can cycle through, set the correct starting view
442
+ if ($.inArray(plugin.settings.view, views) == -1) plugin.settings.view = views[views.length - 1];
443
+
444
+ // parse the rules for disabling dates and turn them into arrays of arrays
445
+
446
+ // array that will hold the rules for enabling/disabling dates
447
+ disabled_dates = []; enabled_dates = [];
448
+
449
+ var dates;
450
+
451
+ // it's the same logic for preparing the enabled/disable dates...
452
+ for (var l = 0; l < 2; l++) {
453
+
454
+ // first time we're doing disabled dates,
455
+ if (l === 0) dates = plugin.settings.disabled_dates;
456
+
457
+ // second time we're doing enabled_dates
458
+ else dates = plugin.settings.enabled_dates;
459
+
460
+ // if we have a non-empty array
461
+ if ($.isArray(dates) && dates.length > 0)
462
+
463
+ // iterate through the rules
464
+ $.each(dates, function() {
465
+
466
+ // split the values in rule by white space
467
+ var rules = this.split(' ');
468
+
469
+ // there can be a maximum of 4 rules (days, months, years and, optionally, day of the week)
470
+ for (var i = 0; i < 4; i++) {
471
+
472
+ // if one of the values is not available
473
+ // replace it with a * (wildcard)
474
+ if (!rules[i]) rules[i] = '*';
475
+
476
+ // if rule contains a comma, create a new array by splitting the rule by commas
477
+ // if there are no commas create an array containing the rule's string
478
+ rules[i] = (rules[i].indexOf(',') > -1 ? rules[i].split(',') : new Array(rules[i]));
479
+
480
+ // iterate through the items in the rule
481
+ for (var j = 0; j < rules[i].length; j++)
482
+
483
+ // if item contains a dash (defining a range)
484
+ if (rules[i][j].indexOf('-') > -1) {
485
+
486
+ // get the lower and upper limits of the range
487
+ var limits = rules[i][j].match(/^([0-9]+)\-([0-9]+)/);
488
+
489
+ // if range is valid
490
+ if (null !== limits) {
491
+
492
+ // iterate through the range
493
+ for (var k = to_int(limits[1]); k <= to_int(limits[2]); k++)
494
+
495
+ // if value is not already among the values of the rule
496
+ // add it to the rule
497
+ if ($.inArray(k, rules[i]) == -1) rules[i].push(k + '');
498
+
499
+ // remove the range indicator
500
+ rules[i].splice(j, 1);
501
+
502
+ }
503
+
504
+ }
505
+
506
+ // iterate through the items in the rule
507
+ // and make sure that numbers are numbers
508
+ for (j = 0; j < rules[i].length; j++) rules[i][j] = (isNaN(to_int(rules[i][j])) ? rules[i][j] : to_int(rules[i][j]));
509
+
510
+ }
511
+
512
+ // add to the correct list of processed rules
513
+ // first time we're doing disabled dates,
514
+ if (l === 0) disabled_dates.push(rules);
515
+
516
+ // second time we're doing enabled_dates
517
+ else enabled_dates.push(rules);
518
+
519
+ });
520
+
521
+ }
522
+
523
+ var
524
+
525
+ // cache the current system date
526
+ date = new Date(),
527
+
528
+ // when the date picker's starting date depends on the value of another date picker, this value will be
529
+ // set by the other date picker
530
+ // this value will be used as base for all calculations (if not set, will be the same as the current
531
+ // system date)
532
+ reference_date = (!plugin.settings.reference_date ? ($element.data('zdp_reference_date') && undefined !== $element.data('zdp_reference_date') ? $element.data('zdp_reference_date') : date) : plugin.settings.reference_date),
533
+
534
+ tmp_start_date, tmp_end_date;
535
+
536
+ // reset these values here as this method might be called more than once during a date picker's lifetime
537
+ // (when the selectable dates depend on the values from another date picker)
538
+ start_date = undefined; end_date = undefined;
539
+
540
+ // extract the date parts
541
+ // also, save the current system month/day/year - we'll use them to highlight the current system date
542
+ first_selectable_month = reference_date.getMonth();
543
+ current_system_month = date.getMonth();
544
+ first_selectable_year = reference_date.getFullYear();
545
+ current_system_year = date.getFullYear();
546
+ first_selectable_day = reference_date.getDate();
547
+ current_system_day = date.getDate();
548
+
549
+ // check if the calendar has any restrictions
550
+
551
+ // calendar is future-only, starting today
552
+ // it means we have a starting date (the current system date), but no ending date
553
+ if (plugin.settings.direction === true) start_date = reference_date;
554
+
555
+ // calendar is past only, ending today
556
+ else if (plugin.settings.direction === false) {
557
+
558
+ // it means we have an ending date (the reference date), but no starting date
559
+ end_date = reference_date;
560
+
561
+ // extract the date parts
562
+ last_selectable_month = end_date.getMonth();
563
+ last_selectable_year = end_date.getFullYear();
564
+ last_selectable_day = end_date.getDate();
565
+
566
+ } else if (
567
+
568
+ // if direction is not given as an array and the value is an integer > 0
569
+ (!$.isArray(plugin.settings.direction) && is_integer(plugin.settings.direction) && to_int(plugin.settings.direction) > 0) ||
570
+
571
+ // or direction is given as an array
572
+ ($.isArray(plugin.settings.direction) && (
573
+
574
+ // and first entry is a valid date
575
+ (tmp_start_date = check_date(plugin.settings.direction[0])) ||
576
+ // or a boolean TRUE
577
+ plugin.settings.direction[0] === true ||
578
+ // or an integer > 0
579
+ (is_integer(plugin.settings.direction[0]) && plugin.settings.direction[0] > 0)
580
+
581
+ ) && (
582
+
583
+ // and second entry is a valid date
584
+ (tmp_end_date = check_date(plugin.settings.direction[1])) ||
585
+ // or a boolean FALSE
586
+ plugin.settings.direction[1] === false ||
587
+ // or integer >= 0
588
+ (is_integer(plugin.settings.direction[1]) && plugin.settings.direction[1] >= 0)
589
+
590
+ ))
591
+
592
+ ) {
593
+
594
+ // if an exact starting date was given, use that as a starting date
595
+ if (tmp_start_date) start_date = tmp_start_date;
596
+
597
+ // otherwise
598
+ else
599
+
600
+ // figure out the starting date
601
+ // use the Date object to normalize the date
602
+ // for example, 2011 05 33 will be transformed to 2011 06 02
603
+ start_date = new Date(
604
+ first_selectable_year,
605
+ first_selectable_month,
606
+ first_selectable_day + (!$.isArray(plugin.settings.direction) ? to_int(plugin.settings.direction) : to_int(plugin.settings.direction[0] === true ? 0 : plugin.settings.direction[0]))
607
+ );
608
+
609
+ // re-extract the date parts
610
+ first_selectable_month = start_date.getMonth();
611
+ first_selectable_year = start_date.getFullYear();
612
+ first_selectable_day = start_date.getDate();
613
+
614
+ // if an exact ending date was given and the date is after the starting date, use that as a ending date
615
+ if (tmp_end_date && +tmp_end_date >= +start_date) end_date = tmp_end_date;
616
+
617
+ // if have information about the ending date
618
+ else if (!tmp_end_date && plugin.settings.direction[1] !== false && $.isArray(plugin.settings.direction))
619
+
620
+ // figure out the ending date
621
+ // use the Date object to normalize the date
622
+ // for example, 2011 05 33 will be transformed to 2011 06 02
623
+ end_date = new Date(
624
+ first_selectable_year,
625
+ first_selectable_month,
626
+ first_selectable_day + to_int(plugin.settings.direction[1])
627
+ );
628
+
629
+ // if a valid ending date exists
630
+ if (end_date) {
631
+
632
+ // extract the date parts
633
+ last_selectable_month = end_date.getMonth();
634
+ last_selectable_year = end_date.getFullYear();
635
+ last_selectable_day = end_date.getDate();
636
+
637
+ }
638
+
639
+ } else if (
640
+
641
+ // if direction is not given as an array and the value is an integer < 0
642
+ (!$.isArray(plugin.settings.direction) && is_integer(plugin.settings.direction) && to_int(plugin.settings.direction) < 0) ||
643
+
644
+ // or direction is given as an array
645
+ ($.isArray(plugin.settings.direction) && (
646
+
647
+ // and first entry is boolean FALSE
648
+ plugin.settings.direction[0] === false ||
649
+ // or an integer < 0
650
+ (is_integer(plugin.settings.direction[0]) && plugin.settings.direction[0] < 0)
651
+
652
+ ) && (
653
+
654
+ // and second entry is a valid date
655
+ (tmp_start_date = check_date(plugin.settings.direction[1])) ||
656
+ // or an integer >= 0
657
+ (is_integer(plugin.settings.direction[1]) && plugin.settings.direction[1] >= 0)
658
+
659
+ ))
660
+
661
+ ) {
662
+
663
+ // figure out the ending date
664
+ // use the Date object to normalize the date
665
+ // for example, 2011 05 33 will be transformed to 2011 06 02
666
+ end_date = new Date(
667
+ first_selectable_year,
668
+ first_selectable_month,
669
+ first_selectable_day + (!$.isArray(plugin.settings.direction) ? to_int(plugin.settings.direction) : to_int(plugin.settings.direction[0] === false ? 0 : plugin.settings.direction[0]))
670
+ );
671
+
672
+ // re-extract the date parts
673
+ last_selectable_month = end_date.getMonth();
674
+ last_selectable_year = end_date.getFullYear();
675
+ last_selectable_day = end_date.getDate();
676
+
677
+ // if an exact starting date was given, and the date is before the ending date, use that as a starting date
678
+ if (tmp_start_date && +tmp_start_date < +end_date) start_date = tmp_start_date;
679
+
680
+ // if have information about the starting date
681
+ else if (!tmp_start_date && $.isArray(plugin.settings.direction))
682
+
683
+ // figure out the staring date
684
+ // use the Date object to normalize the date
685
+ // for example, 2011 05 33 will be transformed to 2011 06 02
686
+ start_date = new Date(
687
+ last_selectable_year,
688
+ last_selectable_month,
689
+ last_selectable_day - to_int(plugin.settings.direction[1])
690
+ );
691
+
692
+ // if a valid starting date exists
693
+ if (start_date) {
694
+
695
+ // extract the date parts
696
+ first_selectable_month = start_date.getMonth();
697
+ first_selectable_year = start_date.getFullYear();
698
+ first_selectable_day = start_date.getDate();
699
+
700
+ }
701
+
702
+ // if there are disabled dates
703
+ } else if ($.isArray(plugin.settings.disabled_dates) && plugin.settings.disabled_dates.length > 0)
704
+
705
+ // iterate through the rules for disabling dates
706
+ for (var interval in disabled_dates)
707
+
708
+ // only if there is a rule that disables *everything*
709
+ if (disabled_dates[interval][0] == '*' && disabled_dates[interval][1] == '*' && disabled_dates[interval][2] == '*' && disabled_dates[interval][3] == '*') {
710
+
711
+ var tmpDates = [];
712
+
713
+ // iterate through the rules for enabling dates
714
+ // looking for the minimum/maximum selectable date (if it's the case)
715
+ $.each(enabled_dates, function() {
716
+
717
+ var rule = this;
718
+
719
+ // if the rule doesn't apply to all years
720
+ if (rule[2][0] != '*')
721
+
722
+ // format date and store it in our stack
723
+ tmpDates.push(parseInt(
724
+ rule[2][0] +
725
+ (rule[1][0] == '*' ? '12' : str_pad(rule[1][0], 2)) +
726
+ (rule[0][0] == '*' ? (rule[1][0] == '*' ? '31' : new Date(rule[2][0], rule[1][0], 0).getDate()) : str_pad(rule[0][0], 2)), 10));
727
+
728
+ });
729
+
730
+ // sort dates ascending
731
+ tmpDates.sort();
732
+
733
+ // if we have any rules
734
+ if (tmpDates.length > 0) {
735
+
736
+ // get date parts
737
+ var matches = (tmpDates[0] + '').match(/([0-9]{4})([0-9]{2})([0-9]{2})/);
738
+
739
+ // assign the date parts to the appropriate variables
740
+ first_selectable_year = parseInt(matches[1], 10);
741
+ first_selectable_month = parseInt(matches[2], 10) - 1;
742
+ first_selectable_day = parseInt(matches[3], 10);
743
+
744
+ }
745
+
746
+ // don't look further
747
+ break;
748
+
749
+ }
750
+
751
+ // if first selectable date exists but is disabled, find the actual first selectable date
752
+ if (is_disabled(first_selectable_year, first_selectable_month, first_selectable_day)) {
753
+
754
+ // loop until we find the first selectable year
755
+ while (is_disabled(first_selectable_year)) {
756
+
757
+ // if calendar is past-only,
758
+ if (!start_date) {
759
+
760
+ // decrement the year
761
+ first_selectable_year--;
762
+
763
+ // because we've changed years, reset the month to December
764
+ first_selectable_month = 11;
765
+
766
+ // otherwise
767
+ } else {
768
+
769
+ // increment the year
770
+ first_selectable_year++;
771
+
772
+ // because we've changed years, reset the month to January
773
+ first_selectable_month = 0;
774
+
775
+ }
776
+
777
+ }
778
+
779
+ // loop until we find the first selectable month
780
+ while (is_disabled(first_selectable_year, first_selectable_month)) {
781
+
782
+ // if calendar is past-only
783
+ if (!start_date) {
784
+
785
+ // decrement the month
786
+ first_selectable_month--;
787
+
788
+ // because we've changed months, reset the day to the last day of the month
789
+ first_selectable_day = new Date(first_selectable_year, first_selectable_month + 1, 0).getDate();
790
+
791
+ // otherwise
792
+ } else {
793
+
794
+ // increment the month
795
+ first_selectable_month++;
796
+
797
+ // because we've changed months, reset the day to the first day of the month
798
+ first_selectable_day = 1;
799
+
800
+ }
801
+
802
+ // if we moved to a following year
803
+ if (first_selectable_month > 11) {
804
+
805
+ // increment the year
806
+ first_selectable_year++;
807
+
808
+ // reset the month to January
809
+ first_selectable_month = 0;
810
+
811
+ // because we've changed months, reset the day to the first day of the month
812
+ first_selectable_day = 1;
813
+
814
+ // if we moved to a previous year
815
+ } else if (first_selectable_month < 0) {
816
+
817
+ // decrement the year
818
+ first_selectable_year--;
819
+
820
+ // reset the month to December
821
+ first_selectable_month = 11;
822
+
823
+ // because we've changed months, reset the day to the last day of the month
824
+ first_selectable_day = new Date(first_selectable_year, first_selectable_month + 1, 0).getDate();
825
+
826
+ }
827
+
828
+ }
829
+
830
+ // loop until we find the first selectable day
831
+ while (is_disabled(first_selectable_year, first_selectable_month, first_selectable_day)) {
832
+
833
+ // if calendar is past-only, decrement the day
834
+ if (!start_date) first_selectable_day--;
835
+
836
+ // otherwise, increment the day
837
+ else first_selectable_day++;
838
+
839
+ // use the Date object to normalize the date
840
+ // for example, 2011 05 33 will be transformed to 2011 06 02
841
+ date = new Date(first_selectable_year, first_selectable_month, first_selectable_day);
842
+
843
+ // re-extract date parts from the normalized date
844
+ // as we use them in the current loop
845
+ first_selectable_year = date.getFullYear();
846
+ first_selectable_month = date.getMonth();
847
+ first_selectable_day = date.getDate();
848
+
849
+ }
850
+
851
+ // use the Date object to normalize the date
852
+ // for example, 2011 05 33 will be transformed to 2011 06 02
853
+ date = new Date(first_selectable_year, first_selectable_month, first_selectable_day);
854
+
855
+ // re-extract date parts from the normalized date
856
+ // as we use them in the current loop
857
+ first_selectable_year = date.getFullYear();
858
+ first_selectable_month = date.getMonth();
859
+ first_selectable_day = date.getDate();
860
+
861
+ }
862
+
863
+ // get the default date, from the element, and check if it represents a valid date, according to the required format
864
+ var default_date = check_date($element.val() || (plugin.settings.start_date ? plugin.settings.start_date : ''));
865
+
866
+ // if there is a default date, date picker is in "strict" mode, and the default date is disabled
867
+ if (default_date && plugin.settings.strict && is_disabled(default_date.getFullYear(), default_date.getMonth(), default_date.getDate()))
868
+
869
+ // clear the value of the parent element
870
+ $element.val('');
871
+
872
+ // updates value for the date picker whose starting date depends on the selected date (if any)
873
+ if (!update && (undefined !== start_date || undefined !== default_date))
874
+ update_dependent(undefined !== start_date ? start_date : default_date);
875
+
876
+ // if date picker is not always visible
877
+ if (!plugin.settings.always_visible) {
878
+
879
+ // if we're just creating the date picker
880
+ if (!update) {
881
+
882
+ // if a calendar icon should be added to the element the plugin is attached to, create the icon now
883
+ if (plugin.settings.show_icon) {
884
+
885
+ // strangely, in Firefox 21+ (or maybe even earlier) input elements have their "display" property
886
+ // set to "inline" instead of "inline-block" as do all the other browsers.
887
+ // because this behavior brakes the positioning of the icon, we'll set the "display" property to
888
+ // "inline-block" before anything else;
889
+ if (browser.name == 'firefox' && $element.is('input[type="text"]') && $element.css('display') == 'inline') $element.css('display', 'inline-block');
890
+
891
+ // we create a wrapper for the parent element so that we can later position the icon
892
+ // also, make sure the wrapper inherits some important css properties of the parent element
893
+ var icon_wrapper = $('<span class="Zebra_DatePicker_Icon_Wrapper"></span>').css({
894
+ 'display': $element.css('display'),
895
+ 'position': $element.css('position') == 'static' ? 'relative' : $element.css('position'),
896
+ 'float': $element.css('float'),
897
+ 'top': $element.css('top'),
898
+ 'right': $element.css('right'),
899
+ 'bottom': $element.css('bottom'),
900
+ 'left': $element.css('left')
901
+ });
902
+
903
+ // put wrapper around the element
904
+ // also, make sure we set some important css properties for it
905
+ $element.wrap(icon_wrapper).css({
906
+ 'position': 'relative',
907
+ 'top': 'auto',
908
+ 'right': 'auto',
909
+ 'bottom': 'auto',
910
+ 'left': 'auto'
911
+ });
912
+
913
+ // create the actual calendar icon (show a disabled icon if the element is disabled)
914
+ icon = $('<button type="button" class="Zebra_DatePicker_Icon' + ($element.attr('disabled') == 'disabled' ? ' Zebra_DatePicker_Icon_Disabled' : '') + '">Pick a date</button>');
915
+
916
+ // a reference to the icon, as a global property
917
+ plugin.icon = icon;
918
+
919
+ // the date picker will open when clicking both the icon and the element the plugin is attached to
920
+ clickables = icon.add($element);
921
+
922
+ // if calendar icon is not visible, the date picker will open when clicking the element
923
+ } else clickables = $element;
924
+
925
+ // attach the click event to the clickable elements (icon and/or element)
926
+ clickables.bind('click', function(e) {
927
+
928
+ e.preventDefault();
929
+
930
+ // if element is not disabled
931
+ if (!$element.attr('disabled'))
932
+
933
+ // if the date picker is visible, hide it
934
+ if (datepicker.hasClass('dp_visible')) plugin.hide();
935
+
936
+ // if the date picker is not visible, show it
937
+ else plugin.show();
938
+
939
+ });
940
+
941
+ // if icon exists, inject it into the DOM, right after the parent element (and inside the wrapper)
942
+ if (undefined !== icon) icon.insertAfter($element);
943
+
944
+ }
945
+
946
+ // if calendar icon exists
947
+ if (undefined !== icon) {
948
+
949
+ // needed when updating: remove any inline style set previously by library,
950
+ // so we get the right values below
951
+ icon.attr('style', '');
952
+
953
+ // if calendar icon is to be placed *inside* the element
954
+ // add an extra class to the icon
955
+ if (plugin.settings.inside) icon.addClass('Zebra_DatePicker_Icon_Inside');
956
+
957
+ var
958
+
959
+ // get element' width and height (including margins)
960
+ element_width = $element.outerWidth(),
961
+ element_height = $element.outerHeight(),
962
+ element_margin_left = parseInt($element.css('marginLeft'), 10) || 0,
963
+ element_margin_top = parseInt($element.css('marginTop'), 10) || 0,
964
+
965
+ // get icon's width, height and margins
966
+ icon_width = icon.outerWidth(),
967
+ icon_height = icon.outerHeight(),
968
+ icon_margin_left = parseInt(icon.css('marginLeft'), 10) || 0,
969
+ icon_margin_right = parseInt(icon.css('marginRight'), 10) || 0;
970
+
971
+ // if icon is to be placed *inside* the element
972
+ // position the icon accordingly
973
+ if (plugin.settings.inside)
974
+
975
+ icon.css({
976
+ 'top': element_margin_top + ((element_height - icon_height) / 2),
977
+ 'left': element_margin_left + (element_width - icon_width - icon_margin_right)
978
+ });
979
+
980
+ // if icon is to be placed to the right of the element
981
+ // position the icon accordingly
982
+ else
983
+
984
+ icon.css({
985
+ 'top': element_margin_top + ((element_height - icon_height) / 2),
986
+ 'left': element_margin_left + element_width + icon_margin_left
987
+ });
988
+
989
+ // assume the datepicker is not disabled
990
+ icon.removeClass(' Zebra_DatePicker_Icon_Disabled');
991
+
992
+ // if element the datepicker is attached to became disabled, disable the calendar icon, too
993
+ if ($element.attr('disabled') == 'disabled') icon.addClass('Zebra_DatePicker_Icon_Disabled');
994
+
995
+ }
996
+
997
+ }
998
+
999
+ // if the "Today" button is to be shown and it makes sense to be shown
1000
+ // (the "days" view is available and "today" is not a disabled date)
1001
+ show_select_today = (plugin.settings.show_select_today !== false && $.inArray('days', views) > -1 && !is_disabled(current_system_year, current_system_month, current_system_day) ? plugin.settings.show_select_today : false);
1002
+
1003
+ // if we just needed to recompute the things above, return now
1004
+ if (update) return;
1005
+
1006
+ // update icon/date picker position on resize
1007
+ $(window).bind('resize.Zebra_DatePicker', function() {
1008
+
1009
+ // hide the date picker
1010
+ plugin.hide();
1011
+
1012
+ // if the icon is visible, update its position as the parent element might have changed position
1013
+ if (icon !== undefined) {
1014
+
1015
+ // we use timeouts so that we do not call the "update" method on *every* step of the resize event
1016
+
1017
+ // clear a previously set timeout
1018
+ clearTimeout(timeout);
1019
+
1020
+ // set timeout again
1021
+ timeout = setTimeout(function() {
1022
+
1023
+ // update the date picker
1024
+ plugin.update();
1025
+
1026
+ }, 100);
1027
+
1028
+ }
1029
+
1030
+ });
1031
+
1032
+ // generate the container that will hold everything
1033
+ var html = '' +
1034
+ '<div class="Zebra_DatePicker">' +
1035
+ '<table class="dp_header">' +
1036
+ '<tr>' +
1037
+ '<td class="dp_previous">' + plugin.settings.header_navigation[0] + '</td>' +
1038
+ '<td class="dp_caption">&#032;</td>' +
1039
+ '<td class="dp_next">' + plugin.settings.header_navigation[1] + '</td>' +
1040
+ '</tr>' +
1041
+ '</table>' +
1042
+ '<table class="dp_daypicker"></table>' +
1043
+ '<table class="dp_monthpicker"></table>' +
1044
+ '<table class="dp_yearpicker"></table>' +
1045
+ '<table class="dp_footer"><tr>' +
1046
+ '<td class="dp_today"' + (plugin.settings.show_clear_date !== false ? ' style="width:50%"' : '') + '>' + show_select_today + '</td>' +
1047
+ '<td class="dp_clear"' + (show_select_today !== false ? ' style="width:50%"' : '') + '>' + plugin.settings.lang_clear_date + '</td>' +
1048
+ '</tr></table>' +
1049
+ '</div>';
1050
+
1051
+ // create a jQuery object out of the HTML above and create a reference to it
1052
+ datepicker = $(html);
1053
+
1054
+ // a reference to the calendar, as a global property
1055
+ plugin.datepicker = datepicker;
1056
+
1057
+ // create references to the different parts of the date picker
1058
+ header = $('table.dp_header', datepicker);
1059
+ daypicker = $('table.dp_daypicker', datepicker);
1060
+ monthpicker = $('table.dp_monthpicker', datepicker);
1061
+ yearpicker = $('table.dp_yearpicker', datepicker);
1062
+ footer = $('table.dp_footer', datepicker);
1063
+ selecttoday = $('td.dp_today', footer);
1064
+ cleardate = $('td.dp_clear', footer);
1065
+
1066
+ // if date picker is not always visible
1067
+ if (!plugin.settings.always_visible)
1068
+
1069
+ // inject the container into the DOM
1070
+ $('body').append(datepicker);
1071
+
1072
+ // otherwise, if element is not disabled
1073
+ else if (!$element.attr('disabled')) {
1074
+
1075
+ // inject the date picker into the designated container element
1076
+ plugin.settings.always_visible.append(datepicker);
1077
+
1078
+ // and make it visible right away
1079
+ plugin.show();
1080
+
1081
+ }
1082
+
1083
+ // add the mouseover/mousevents to all to the date picker's cells
1084
+ // except those that are not selectable
1085
+ datepicker.
1086
+ delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)', 'mouseover', function() {
1087
+ $(this).addClass('dp_hover');
1088
+ }).
1089
+ delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)', 'mouseout', function() {
1090
+ $(this).removeClass('dp_hover');
1091
+ });
1092
+
1093
+ // prevent text highlighting for the text in the header
1094
+ // (for the case when user keeps clicking the "next" and "previous" buttons)
1095
+ disable_text_select($('td', header));
1096
+
1097
+ // event for when clicking the "previous" button
1098
+ $('.dp_previous', header).bind('click', function() {
1099
+
1100
+ // if view is "months"
1101
+ // decrement year by one
1102
+ if (view == 'months') selected_year--;
1103
+
1104
+ // if view is "years"
1105
+ // decrement years by 12
1106
+ else if (view == 'years') selected_year -= 12;
1107
+
1108
+ // if view is "days"
1109
+ // decrement the month and
1110
+ // if month is out of range
1111
+ else if (--selected_month < 0) {
1112
+
1113
+ // go to the last month of the previous year
1114
+ selected_month = 11;
1115
+ selected_year--;
1116
+
1117
+ }
1118
+
1119
+ // generate the appropriate view
1120
+ manage_views();
1121
+
1122
+ });
1123
+
1124
+ // attach a click event to the caption in header
1125
+ $('.dp_caption', header).bind('click', function() {
1126
+
1127
+ // if current view is "days", take the user to the next view, depending on the format
1128
+ if (view == 'days') view = ($.inArray('months', views) > -1 ? 'months' : ($.inArray('years', views) > -1 ? 'years' : 'days'));
1129
+
1130
+ // if current view is "months", take the user to the next view, depending on the format
1131
+ else if (view == 'months') view = ($.inArray('years', views) > -1 ? 'years' : ($.inArray('days', views) > -1 ? 'days' : 'months'));
1132
+
1133
+ // if current view is "years", take the user to the next view, depending on the format
1134
+ else view = ($.inArray('days', views) > -1 ? 'days' : ($.inArray('months', views) > -1 ? 'months' : 'years'));
1135
+
1136
+ // generate the appropriate view
1137
+ manage_views();
1138
+
1139
+ });
1140
+
1141
+ // event for when clicking the "next" button
1142
+ $('.dp_next', header).bind('click', function() {
1143
+
1144
+ // if view is "months"
1145
+ // increment year by 1
1146
+ if (view == 'months') selected_year++;
1147
+
1148
+ // if view is "years"
1149
+ // increment years by 12
1150
+ else if (view == 'years') selected_year += 12;
1151
+
1152
+ // if view is "days"
1153
+ // increment the month and
1154
+ // if month is out of range
1155
+ else if (++selected_month == 12) {
1156
+
1157
+ // go to the first month of the next year
1158
+ selected_month = 0;
1159
+ selected_year++;
1160
+
1161
+ }
1162
+
1163
+ // generate the appropriate view
1164
+ manage_views();
1165
+
1166
+ });
1167
+
1168
+ // attach a click event for the cells in the day picker
1169
+ daypicker.delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)', 'click', function() {
1170
+
1171
+ // if other months are selectable and currently clicked cell contains a class with the cell's date
1172
+ if (plugin.settings.select_other_months && null !== (matches = $(this).attr('class').match(/date\_([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/)))
1173
+
1174
+ // use the stored date
1175
+ select_date(matches[1], matches[2] - 1, matches[3], 'days', $(this));
1176
+
1177
+ // put selected date in the element the plugin is attached to, and hide the date picker
1178
+ else select_date(selected_year, selected_month, to_int($(this).html()), 'days', $(this));
1179
+
1180
+ });
1181
+
1182
+ // attach a click event for the cells in the month picker
1183
+ monthpicker.delegate('td:not(.dp_disabled)', 'click', function() {
1184
+
1185
+ // get the month we've clicked on
1186
+ var matches = $(this).attr('class').match(/dp\_month\_([0-9]+)/);
1187
+
1188
+ // set the selected month
1189
+ selected_month = to_int(matches[1]);
1190
+
1191
+ // if user can select only years and months
1192
+ if ($.inArray('days', views) == -1)
1193
+
1194
+ // put selected date in the element the plugin is attached to, and hide the date picker
1195
+ select_date(selected_year, selected_month, 1, 'months', $(this));
1196
+
1197
+ else {
1198
+
1199
+ // direct the user to the "days" view
1200
+ view = 'days';
1201
+
1202
+ // if date picker is always visible
1203
+ // empty the value in the text box the date picker is attached to
1204
+ if (plugin.settings.always_visible) $element.val('');
1205
+
1206
+ // generate the appropriate view
1207
+ manage_views();
1208
+
1209
+ }
1210
+
1211
+ });
1212
+
1213
+ // attach a click event for the cells in the year picker
1214
+ yearpicker.delegate('td:not(.dp_disabled)', 'click', function() {
1215
+
1216
+ // set the selected year
1217
+ selected_year = to_int($(this).html());
1218
+
1219
+ // if user can select only years
1220
+ if ($.inArray('months', views) == -1)
1221
+
1222
+ // put selected date in the element the plugin is attached to, and hide the date picker
1223
+ select_date(selected_year, 1, 1, 'years', $(this));
1224
+
1225
+ else {
1226
+
1227
+ // direct the user to the "months" view
1228
+ view = 'months';
1229
+
1230
+ // if date picker is always visible
1231
+ // empty the value in the text box the date picker is attached to
1232
+ if (plugin.settings.always_visible) $element.val('');
1233
+
1234
+ // generate the appropriate view
1235
+ manage_views();
1236
+
1237
+ }
1238
+
1239
+ });
1240
+
1241
+ // function to execute when the "Today" button is clicked
1242
+ $(selecttoday).bind('click', function(e) {
1243
+
1244
+ e.preventDefault();
1245
+
1246
+ // select the current date
1247
+ select_date(current_system_year, current_system_month, current_system_day, 'days', $('.dp_current', daypicker));
1248
+
1249
+ // if date picker is always visible
1250
+ if (plugin.settings.always_visible)
1251
+
1252
+ // repaint the datepicker so it centers on the currently selected date
1253
+ plugin.show();
1254
+
1255
+ // hide the date picker
1256
+ plugin.hide();
1257
+
1258
+ });
1259
+
1260
+ // function to execute when the "Clear" button is clicked
1261
+ $(cleardate).bind('click', function(e) {
1262
+
1263
+ e.preventDefault();
1264
+
1265
+ // clear the element's value
1266
+ $element.val('');
1267
+
1268
+ // if date picker is not always visible
1269
+ if (!plugin.settings.always_visible) {
1270
+
1271
+ // reset these values
1272
+ default_day = null; default_month = null; default_year = null; selected_month = null; selected_year = null;
1273
+
1274
+ // if date picker is always visible
1275
+ } else {
1276
+
1277
+ // reset these values
1278
+ default_day = null; default_month = null; default_year = null;
1279
+
1280
+ // remove the "selected" class from all cells that have it
1281
+ $('td.dp_selected', datepicker).removeClass('dp_selected');
1282
+
1283
+ }
1284
+
1285
+ // hide the date picker
1286
+ plugin.hide();
1287
+
1288
+ // if a callback function exists for when clearing a date
1289
+ if (plugin.settings.onClear && typeof plugin.settings.onClear == 'function')
1290
+
1291
+ // execute the callback function and pass as argument the element the plugin is attached to
1292
+ plugin.settings.onClear.call($element, $element);
1293
+
1294
+ });
1295
+
1296
+ // if date picker is not always visible
1297
+ if (!plugin.settings.always_visible)
1298
+
1299
+ // bind some events to the document
1300
+ $(document).bind({
1301
+
1302
+ //whenever anything is clicked on the page
1303
+ 'mousedown.Zebra_DatePicker': function(e) {
1304
+
1305
+ // if the date picker is visible
1306
+ if (datepicker.hasClass('dp_visible')) {
1307
+
1308
+ // if the calendar icon is visible and we clicked it, let the onClick event of the icon to handle the event
1309
+ // (we want it to toggle the date picker)
1310
+ if (plugin.settings.show_icon && $(e.target).get(0) === icon.get(0)) return true;
1311
+
1312
+ // if what's clicked is not inside the date picker
1313
+ // hide the date picker
1314
+ if ($(e.target).parents().filter('.Zebra_DatePicker').length === 0) plugin.hide();
1315
+
1316
+ }
1317
+
1318
+ },
1319
+
1320
+ //whenever a key is pressed on the page
1321
+ 'keyup.Zebra_DatePicker': function(e) {
1322
+
1323
+ // if the date picker is visible
1324
+ // and the pressed key is ESC
1325
+ // hide the date picker
1326
+ if (datepicker.hasClass('dp_visible') && e.which == 27) plugin.hide();
1327
+
1328
+ }
1329
+
1330
+ });
1331
+
1332
+ // last thing is to pre-render some of the date picker right away
1333
+ manage_views();
1334
+
1335
+ };
1336
+
1337
+ /**
1338
+ * Destroys the date picker.
1339
+ *
1340
+ * @return void
1341
+ */
1342
+ plugin.destroy = function() {
1343
+
1344
+ // remove the attached icon (if it exists)...
1345
+ if (undefined !== plugin.icon) plugin.icon.remove();
1346
+
1347
+ // ...and the calendar
1348
+ plugin.datepicker.remove();
1349
+
1350
+ // remove associated event handlers from the document
1351
+ $(document).unbind('keyup.Zebra_DatePicker');
1352
+ $(document).unbind('mousedown.Zebra_DatePicker');
1353
+ $(window).unbind('resize.Zebra_DatePicker');
1354
+
1355
+ // remove association with the element
1356
+ $element.removeData('Zebra_DatePicker');
1357
+
1358
+ };
1359
+
1360
+ /**
1361
+ * Hides the date picker.
1362
+ *
1363
+ * @return void
1364
+ */
1365
+ plugin.hide = function() {
1366
+
1367
+ // if date picker is not always visible
1368
+ if (!plugin.settings.always_visible) {
1369
+
1370
+ // hide the iFrameShim in Internet Explorer 6
1371
+ iframeShim('hide');
1372
+
1373
+ // hide the date picker
1374
+ datepicker.removeClass('dp_visible').addClass('dp_hidden');
1375
+
1376
+ }
1377
+
1378
+ };
1379
+
1380
+ /**
1381
+ * Shows the date picker.
1382
+ *
1383
+ * @return void
1384
+ */
1385
+ plugin.show = function() {
1386
+
1387
+ // always show the view defined in settings
1388
+ view = plugin.settings.view;
1389
+
1390
+ // get the default date, from the element, and check if it represents a valid date, according to the required format
1391
+ var default_date = check_date($element.val() || (plugin.settings.start_date ? plugin.settings.start_date : ''));
1392
+
1393
+ // if the value represents a valid date
1394
+ if (default_date) {
1395
+
1396
+ // extract the date parts
1397
+ // we'll use these to highlight the default date in the date picker and as starting point to
1398
+ // what year and month to start the date picker with
1399
+ // why separate values? because selected_* will change as user navigates within the date picker
1400
+ default_month = default_date.getMonth();
1401
+ selected_month = default_date.getMonth();
1402
+ default_year = default_date.getFullYear();
1403
+ selected_year = default_date.getFullYear();
1404
+ default_day = default_date.getDate();
1405
+
1406
+ // if the default date represents a disabled date
1407
+ if (is_disabled(default_year, default_month, default_day)) {
1408
+
1409
+ // if date picker is in "strict" mode, clear the value of the parent element
1410
+ if (plugin.settings.strict) $element.val('');
1411
+
1412
+ // the calendar will start with the first selectable year/month
1413
+ selected_month = first_selectable_month;
1414
+ selected_year = first_selectable_year;
1415
+
1416
+ }
1417
+
1418
+ // if a default value is not available, or value does not represent a valid date
1419
+ } else {
1420
+
1421
+ // the calendar will start with the first selectable year/month
1422
+ selected_month = first_selectable_month;
1423
+ selected_year = first_selectable_year;
1424
+
1425
+ }
1426
+
1427
+ // generate the appropriate view
1428
+ manage_views();
1429
+
1430
+ // if date picker is not always visible and the calendar icon is visible
1431
+ if (!plugin.settings.always_visible) {
1432
+
1433
+ var
1434
+
1435
+ // get the date picker width and height
1436
+ datepicker_width = datepicker.outerWidth(),
1437
+ datepicker_height = datepicker.outerHeight(),
1438
+
1439
+ // compute the date picker's default left and top
1440
+ // this will be computed relative to the icon's top-right corner (if the calendar icon exists), or
1441
+ // relative to the element's top-right corner otherwise, to which the offsets given at initialization
1442
+ // are added/subtracted
1443
+ left = (undefined !== icon ? icon.offset().left + icon.outerWidth(true) : $element.offset().left + $element.outerWidth(true)) + plugin.settings.offset[0],
1444
+ top = (undefined !== icon ? icon.offset().top : $element.offset().top) - datepicker_height + plugin.settings.offset[1],
1445
+
1446
+ // get browser window's width and height
1447
+ window_width = $(window).width(),
1448
+ window_height = $(window).height(),
1449
+
1450
+ // get browser window's horizontal and vertical scroll offsets
1451
+ window_scroll_top = $(window).scrollTop(),
1452
+ window_scroll_left = $(window).scrollLeft();
1453
+
1454
+ if (plugin.settings.default_position == 'below')
1455
+ top = (undefined !== icon ? icon.offset().top : $element.offset().top) + plugin.settings.offset[1];
1456
+
1457
+ // if date picker is outside the viewport, adjust its position so that it is visible
1458
+ if (left + datepicker_width > window_scroll_left + window_width) left = window_scroll_left + window_width - datepicker_width;
1459
+ if (left < window_scroll_left) left = window_scroll_left;
1460
+
1461
+ if (top + datepicker_height > window_scroll_top + window_height) top = window_scroll_top + window_height - datepicker_height;
1462
+ if (top < window_scroll_top) top = window_scroll_top;
1463
+
1464
+ // make the date picker visible
1465
+ datepicker.css({
1466
+ 'left': left,
1467
+ 'top': top
1468
+ });
1469
+
1470
+ // fade-in the date picker
1471
+ // for Internet Explorer < 9 show the date picker instantly or fading alters the font's weight
1472
+ datepicker.removeClass('dp_hidden').addClass('dp_visible');
1473
+
1474
+ // show the iFrameShim in Internet Explorer 6
1475
+ iframeShim();
1476
+
1477
+ // if date picker is always visible, show it
1478
+ } else datepicker.removeClass('dp_hidden').addClass('dp_visible');
1479
+
1480
+ // if a callback function exists for when showing the date picker
1481
+ if (plugin.settings.onOpen && typeof plugin.settings.onOpen == 'function')
1482
+
1483
+ // execute the callback function and pass as argument the element the plugin is attached to
1484
+ plugin.settings.onOpen.call($element, $element);
1485
+
1486
+ };
1487
+
1488
+ /**
1489
+ * Updates the configuration options given as argument
1490
+ *
1491
+ * @param object values An object containing any number of configuration options to be updated
1492
+ *
1493
+ * @return void
1494
+ */
1495
+ plugin.update = function(values) {
1496
+
1497
+ // if original direction not saved, save it now
1498
+ if (plugin.original_direction) plugin.original_direction = plugin.direction;
1499
+
1500
+ // update configuration options
1501
+ plugin.settings = $.extend(plugin.settings, values);
1502
+
1503
+ // reinitialize the object with the new options
1504
+ init(true);
1505
+
1506
+ };
1507
+
1508
+ /**
1509
+ * Checks if a string represents a valid date according to the format defined by the "format" property.
1510
+ *
1511
+ * @param string str_date A string representing a date, formatted accordingly to the "format" property.
1512
+ * For example, if "format" is "Y-m-d" the string should look like "2011-06-01"
1513
+ *
1514
+ * @return mixed Returns a JavaScript Date object if string represents a valid date according
1515
+ * formatted according to the "format" property, or FALSE otherwise.
1516
+ *
1517
+ * @access private
1518
+ */
1519
+ var check_date = function(str_date) {
1520
+
1521
+ // treat argument as a string
1522
+ str_date += '';
1523
+
1524
+ // if value is given
1525
+ if ($.trim(str_date) !== '') {
1526
+
1527
+ var
1528
+
1529
+ // prepare the format by removing white space from it
1530
+ // and also escape characters that could have special meaning in a regular expression
1531
+ format = escape_regexp(plugin.settings.format),
1532
+
1533
+ // allowed characters in date's format
1534
+ format_chars = ['d','D','j','l','N','S','w','F','m','M','n','Y','y'],
1535
+
1536
+ // "matches" will contain the characters defining the date's format
1537
+ matches = [],
1538
+
1539
+ // "regexp" will contain the regular expression built for each of the characters used in the date's format
1540
+ regexp = [],
1541
+
1542
+ // "position" will contain the position of the caracter found in the date's format
1543
+ position = null,
1544
+
1545
+ // "segments" will contain the matches of the regular expression
1546
+ segments = null;
1547
+
1548
+ // iterate through the allowed characters in date's format
1549
+ for (var i = 0; i < format_chars.length; i++)
1550
+
1551
+ // if character is found in the date's format
1552
+ if ((position = format.indexOf(format_chars[i])) > -1)
1553
+
1554
+ // save it, alongside the character's position
1555
+ matches.push({character: format_chars[i], position: position});
1556
+
1557
+ // sort characters defining the date's format based on their position, ascending
1558
+ matches.sort(function(a, b){ return a.position - b.position; });
1559
+
1560
+ // iterate through the characters defining the date's format
1561
+ $.each(matches, function(index, match) {
1562
+
1563
+ // add to the array of regular expressions, based on the character
1564
+ switch (match.character) {
1565
+
1566
+ case 'd': regexp.push('0[1-9]|[12][0-9]|3[01]'); break;
1567
+ case 'D': regexp.push('[a-z]{3}'); break;
1568
+ case 'j': regexp.push('[1-9]|[12][0-9]|3[01]'); break;
1569
+ case 'l': regexp.push('[a-z]+'); break;
1570
+ case 'N': regexp.push('[1-7]'); break;
1571
+ case 'S': regexp.push('st|nd|rd|th'); break;
1572
+ case 'w': regexp.push('[0-6]'); break;
1573
+ case 'F': regexp.push('[a-z]+'); break;
1574
+ case 'm': regexp.push('0[1-9]|1[012]+'); break;
1575
+ case 'M': regexp.push('[a-z]{3}'); break;
1576
+ case 'n': regexp.push('[1-9]|1[012]'); break;
1577
+ case 'Y': regexp.push('[0-9]{4}'); break;
1578
+ case 'y': regexp.push('[0-9]{2}'); break;
1579
+
1580
+ }
1581
+
1582
+ });
1583
+
1584
+ // if we have an array of regular expressions
1585
+ if (regexp.length) {
1586
+
1587
+ // we will replace characters in the date's format in reversed order
1588
+ matches.reverse();
1589
+
1590
+ // iterate through the characters in date's format
1591
+ $.each(matches, function(index, match) {
1592
+
1593
+ // replace each character with the appropriate regular expression
1594
+ format = format.replace(match.character, '(' + regexp[regexp.length - index - 1] + ')');
1595
+
1596
+ });
1597
+
1598
+ // the final regular expression
1599
+ regexp = new RegExp('^' + format + '$', 'ig');
1600
+
1601
+ // if regular expression was matched
1602
+ if ((segments = regexp.exec(str_date))) {
1603
+
1604
+ // check if date is a valid date (i.e. there's no February 31)
1605
+
1606
+ var tmpdate = new Date(),
1607
+ original_day = 1,
1608
+ original_month = tmpdate.getMonth() + 1,
1609
+ original_year = tmpdate.getFullYear(),
1610
+ english_days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
1611
+ english_months = ['January','February','March','April','May','June','July','August','September','October','November','December'],
1612
+ iterable,
1613
+
1614
+ // by default, we assume the date is valid
1615
+ valid = true;
1616
+
1617
+ // reverse back the characters in the date's format
1618
+ matches.reverse();
1619
+
1620
+ // iterate through the characters in the date's format
1621
+ $.each(matches, function(index, match) {
1622
+
1623
+ // if the date is not valid, don't look further
1624
+ if (!valid) return true;
1625
+
1626
+ // based on the character
1627
+ switch (match.character) {
1628
+
1629
+ case 'm':
1630
+ case 'n':
1631
+
1632
+ // extract the month from the value entered by the user
1633
+ original_month = to_int(segments[index + 1]);
1634
+
1635
+ break;
1636
+
1637
+ case 'd':
1638
+ case 'j':
1639
+
1640
+ // extract the day from the value entered by the user
1641
+ original_day = to_int(segments[index + 1]);
1642
+
1643
+ break;
1644
+
1645
+ case 'D':
1646
+ case 'l':
1647
+ case 'F':
1648
+ case 'M':
1649
+
1650
+ // if day is given as day name, we'll check against the names in the used language
1651
+ if (match.character == 'D' || match.character == 'l') iterable = plugin.settings.days;
1652
+
1653
+ // if month is given as month name, we'll check against the names in the used language
1654
+ else iterable = plugin.settings.months;
1655
+
1656
+ // by default, we assume the day or month was not entered correctly
1657
+ valid = false;
1658
+
1659
+ // iterate through the month/days in the used language
1660
+ $.each(iterable, function(key, value) {
1661
+
1662
+ // if month/day was entered correctly, don't look further
1663
+ if (valid) return true;
1664
+
1665
+ // if month/day was entered correctly
1666
+ if (segments[index + 1].toLowerCase() == value.substring(0, (match.character == 'D' || match.character == 'M' ? 3 : value.length)).toLowerCase()) {
1667
+
1668
+ // extract the day/month from the value entered by the user
1669
+ switch (match.character) {
1670
+
1671
+ case 'D': segments[index + 1] = english_days[key].substring(0, 3); break;
1672
+ case 'l': segments[index + 1] = english_days[key]; break;
1673
+ case 'F': segments[index + 1] = english_months[key]; original_month = key + 1; break;
1674
+ case 'M': segments[index + 1] = english_months[key].substring(0, 3); original_month = key + 1; break;
1675
+
1676
+ }
1677
+
1678
+ // day/month value is valid
1679
+ valid = true;
1680
+
1681
+ }
1682
+
1683
+ });
1684
+
1685
+ break;
1686
+
1687
+ case 'Y':
1688
+
1689
+ // extract the year from the value entered by the user
1690
+ original_year = to_int(segments[index + 1]);
1691
+
1692
+ break;
1693
+
1694
+ case 'y':
1695
+
1696
+ // extract the year from the value entered by the user
1697
+ original_year = '19' + to_int(segments[index + 1]);
1698
+
1699
+ break;
1700
+
1701
+ }
1702
+ });
1703
+
1704
+ // if everything is ok so far
1705
+ if (valid) {
1706
+
1707
+ // generate a Date object using the values entered by the user
1708
+ // (handle also the case when original_month and/or original_day are undefined - i.e date format is "Y-m" or "Y")
1709
+ var date = new Date(original_year, (original_month || 1) - 1, original_day || 1);
1710
+
1711
+ // if, after that, the date is the same as the date entered by the user
1712
+ if (date.getFullYear() == original_year && date.getDate() == (original_day || 1) && date.getMonth() == ((original_month || 1) - 1))
1713
+
1714
+ // return the date as JavaScript date object
1715
+ return date;
1716
+
1717
+ }
1718
+
1719
+ }
1720
+
1721
+ }
1722
+
1723
+ // if script gets this far, return false as something must've went wrong
1724
+ return false;
1725
+
1726
+ }
1727
+
1728
+ };
1729
+
1730
+ /**
1731
+ * Prevents the possibility of selecting text on a given element. Used on the "previous" and "next" buttons
1732
+ * where text might get accidentally selected when user quickly clicks on the buttons.
1733
+ *
1734
+ * Code by http://chris-barr.com/index.php/entry/disable_text_selection_with_jquery/
1735
+ *
1736
+ * @param jQuery Element el A jQuery element on which to prevents text selection.
1737
+ *
1738
+ * @return void
1739
+ *
1740
+ * @access private
1741
+ */
1742
+ var disable_text_select = function(el) {
1743
+
1744
+ // if browser is Firefox
1745
+ if (browser.name == 'firefox') el.css('MozUserSelect', 'none');
1746
+
1747
+ // if browser is Internet Explorer
1748
+ else if (browser.name == 'explorer') el.bind('selectstart', function() { return false; });
1749
+
1750
+ // for the other browsers
1751
+ else el.mousedown(function() { return false; });
1752
+
1753
+ };
1754
+
1755
+ /**
1756
+ * Escapes special characters in a string, preparing it for use in a regular expression.
1757
+ *
1758
+ * @param string str The string in which special characters should be escaped.
1759
+ *
1760
+ * @return string Returns the string with escaped special characters.
1761
+ *
1762
+ * @access private
1763
+ */
1764
+ var escape_regexp = function(str) {
1765
+
1766
+ // return string with special characters escaped
1767
+ return str.replace(/([-.,*+?^${}()|[\]\/\\])/g, '\\$1');
1768
+
1769
+ };
1770
+
1771
+ /**
1772
+ * Formats a JavaScript date object to the format specified by the "format" property.
1773
+ * Code taken from http://electricprism.com/aeron/calendar/
1774
+ *
1775
+ * @param date date A valid JavaScript date object
1776
+ *
1777
+ * @return string Returns a string containing the formatted date
1778
+ *
1779
+ * @access private
1780
+ */
1781
+ var format = function(date) {
1782
+
1783
+ var result = '',
1784
+
1785
+ // extract parts of the date:
1786
+ // day number, 1 - 31
1787
+ j = date.getDate(),
1788
+
1789
+ // day of the week, 0 - 6, Sunday - Saturday
1790
+ w = date.getDay(),
1791
+
1792
+ // the name of the day of the week Sunday - Saturday
1793
+ l = plugin.settings.days[w],
1794
+
1795
+ // the month number, 1 - 12
1796
+ n = date.getMonth() + 1,
1797
+
1798
+ // the month name, January - December
1799
+ f = plugin.settings.months[n - 1],
1800
+
1801
+ // the year (as a string)
1802
+ y = date.getFullYear() + '';
1803
+
1804
+ // iterate through the characters in the format
1805
+ for (var i = 0; i < plugin.settings.format.length; i++) {
1806
+
1807
+ // extract the current character
1808
+ var chr = plugin.settings.format.charAt(i);
1809
+
1810
+ // see what character it is
1811
+ switch(chr) {
1812
+
1813
+ // year as two digits
1814
+ case 'y': y = y.substr(2);
1815
+
1816
+ // year as four digits
1817
+ case 'Y': result += y; break;
1818
+
1819
+ // month number, prefixed with 0
1820
+ case 'm': n = str_pad(n, 2);
1821
+
1822
+ // month number, not prefixed with 0
1823
+ case 'n': result += n; break;
1824
+
1825
+ // month name, three letters
1826
+ case 'M': f = ($.isArray(plugin.settings.months_abbr) && undefined !== plugin.settings.months_abbr[n - 1] ? plugin.settings.months_abbr[n - 1] : plugin.settings.months[n - 1].substr(0, 3));
1827
+
1828
+ // full month name
1829
+ case 'F': result += f; break;
1830
+
1831
+ // day number, prefixed with 0
1832
+ case 'd': j = str_pad(j, 2);
1833
+
1834
+ // day number not prefixed with 0
1835
+ case 'j': result += j; break;
1836
+
1837
+ // day name, three letters
1838
+ case 'D': l = ($.isArray(plugin.settings.days_abbr) && undefined !== plugin.settings.days_abbr[w] ? plugin.settings.days_abbr[w] : plugin.settings.days[w].substr(0, 3));
1839
+
1840
+ // full day name
1841
+ case 'l': result += l; break;
1842
+
1843
+ // ISO-8601 numeric representation of the day of the week, 1 - 7
1844
+ case 'N': w++;
1845
+
1846
+ // day of the week, 0 - 6
1847
+ case 'w': result += w; break;
1848
+
1849
+ // English ordinal suffix for the day of the month, 2 characters
1850
+ // (st, nd, rd or th (works well with j))
1851
+ case 'S':
1852
+
1853
+ if (j % 10 == 1 && j != '11') result += 'st';
1854
+
1855
+ else if (j % 10 == 2 && j != '12') result += 'nd';
1856
+
1857
+ else if (j % 10 == 3 && j != '13') result += 'rd';
1858
+
1859
+ else result += 'th';
1860
+
1861
+ break;
1862
+
1863
+ // this is probably the separator
1864
+ default: result += chr;
1865
+
1866
+ }
1867
+
1868
+ }
1869
+
1870
+ // return formated date
1871
+ return result;
1872
+
1873
+ };
1874
+
1875
+ /**
1876
+ * Generates the day picker view, and displays it
1877
+ *
1878
+ * @return void
1879
+ *
1880
+ * @access private
1881
+ */
1882
+ var generate_daypicker = function() {
1883
+
1884
+ var
1885
+
1886
+ // get the number of days in the selected month
1887
+ days_in_month = new Date(selected_year, selected_month + 1, 0).getDate(),
1888
+
1889
+ // get the selected month's starting day (from 0 to 6)
1890
+ first_day = new Date(selected_year, selected_month, 1).getDay(),
1891
+
1892
+ // how many days are there in the previous month
1893
+ days_in_previous_month = new Date(selected_year, selected_month, 0).getDate(),
1894
+
1895
+ // how many days are there to be shown from the previous month
1896
+ days_from_previous_month = first_day - plugin.settings.first_day_of_week;
1897
+
1898
+ // the final value of how many days are there to be shown from the previous month
1899
+ days_from_previous_month = days_from_previous_month < 0 ? 7 + days_from_previous_month : days_from_previous_month;
1900
+
1901
+ // manage header caption and enable/disable navigation buttons if necessary
1902
+ manage_header(plugin.settings.header_captions['days']);
1903
+
1904
+ // start generating the HTML
1905
+ var html = '<tr>';
1906
+
1907
+ // if a column featuring the number of the week is to be shown
1908
+ if (plugin.settings.show_week_number)
1909
+
1910
+ // column title
1911
+ html += '<th>' + plugin.settings.show_week_number + '</th>';
1912
+
1913
+ // name of week days
1914
+ // show the abbreviated day names (or only the first two letters of the full name if no abbreviations are specified)
1915
+ // and also, take in account the value of the "first_day_of_week" property
1916
+ for (var i = 0; i < 7; i++)
1917
+
1918
+ html += '<th>' + ($.isArray(plugin.settings.days_abbr) && undefined !== plugin.settings.days_abbr[(plugin.settings.first_day_of_week + i) % 7] ? plugin.settings.days_abbr[(plugin.settings.first_day_of_week + i) % 7] : plugin.settings.days[(plugin.settings.first_day_of_week + i) % 7].substr(0, 2)) + '</th>';
1919
+
1920
+ html += '</tr><tr>';
1921
+
1922
+ // the calendar shows a total of 42 days
1923
+ for (i = 0; i < 42; i++) {
1924
+
1925
+ // seven days per row
1926
+ if (i > 0 && i % 7 === 0) html += '</tr><tr>';
1927
+
1928
+ // if week number is to be shown
1929
+ if (i % 7 === 0 && plugin.settings.show_week_number)
1930
+
1931
+ // show ISO 8601 week number
1932
+ html += '<td class="dp_week_number">' + getWeekNumber(new Date(selected_year, selected_month, (i - days_from_previous_month + 1))) + '</td>';
1933
+
1934
+ // the number of the day in month
1935
+ var day = (i - days_from_previous_month + 1);
1936
+
1937
+ // if dates in previous/next month can be selected, and this is one of those days
1938
+ if (plugin.settings.select_other_months && (i < days_from_previous_month || day > days_in_month)) {
1939
+
1940
+ // use the Date object to normalize the date
1941
+ // for example, 2011 05 33 will be transformed to 2011 06 02
1942
+ var real_date = new Date(selected_year, selected_month, day),
1943
+ real_year = real_date.getFullYear(),
1944
+ real_month = real_date.getMonth(),
1945
+ real_day = real_date.getDate();
1946
+
1947
+ // extract normalized date parts and merge them
1948
+ real_date = real_year + str_pad(real_month + 1, 2) + str_pad(real_day, 2);
1949
+
1950
+ }
1951
+
1952
+ // if this is a day from the previous month
1953
+ if (i < days_from_previous_month)
1954
+
1955
+ html += '<td class="' + (plugin.settings.select_other_months && !is_disabled(real_year, real_month, real_day) ? 'dp_not_in_month_selectable date_' + real_date : 'dp_not_in_month') + '">' + (plugin.settings.select_other_months || plugin.settings.show_other_months ? str_pad(days_in_previous_month - days_from_previous_month + i + 1, plugin.settings.zero_pad ? 2 : 0) : '&nbsp;') + '</td>';
1956
+
1957
+ // if this is a day from the next month
1958
+ else if (day > days_in_month)
1959
+
1960
+ html += '<td class="' + (plugin.settings.select_other_months && !is_disabled(real_year, real_month, real_day) ? 'dp_not_in_month_selectable date_' + real_date : 'dp_not_in_month') + '">' + (plugin.settings.select_other_months || plugin.settings.show_other_months ? str_pad(day - days_in_month, plugin.settings.zero_pad ? 2 : 0) : '&nbsp;') + '</td>';
1961
+
1962
+ // if this is a day from the current month
1963
+ else {
1964
+
1965
+ var
1966
+
1967
+ // get the week day (0 to 6, Sunday to Saturday)
1968
+ weekday = (plugin.settings.first_day_of_week + i) % 7,
1969
+
1970
+ class_name = '';
1971
+
1972
+ // if date needs to be disabled
1973
+ if (is_disabled(selected_year, selected_month, day)) {
1974
+
1975
+ // if day is in weekend
1976
+ if ($.inArray(weekday, plugin.settings.weekend_days) > -1) class_name = 'dp_weekend_disabled';
1977
+
1978
+ // if work day
1979
+ else class_name += ' dp_disabled';
1980
+
1981
+ // highlight the current system date
1982
+ if (selected_month == current_system_month && selected_year == current_system_year && current_system_day == day) class_name += ' dp_disabled_current';
1983
+
1984
+ // if there are no restrictions
1985
+ } else {
1986
+
1987
+ // if day is in weekend
1988
+ if ($.inArray(weekday, plugin.settings.weekend_days) > -1) class_name = 'dp_weekend';
1989
+
1990
+ // highlight the currently selected date
1991
+ if (selected_month == default_month && selected_year == default_year && default_day == day) class_name += ' dp_selected';
1992
+
1993
+ // highlight the current system date
1994
+ if (selected_month == current_system_month && selected_year == current_system_year && current_system_day == day) class_name += ' dp_current';
1995
+
1996
+ }
1997
+
1998
+ // print the day of the month
1999
+ html += '<td' + (class_name !== '' ? ' class="' + $.trim(class_name) + '"' : '') + '>' + (plugin.settings.zero_pad ? str_pad(day, 2) : day) + '</td>';
2000
+
2001
+ }
2002
+
2003
+ }
2004
+
2005
+ // wrap up generating the day picker
2006
+ html += '</tr>';
2007
+
2008
+ // inject the day picker into the DOM
2009
+ daypicker.html($(html));
2010
+
2011
+ // if date picker is always visible
2012
+ if (plugin.settings.always_visible)
2013
+
2014
+ // cache all the cells
2015
+ // (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a date)
2016
+ daypicker_cells = $('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)', daypicker);
2017
+
2018
+ // make the day picker visible
2019
+ daypicker.show();
2020
+
2021
+ };
2022
+
2023
+ /**
2024
+ * Generates the month picker view, and displays it
2025
+ *
2026
+ * @return void
2027
+ *
2028
+ * @access private
2029
+ */
2030
+ var generate_monthpicker = function() {
2031
+
2032
+ // manage header caption and enable/disable navigation buttons if necessary
2033
+ manage_header(plugin.settings.header_captions['months']);
2034
+
2035
+ // start generating the HTML
2036
+ var html = '<tr>';
2037
+
2038
+ // iterate through all the months
2039
+ for (var i = 0; i < 12; i++) {
2040
+
2041
+ // three month per row
2042
+ if (i > 0 && i % 3 === 0) html += '</tr><tr>';
2043
+
2044
+ var class_name = 'dp_month_' + i;
2045
+
2046
+ // if month needs to be disabled
2047
+ if (is_disabled(selected_year, i)) class_name += ' dp_disabled';
2048
+
2049
+ // else, if a date is already selected and this is that particular month, highlight it
2050
+ else if (default_month !== false && default_month == i && selected_year == default_year) class_name += ' dp_selected';
2051
+
2052
+ // else, if this the current system month, highlight it
2053
+ else if (current_system_month == i && current_system_year == selected_year) class_name += ' dp_current';
2054
+
2055
+ // first three letters of the month's name
2056
+ html += '<td class="' + $.trim(class_name) + '">' + ($.isArray(plugin.settings.months_abbr) && undefined !== plugin.settings.months_abbr[i] ? plugin.settings.months_abbr[i] : plugin.settings.months[i].substr(0, 3)) + '</td>';
2057
+
2058
+ }
2059
+
2060
+ // wrap up
2061
+ html += '</tr>';
2062
+
2063
+ // inject into the DOM
2064
+ monthpicker.html($(html));
2065
+
2066
+ // if date picker is always visible
2067
+ if (plugin.settings.always_visible)
2068
+
2069
+ // cache all the cells
2070
+ // (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a month)
2071
+ monthpicker_cells = $('td:not(.dp_disabled)', monthpicker);
2072
+
2073
+ // make the month picker visible
2074
+ monthpicker.show();
2075
+
2076
+ };
2077
+
2078
+ /**
2079
+ * Generates the year picker view, and displays it
2080
+ *
2081
+ * @return void
2082
+ *
2083
+ * @access private
2084
+ */
2085
+ var generate_yearpicker = function() {
2086
+
2087
+ // manage header caption and enable/disable navigation buttons if necessary
2088
+ manage_header(plugin.settings.header_captions['years']);
2089
+
2090
+ // start generating the HTML
2091
+ var html = '<tr>';
2092
+
2093
+ // we're showing 9 years at a time, current year in the middle
2094
+ for (var i = 0; i < 12; i++) {
2095
+
2096
+ // three years per row
2097
+ if (i > 0 && i % 3 === 0) html += '</tr><tr>';
2098
+
2099
+ var class_name = '';
2100
+
2101
+ // if year needs to be disabled
2102
+ if (is_disabled(selected_year - 7 + i)) class_name += ' dp_disabled';
2103
+
2104
+ // else, if a date is already selected and this is that particular year, highlight it
2105
+ else if (default_year && default_year == selected_year - 7 + i) class_name += ' dp_selected';
2106
+
2107
+ // else, if this is the current system year, highlight it
2108
+ else if (current_system_year == (selected_year - 7 + i)) class_name += ' dp_current';
2109
+
2110
+ // first three letters of the month's name
2111
+ html += '<td' + ($.trim(class_name) !== '' ? ' class="' + $.trim(class_name) + '"' : '') + '>' + (selected_year - 7 + i) + '</td>';
2112
+
2113
+ }
2114
+
2115
+ // wrap up
2116
+ html += '</tr>';
2117
+
2118
+ // inject into the DOM
2119
+ yearpicker.html($(html));
2120
+
2121
+ // if date picker is always visible
2122
+ if (plugin.settings.always_visible)
2123
+
2124
+ // cache all the cells
2125
+ // (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a year)
2126
+ yearpicker_cells = $('td:not(.dp_disabled)', yearpicker);
2127
+
2128
+ // make the year picker visible
2129
+ yearpicker.show();
2130
+
2131
+ };
2132
+
2133
+ /**
2134
+ * Generates an iFrame shim in Internet Explorer 6 so that the date picker appears above select boxes.
2135
+ *
2136
+ * @return void
2137
+ *
2138
+ * @access private
2139
+ */
2140
+ var iframeShim = function(action) {
2141
+
2142
+ // this is necessary only if browser is Internet Explorer 6
2143
+ if (browser.name == 'explorer' && browser.version == 6) {
2144
+
2145
+ // if the iFrame was not yet created
2146
+ // "undefined" evaluates as FALSE
2147
+ if (!shim) {
2148
+
2149
+ // the iFrame has to have the element's zIndex minus 1
2150
+ var zIndex = to_int(datepicker.css('zIndex')) - 1;
2151
+
2152
+ // create the iFrame
2153
+ shim = $('<iframe>', {
2154
+ 'src': 'javascript:document.write("")',
2155
+ 'scrolling': 'no',
2156
+ 'frameborder': 0,
2157
+ css: {
2158
+ 'zIndex': zIndex,
2159
+ 'position': 'absolute',
2160
+ 'top': -1000,
2161
+ 'left': -1000,
2162
+ 'width': datepicker.outerWidth(),
2163
+ 'height': datepicker.outerHeight(),
2164
+ 'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)',
2165
+ 'display': 'none'
2166
+ }
2167
+ });
2168
+
2169
+ // inject iFrame into DOM
2170
+ $('body').append(shim);
2171
+
2172
+ }
2173
+
2174
+ // what do we need to do
2175
+ switch (action) {
2176
+
2177
+ // hide the iFrame?
2178
+ case 'hide':
2179
+
2180
+ // set the iFrame's display property to "none"
2181
+ shim.hide();
2182
+
2183
+ break;
2184
+
2185
+ // show the iFrame?
2186
+ default:
2187
+
2188
+ // get date picker top and left position
2189
+ var offset = datepicker.offset();
2190
+
2191
+ // position the iFrame shim right underneath the date picker
2192
+ // and set its display to "block"
2193
+ shim.css({
2194
+ 'top': offset.top,
2195
+ 'left': offset.left,
2196
+ 'display': 'block'
2197
+ });
2198
+
2199
+ }
2200
+
2201
+ }
2202
+
2203
+ };
2204
+
2205
+ /**
2206
+ * Checks if, according to the restrictions of the calendar and/or the values defined by the "disabled_dates"
2207
+ * property, a day, a month or a year needs to be disabled.
2208
+ *
2209
+ * @param integer year The year to check
2210
+ * @param integer month The month to check
2211
+ * @param integer day The day to check
2212
+ *
2213
+ * @return boolean Returns TRUE if the given value is not disabled or FALSE otherwise
2214
+ *
2215
+ * @access private
2216
+ */
2217
+ var is_disabled = function(year, month, day) {
2218
+
2219
+ // don't check bogus values
2220
+ if ((undefined === year || isNaN(year)) && (undefined === month || isNaN(month)) && (undefined === day || isNaN(day))) return false;
2221
+
2222
+ // if calendar has direction restrictions
2223
+ if (!(!$.isArray(plugin.settings.direction) && to_int(plugin.settings.direction) === 0)) {
2224
+
2225
+ var
2226
+ // normalize and merge arguments then transform the result to an integer
2227
+ now = to_int(str_concat(year, (typeof month != 'undefined' ? str_pad(month, 2) : ''), (typeof day != 'undefined' ? str_pad(day, 2) : ''))),
2228
+
2229
+ // get the length of the argument
2230
+ len = (now + '').length;
2231
+
2232
+ // if we're checking days
2233
+ if (len == 8 && (
2234
+
2235
+ // day is before the first selectable date
2236
+ (typeof start_date != 'undefined' && now < to_int(str_concat(first_selectable_year, str_pad(first_selectable_month, 2), str_pad(first_selectable_day, 2)))) ||
2237
+
2238
+ // or day is after the last selectable date
2239
+ (typeof end_date != 'undefined' && now > to_int(str_concat(last_selectable_year, str_pad(last_selectable_month, 2), str_pad(last_selectable_day, 2))))
2240
+
2241
+ // day needs to be disabled
2242
+ )) return true;
2243
+
2244
+ // if we're checking months
2245
+ else if (len == 6 && (
2246
+
2247
+ // month is before the first selectable month
2248
+ (typeof start_date != 'undefined' && now < to_int(str_concat(first_selectable_year, str_pad(first_selectable_month, 2)))) ||
2249
+
2250
+ // or day is after the last selectable date
2251
+ (typeof end_date != 'undefined' && now > to_int(str_concat(last_selectable_year, str_pad(last_selectable_month, 2))))
2252
+
2253
+ // month needs to be disabled
2254
+ )) return true;
2255
+
2256
+ // if we're checking years
2257
+ else if (len == 4 && (
2258
+
2259
+ // year is before the first selectable year
2260
+ (typeof start_date != 'undefined' && now < first_selectable_year) ||
2261
+
2262
+ // or day is after the last selectable date
2263
+ (typeof end_date != 'undefined' && now > last_selectable_year)
2264
+
2265
+ // year needs to be disabled
2266
+ )) return true;
2267
+
2268
+ }
2269
+
2270
+ // if month is given as argument, increment it (as JavaScript uses 0 for January, 1 for February...)
2271
+ if (typeof month != 'undefined') month = month + 1;
2272
+
2273
+ // by default, we assume the day/month/year is not enabled nor disabled
2274
+ var disabled = false, enabled = false;
2275
+
2276
+ // if there are rules for disabling dates
2277
+ if (disabled_dates)
2278
+
2279
+ // iterate through the rules for disabling dates
2280
+ $.each(disabled_dates, function() {
2281
+
2282
+ // if the date is to be disabled, don't look any further
2283
+ if (disabled) return;
2284
+
2285
+ var rule = this;
2286
+
2287
+ // if the rules apply for the current year
2288
+ if ($.inArray(year, rule[2]) > -1 || $.inArray('*', rule[2]) > -1)
2289
+
2290
+ // if the rules apply for the current month
2291
+ if ((typeof month != 'undefined' && $.inArray(month, rule[1]) > -1) || $.inArray('*', rule[1]) > -1)
2292
+
2293
+ // if the rules apply for the current day
2294
+ if ((typeof day != 'undefined' && $.inArray(day, rule[0]) > -1) || $.inArray('*', rule[0]) > -1) {
2295
+
2296
+ // if day is to be disabled whatever the day
2297
+ // don't look any further
2298
+ if (rule[3] == '*') return (disabled = true);
2299
+
2300
+ // get the weekday
2301
+ var weekday = new Date(year, month - 1, day).getDay();
2302
+
2303
+ // if weekday is to be disabled
2304
+ // don't look any further
2305
+ if ($.inArray(weekday, rule[3]) > -1) return (disabled = true);
2306
+
2307
+ }
2308
+
2309
+ });
2310
+
2311
+ // if there are rules that explicitly enable dates
2312
+ if (enabled_dates)
2313
+
2314
+ // iterate through the rules for enabling dates
2315
+ $.each(enabled_dates, function() {
2316
+
2317
+ // if the date is to be enabled, don't look any further
2318
+ if (enabled) return;
2319
+
2320
+ var rule = this;
2321
+
2322
+ // if the rules apply for the current year
2323
+ if ($.inArray(year, rule[2]) > -1 || $.inArray('*', rule[2]) > -1) {
2324
+
2325
+ // the year is enabled
2326
+ enabled = true;
2327
+
2328
+ // if we're also checking months
2329
+ if (typeof month != 'undefined') {
2330
+
2331
+ // we assume the month is enabled
2332
+ enabled = true;
2333
+
2334
+ // if the rules apply for the current month
2335
+ if ($.inArray(month, rule[1]) > -1 || $.inArray('*', rule[1]) > -1) {
2336
+
2337
+ // if we're also checking days
2338
+ if (typeof day != 'undefined') {
2339
+
2340
+ // we assume the day is enabled
2341
+ enabled = true;
2342
+
2343
+ // if the rules apply for the current day
2344
+ if ($.inArray(day, rule[0]) > -1 || $.inArray('*', rule[0]) > -1) {
2345
+
2346
+ // if day is to be enabled whatever the day
2347
+ // don't look any further
2348
+ if (rule[3] == '*') return (enabled = true);
2349
+
2350
+ // get the weekday
2351
+ var weekday = new Date(year, month - 1, day).getDay();
2352
+
2353
+ // if weekday is to be enabled
2354
+ // don't look any further
2355
+ if ($.inArray(weekday, rule[3]) > -1) return (enabled = true);
2356
+
2357
+ // if we get this far, it means the day is not enabled
2358
+ enabled = false;
2359
+
2360
+ // if day is not enabled
2361
+ } else enabled = false;
2362
+
2363
+ }
2364
+
2365
+ // if month is not enabled
2366
+ } else enabled = false;
2367
+
2368
+ }
2369
+
2370
+ }
2371
+
2372
+ });
2373
+
2374
+ // if checked date is enabled, return false
2375
+ if (enabled_dates && enabled) return false;
2376
+
2377
+ // if checked date is disabled return false
2378
+ else if (disabled_dates && disabled) return true;
2379
+
2380
+ // if script gets this far it means that the day/month/year doesn't need to be disabled
2381
+ return false;
2382
+
2383
+ };
2384
+
2385
+ /**
2386
+ * Checks whether a value is an integer number.
2387
+ *
2388
+ * @param mixed value Value to check
2389
+ *
2390
+ * @return Returns TRUE if the value represents an integer number, or FALSE otherwise
2391
+ *
2392
+ * @access private
2393
+ */
2394
+ var is_integer = function(value) {
2395
+
2396
+ // return TRUE if value represents an integer number, or FALSE otherwise
2397
+ return (value + '').match(/^\-?[0-9]+$/) ? true : false;
2398
+
2399
+ };
2400
+
2401
+ /**
2402
+ * Sets the caption in the header of the date picker and enables or disables navigation buttons when necessary.
2403
+ *
2404
+ * @param string caption String that needs to be displayed in the header
2405
+ *
2406
+ * @return void
2407
+ *
2408
+ * @access private
2409
+ */
2410
+ var manage_header = function(caption) {
2411
+
2412
+ // if "selected_month" has a value
2413
+ // $.isNumeric is available only from jQuery 1.7 - thanks to birla for the fix!
2414
+ if (!isNaN(parseFloat(selected_month)) && isFinite(selected_month))
2415
+
2416
+ caption = caption.replace(/\bm\b|\bn\b|\bF\b|\bM\b/, function (match) {
2417
+
2418
+ switch (match) {
2419
+
2420
+ // month number, prefixed with 0
2421
+ case 'm':
2422
+ return str_pad(selected_month + 1, 2);
2423
+
2424
+ // month number, not prefixed with 0
2425
+ case 'n':
2426
+ return selected_month + 1;
2427
+
2428
+ // full month name
2429
+ case 'F':
2430
+ return plugin.settings.months[selected_month];
2431
+
2432
+ // month name, three letters
2433
+ case 'M':
2434
+ return ($.isArray(plugin.settings.months_abbr) && undefined !== plugin.settings.months_abbr[selected_month] ? plugin.settings.months_abbr[selected_month] : plugin.settings.months[selected_month].substr(0, 3));
2435
+
2436
+ // unknown replace
2437
+ default:
2438
+ return match;
2439
+
2440
+ }
2441
+
2442
+ });
2443
+
2444
+ // if "selected_year" has a value
2445
+ // $.isNumeric is available only from jQuery 1.7 - thanks to birla for the fix!
2446
+ if (!isNaN(parseFloat(selected_year)) && isFinite(selected_year))
2447
+
2448
+ // replace year-related patterns
2449
+ caption =
2450
+
2451
+ caption.
2452
+
2453
+ // year as four digits
2454
+ replace(/\bY\b/, selected_year).
2455
+
2456
+ // year as two digits
2457
+ replace(/\by\b/, (selected_year + '').substr(2)).
2458
+
2459
+ // lower limit of year as two or four digits
2460
+ replace(/\bY1\b/i, selected_year - 7).
2461
+
2462
+ // upper limit of year as two or four digits
2463
+ replace(/\bY2\b/i, selected_year + 4);
2464
+
2465
+ // update the caption in the header
2466
+ $('.dp_caption', header).html(caption);
2467
+
2468
+ };
2469
+
2470
+ /**
2471
+ * Shows the appropriate view (days, months or years) according to the current value of the "view" property.
2472
+ *
2473
+ * @return void
2474
+ *
2475
+ * @access private
2476
+ */
2477
+ var manage_views = function() {
2478
+
2479
+ // if the day picker was not yet generated
2480
+ if (daypicker.text() === '' || view == 'days') {
2481
+
2482
+ // if the day picker was not yet generated
2483
+ if (daypicker.text() === '') {
2484
+
2485
+ // if date picker is not always visible
2486
+ if (!plugin.settings.always_visible)
2487
+
2488
+ // temporarily set the date picker's left outside of view
2489
+ // so that we can later grab its width and height
2490
+ datepicker.css('left', -1000);
2491
+
2492
+ // temporarily make the date picker visible
2493
+ // so that we can later grab its width and height
2494
+ datepicker.css('visibility', 'visible');
2495
+
2496
+ // generate the day picker
2497
+ generate_daypicker();
2498
+
2499
+ // get the day picker's width and height
2500
+ var width = daypicker.outerWidth(),
2501
+ height = daypicker.outerHeight();
2502
+
2503
+ // make the month picker have the same size as the day picker
2504
+ monthpicker.css({
2505
+ 'width': width,
2506
+ 'height': height
2507
+ });
2508
+
2509
+ // make the year picker have the same size as the day picker
2510
+ yearpicker.css({
2511
+ 'width': width,
2512
+ 'height': height
2513
+ });
2514
+
2515
+ // make the header and the footer have the same size as the day picker
2516
+ header.css('width', width);
2517
+ footer.css('width', width);
2518
+
2519
+ // hide the date picker again
2520
+ datepicker.css('visibility', '').addClass('dp_hidden');
2521
+
2522
+ // if the day picker was previously generated at least once
2523
+ // generate the day picker
2524
+ } else generate_daypicker();
2525
+
2526
+ // hide the year and the month pickers
2527
+ monthpicker.hide();
2528
+ yearpicker.hide();
2529
+
2530
+ // if the view is "months"
2531
+ } else if (view == 'months') {
2532
+
2533
+ // generate the month picker
2534
+ generate_monthpicker();
2535
+
2536
+ // hide the day and the year pickers
2537
+ daypicker.hide();
2538
+ yearpicker.hide();
2539
+
2540
+ // if the view is "years"
2541
+ } else if (view == 'years') {
2542
+
2543
+ // generate the year picker
2544
+ generate_yearpicker();
2545
+
2546
+ // hide the day and the month pickers
2547
+ daypicker.hide();
2548
+ monthpicker.hide();
2549
+
2550
+ }
2551
+
2552
+ // if a callback function exists for when navigating through months/years
2553
+ if (plugin.settings.onChange && typeof plugin.settings.onChange == 'function' && undefined !== view) {
2554
+
2555
+ // get the "active" elements in the view (ignoring the disabled ones)
2556
+ var elements = (view == 'days' ?
2557
+ daypicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month)') :
2558
+ (view == 'months' ?
2559
+ monthpicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month)') :
2560
+ yearpicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month)')));
2561
+
2562
+ // iterate through the active elements
2563
+ // and attach a "date" data attribute to each element in the form of
2564
+ // YYYY-MM-DD if the view is "days"
2565
+ // YYYY-MM if the view is "months"
2566
+ // YYYY if the view is "years"
2567
+ // so it's easy to identify elements in the list
2568
+ elements.each(function() {
2569
+
2570
+ // if view is "days"
2571
+ if (view == 'days') {
2572
+
2573
+ // if date is from a next/previous month and is selectable
2574
+ if ($(this).hasClass('dp_not_in_month_selectable')) {
2575
+
2576
+ // extract date from the attached class
2577
+ var matches = $(this).attr('class').match(/date\_([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/);
2578
+
2579
+ // attach a "date" data attribute to each element in the form of of YYYY-MM-DD for easily identifying sought elements
2580
+ $(this).data('date', matches[1] + '-' + matches[2] + '-' + matches[3]);
2581
+
2582
+ // if date is from the currently selected month
2583
+ } else
2584
+
2585
+ // attach a "date" data attribute to each element in the form of of YYYY-MM-DD for easily identifying sought elements
2586
+ $(this).data('date', selected_year + '-' + str_pad(selected_month + 1, 2) + '-' + str_pad(to_int($(this).text()), 2));
2587
+
2588
+ // if view is "months"
2589
+ } else if (view == 'months') {
2590
+
2591
+ // get the month's number for the element's class
2592
+ var matches = $(this).attr('class').match(/dp\_month\_([0-9]+)/);
2593
+
2594
+ // attach a "date" data attribute to each element in the form of of YYYY-MM for easily identifying sought elements
2595
+ $(this).data('date', selected_year + '-' + str_pad(to_int(matches[1]) + 1, 2));
2596
+
2597
+ // if view is "years"
2598
+ } else
2599
+
2600
+ // attach a "date" data attribute to each element in the form of of YYYY for easily identifying sought elements
2601
+ $(this).data('date', to_int($(this).text()));
2602
+
2603
+ });
2604
+
2605
+ // execute the callback function and send as arguments the current view, the elements in the view, and
2606
+ // the element the plugin is attached to
2607
+ plugin.settings.onChange.call($element, view, elements, $element);
2608
+
2609
+ }
2610
+
2611
+ // assume the footer is visible
2612
+ footer.show();
2613
+
2614
+ // if the button for clearing a previously selected date needs to be visible all the time,
2615
+ // or the "Clear" button needs to be shown only when a date was previously selected, and now it's the case,
2616
+ // or the date picker is always visible and the "Clear" button was not explicitly disabled
2617
+ if (
2618
+ plugin.settings.show_clear_date === true ||
2619
+ (plugin.settings.show_clear_date === 0 && $element.val() !== '') ||
2620
+ (plugin.settings.always_visible && plugin.settings.show_clear_date !== false)
2621
+ ) {
2622
+
2623
+ // show the "Clear" button
2624
+ cleardate.show();
2625
+
2626
+ // if the "Today" button is visible
2627
+ if (show_select_today) {
2628
+
2629
+ // show it, and set it's width to 50% of the available space
2630
+ selecttoday.css('width', '50%');
2631
+
2632
+ // the "Clear date" button only takes up 50% of the available space
2633
+ cleardate.css('width', '50%');
2634
+
2635
+ // if the "Today" button is not visible
2636
+ } else {
2637
+
2638
+ // hide the "Today" button
2639
+ selecttoday.hide();
2640
+
2641
+ // the "Clear date" button takes up 100% of the available space
2642
+ cleardate.css('width', '100%');
2643
+
2644
+ }
2645
+
2646
+ // otherwise
2647
+ } else {
2648
+
2649
+ // hide the "Clear" button
2650
+ cleardate.hide();
2651
+
2652
+ // if the "Today" button is visible, it will now take up all the available space
2653
+ if (show_select_today) selecttoday.show().css('width', '100%');
2654
+
2655
+ // if the "Today" button is also not visible, hide the footer entirely
2656
+ else footer.hide();
2657
+
2658
+ }
2659
+
2660
+
2661
+ };
2662
+
2663
+ /**
2664
+ * Puts the specified date in the element the plugin is attached to, and hides the date picker.
2665
+ *
2666
+ * @param integer year The year
2667
+ *
2668
+ * @param integer month The month
2669
+ *
2670
+ * @param integer day The day
2671
+ *
2672
+ * @param string view The view from where the method was called
2673
+ *
2674
+ * @param object cell The element that was clicked
2675
+ *
2676
+ * @return void
2677
+ *
2678
+ * @access private
2679
+ */
2680
+ var select_date = function(year, month, day, view, cell) {
2681
+
2682
+ var
2683
+
2684
+ // construct a new date object from the arguments
2685
+ default_date = new Date(year, month, day, 12, 0, 0),
2686
+
2687
+ // pointer to the cells in the current view
2688
+ view_cells = (view == 'days' ? daypicker_cells : (view == 'months' ? monthpicker_cells : yearpicker_cells)),
2689
+
2690
+ // the selected date, formatted correctly
2691
+ selected_value = format(default_date);
2692
+
2693
+ // set the currently selected and formated date as the value of the element the plugin is attached to
2694
+ $element.val(selected_value);
2695
+
2696
+ // if date picker is always visible
2697
+ if (plugin.settings.always_visible) {
2698
+
2699
+ // extract the date parts and reassign values to these variables
2700
+ // so that everything will be correctly highlighted
2701
+ default_month = default_date.getMonth();
2702
+ selected_month = default_date.getMonth();
2703
+ default_year = default_date.getFullYear();
2704
+ selected_year = default_date.getFullYear();
2705
+ default_day = default_date.getDate();
2706
+
2707
+ // remove the "selected" class from all cells in the current view
2708
+ view_cells.removeClass('dp_selected');
2709
+
2710
+ // add the "selected" class to the currently selected cell
2711
+ cell.addClass('dp_selected');
2712
+
2713
+ // if we're on the "days" view and days from other months are selectable and one of those days was
2714
+ // selected, repaint the datepicker so it will take us to the selected month
2715
+ if (view == 'days' && cell.hasClass('dp_not_in_month_selectable')) plugin.show();
2716
+
2717
+ }
2718
+
2719
+ // hide the date picker
2720
+ plugin.hide();
2721
+
2722
+ // updates value for the date picker whose starting date depends on the selected date (if any)
2723
+ update_dependent(default_date);
2724
+
2725
+ // if a callback function exists for when selecting a date
2726
+ if (plugin.settings.onSelect && typeof plugin.settings.onSelect == 'function')
2727
+
2728
+ // execute the callback function
2729
+ // make "this" inside the callback function refer to the element the date picker is attached to
2730
+ plugin.settings.onSelect.call($element, selected_value, year + '-' + str_pad(month + 1, 2) + '-' + str_pad(day, 2), default_date, $element, getWeekNumber(default_date));
2731
+
2732
+ // move focus to the element the plugin is attached to
2733
+ $element.focus();
2734
+
2735
+ };
2736
+
2737
+ /**
2738
+ * Concatenates any number of arguments and returns them as string.
2739
+ *
2740
+ * @return string Returns the concatenated values.
2741
+ *
2742
+ * @access private
2743
+ */
2744
+ var str_concat = function() {
2745
+
2746
+ var str = '';
2747
+
2748
+ // concatenate as string
2749
+ for (var i = 0; i < arguments.length; i++) str += (arguments[i] + '');
2750
+
2751
+ // return the concatenated values
2752
+ return str;
2753
+
2754
+ };
2755
+
2756
+ /**
2757
+ * Left-pad a string to a certain length with zeroes.
2758
+ *
2759
+ * @param string str The string to be padded.
2760
+ *
2761
+ * @param integer len The length to which the string must be padded
2762
+ *
2763
+ * @return string Returns the string left-padded with leading zeroes
2764
+ *
2765
+ * @access private
2766
+ */
2767
+ var str_pad = function(str, len) {
2768
+
2769
+ // make sure argument is a string
2770
+ str += '';
2771
+
2772
+ // pad with leading zeroes until we get to the desired length
2773
+ while (str.length < len) str = '0' + str;
2774
+
2775
+ // return padded string
2776
+ return str;
2777
+
2778
+ };
2779
+
2780
+ /**
2781
+ * Returns the integer representation of a string
2782
+ *
2783
+ * @return int Returns the integer representation of the string given as argument
2784
+ *
2785
+ * @access private
2786
+ */
2787
+ var to_int = function(str) {
2788
+
2789
+ // return the integer representation of the string given as argument
2790
+ return parseInt(str , 10);
2791
+
2792
+ };
2793
+
2794
+ /**
2795
+ * Updates the paired date picker (whose starting date depends on the value of the current date picker)
2796
+ *
2797
+ * @param date date A JavaScript date object representing the currently selected date
2798
+ *
2799
+ * @return void
2800
+ *
2801
+ * @access private
2802
+ */
2803
+ var update_dependent = function(date) {
2804
+
2805
+ // if the pair element exists
2806
+ if (plugin.settings.pair) {
2807
+
2808
+ // iterate through the pair elements (as there may be more than just one)
2809
+ $.each(plugin.settings.pair, function() {
2810
+
2811
+ var $pair = $(this);
2812
+
2813
+ // chances are that in the beginning the pair element doesn't have the Zebra_DatePicker attached to it yet
2814
+ // (as the "start" element is usually created before the "end" element)
2815
+ // so we'll have to rely on "data" to send the starting date to the pair element
2816
+
2817
+ // therefore, if Zebra_DatePicker is not yet attached
2818
+ if (!($pair.data && $pair.data('Zebra_DatePicker')))
2819
+
2820
+ // set the starting date like this
2821
+ $pair.data('zdp_reference_date', date);
2822
+
2823
+ // if Zebra_DatePicker is attached to the pair element
2824
+ else {
2825
+
2826
+ // reference the date picker object attached to the other element
2827
+ var dp = $pair.data('Zebra_DatePicker');
2828
+
2829
+ // update the other date picker's starting date
2830
+ // the value depends on the original value of the "direction" attribute
2831
+ // (also, if the pair date picker does not have a direction, set it to 1)
2832
+ dp.update({
2833
+ 'reference_date': date,
2834
+ 'direction': dp.settings.direction === 0 ? 1 : dp.settings.direction
2835
+ });
2836
+
2837
+ // if the other date picker is always visible, update the visuals now
2838
+ if (dp.settings.always_visible) dp.show();
2839
+
2840
+ }
2841
+
2842
+ });
2843
+
2844
+ }
2845
+
2846
+ };
2847
+
2848
+ /**
2849
+ * Calculate the ISO 8601 week number for a given date.
2850
+ *
2851
+ * Code is based on the algorithm at http://www.tondering.dk/claus/cal/week.php#calcweekno
2852
+ */
2853
+ var getWeekNumber = function(date) {
2854
+
2855
+ var y = date.getFullYear(),
2856
+ m = date.getMonth() + 1,
2857
+ d = date.getDate(),
2858
+ a, b, c, s, e, f, g, n, w;
2859
+
2860
+ // If month jan. or feb.
2861
+ if (m < 3) {
2862
+
2863
+ a = y - 1;
2864
+ b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
2865
+ c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
2866
+ s = b - c;
2867
+ e = 0;
2868
+ f = d - 1 + 31 * (m - 1);
2869
+
2870
+ // If month mar. through dec.
2871
+ } else {
2872
+
2873
+ a = y;
2874
+ b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
2875
+ c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
2876
+ s = b - c;
2877
+ e = s + 1;
2878
+ f = d + ((153 * (m - 3) + 2) / 5 | 0) + 58 + s;
2879
+
2880
+ }
2881
+
2882
+ g = (a + b) % 7;
2883
+ // ISO Weekday (0 is monday, 1 is tuesday etc.)
2884
+ d = (f + g - e) % 7;
2885
+ n = f + 3 - d;
2886
+
2887
+ if (n < 0) w = 53 - ((g - s) / 5 | 0);
2888
+
2889
+ else if (n > 364 + s) w = 1;
2890
+
2891
+ else w = (n / 7 | 0) + 1;
2892
+
2893
+ return w;
2894
+
2895
+ };
2896
+
2897
+ // since with jQuery 1.9.0 the $.browser object was removed, we rely on this piece of code from
2898
+ // http://www.quirksmode.org/js/detect.html to detect the browser
2899
+ var browser = {
2900
+ init: function () {
2901
+ this.name = this.searchString(this.dataBrowser) || '';
2902
+ this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || '';
2903
+ },
2904
+ searchString: function (data) {
2905
+ for (var i=0;i<data.length;i++) {
2906
+ var dataString = data[i].string;
2907
+ var dataProp = data[i].prop;
2908
+ this.versionSearchString = data[i].versionSearch || data[i].identity;
2909
+ if (dataString) {
2910
+ if (dataString.indexOf(data[i].subString) != -1)
2911
+ return data[i].identity;
2912
+ }
2913
+ else if (dataProp)
2914
+ return data[i].identity;
2915
+ }
2916
+ },
2917
+ searchVersion: function (dataString) {
2918
+ var index = dataString.indexOf(this.versionSearchString);
2919
+ if (index == -1) return;
2920
+ return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
2921
+ },
2922
+ dataBrowser: [
2923
+ {
2924
+ string: navigator.userAgent,
2925
+ subString: 'Firefox',
2926
+ identity: 'firefox'
2927
+ },
2928
+ {
2929
+ string: navigator.userAgent,
2930
+ subString: 'MSIE',
2931
+ identity: 'explorer',
2932
+ versionSearch: 'MSIE'
2933
+ }
2934
+ ]
2935
+ };
2936
+
2937
+ browser.init();
2938
+
2939
+ // initialize the plugin
2940
+ init();
2941
+
2942
+ };
2943
+
2944
+ $.fn.Zebra_DatePicker = function(options) {
2945
+
2946
+ // iterate through all the elements to which we need to attach the date picker to
2947
+ return this.each(function() {
2948
+
2949
+ // if element has a date picker already attached
2950
+ if (undefined !== $(this).data('Zebra_DatePicker'))
2951
+
2952
+ // remove the attached date picker
2953
+ $(this).data('Zebra_DatePicker').destroy();
2954
+
2955
+ // create an instance of the plugin
2956
+ var plugin = new $.Zebra_DatePicker(this, options);
2957
+
2958
+ // save a reference to the newly created object
2959
+ $(this).data('Zebra_DatePicker', plugin);
2960
+
2961
+ });
2962
+
2963
+ };
2964
+
2965
+ })(jQuery);