assets-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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);