asset_box 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +60 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +35 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +43 -0
  10. data/Rakefile +6 -0
  11. data/asset_box.gemspec +42 -0
  12. data/assets/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  13. data/assets/fonts/bootstrap/glyphicons-halflings-regular.svg +288 -0
  14. data/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  15. data/assets/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  16. data/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
  17. data/assets/fonts/font-awesome/fa-brands-400.eot +0 -0
  18. data/assets/fonts/font-awesome/fa-brands-400.svg +3717 -0
  19. data/assets/fonts/font-awesome/fa-brands-400.ttf +0 -0
  20. data/assets/fonts/font-awesome/fa-brands-400.woff +0 -0
  21. data/assets/fonts/font-awesome/fa-brands-400.woff2 +0 -0
  22. data/assets/fonts/font-awesome/fa-regular-400.eot +0 -0
  23. data/assets/fonts/font-awesome/fa-regular-400.svg +801 -0
  24. data/assets/fonts/font-awesome/fa-regular-400.ttf +0 -0
  25. data/assets/fonts/font-awesome/fa-regular-400.woff +0 -0
  26. data/assets/fonts/font-awesome/fa-regular-400.woff2 +0 -0
  27. data/assets/fonts/font-awesome/fa-solid-900.eot +0 -0
  28. data/assets/fonts/font-awesome/fa-solid-900.svg +5028 -0
  29. data/assets/fonts/font-awesome/fa-solid-900.ttf +0 -0
  30. data/assets/fonts/font-awesome/fa-solid-900.woff +0 -0
  31. data/assets/fonts/font-awesome/fa-solid-900.woff2 +0 -0
  32. data/assets/images/bootstrap/bg.png +0 -0
  33. data/assets/images/bootstrap/bg_2.png +0 -0
  34. data/assets/images/bootstrap/bg_3.png +0 -0
  35. data/assets/images/bootstrap/bg_4.png +0 -0
  36. data/assets/images/bootstrap/bg_5.png +0 -0
  37. data/assets/images/bootstrap/dark_dots.png +0 -0
  38. data/assets/images/bootstrap/light_dots.png +0 -0
  39. data/assets/images/bootstrap/line.png +0 -0
  40. data/assets/images/bootstrap/line_detail.png +0 -0
  41. data/assets/images/bootstrap/note_dot.png +0 -0
  42. data/assets/images/bootstrap/timer-piece.png +0 -0
  43. data/assets/javascripts/app/bootstrap-datepicker.js +1395 -0
  44. data/assets/javascripts/app/bootstrap-fileupload.min.js +7 -0
  45. data/assets/javascripts/app/bootstrap-modal.js +378 -0
  46. data/assets/javascripts/app/bootstrap-modalmanager.js +423 -0
  47. data/assets/javascripts/app/bootstrap-switch.min.js +22 -0
  48. data/assets/javascripts/app/daterangepicker.js +1635 -0
  49. data/assets/javascripts/app/debounce.js +1492 -0
  50. data/assets/javascripts/app/jquery.appear.js +101 -0
  51. data/assets/javascripts/app/jquery.inputlimiter.1.3.1.min.js +11 -0
  52. data/assets/javascripts/app/jquery.mousewheel.js +84 -0
  53. data/assets/javascripts/app/jquery.serialScroll.min.js +7 -0
  54. data/assets/javascripts/app/moment.min.js +7 -0
  55. data/assets/javascripts/app/perfect-scrollbar.js +584 -0
  56. data/assets/javascripts/app/subview.js +392 -0
  57. data/assets/javascripts/app/velocity.min.js +8 -0
  58. data/assets/javascripts/asset_box.js +16 -0
  59. data/assets/javascripts/bootstrap-sprockets.js +12 -0
  60. data/assets/javascripts/bootstrap.js +2580 -0
  61. data/assets/javascripts/bootstrap.min.js +6 -0
  62. data/assets/javascripts/bootstrap/affix.js +164 -0
  63. data/assets/javascripts/bootstrap/alert.js +95 -0
  64. data/assets/javascripts/bootstrap/button.js +125 -0
  65. data/assets/javascripts/bootstrap/carousel.js +246 -0
  66. data/assets/javascripts/bootstrap/collapse.js +212 -0
  67. data/assets/javascripts/bootstrap/dropdown.js +165 -0
  68. data/assets/javascripts/bootstrap/modal.js +358 -0
  69. data/assets/javascripts/bootstrap/popover.js +123 -0
  70. data/assets/javascripts/bootstrap/scrollspy.js +172 -0
  71. data/assets/javascripts/bootstrap/tab.js +155 -0
  72. data/assets/javascripts/bootstrap/tooltip.js +677 -0
  73. data/assets/javascripts/bootstrap/transition.js +59 -0
  74. data/assets/stylesheets/_asset_box.scss +760 -0
  75. data/assets/stylesheets/_bootstrap-compass.scss +9 -0
  76. data/assets/stylesheets/_bootstrap-mincer.scss +19 -0
  77. data/assets/stylesheets/_bootstrap-sprockets.scss +9 -0
  78. data/assets/stylesheets/_bootstrap.scss +56 -0
  79. data/assets/stylesheets/_bootstrap_login.scss +166 -0
  80. data/assets/stylesheets/_font-awesome-compass.scss +5 -0
  81. data/assets/stylesheets/_font-awesome-sprockets.scss +5 -0
  82. data/assets/stylesheets/_font-awesome.scss +17 -0
  83. data/assets/stylesheets/_font-awesome_v4-shims.scss +6 -0
  84. data/assets/stylesheets/_load_bootstrap.scss +12 -0
  85. data/assets/stylesheets/app/_base.scss +136 -0
  86. data/assets/stylesheets/app/_buttons.scss +1149 -0
  87. data/assets/stylesheets/app/_calendar.scss +343 -0
  88. data/assets/stylesheets/app/_ckeditor.scss +123 -0
  89. data/assets/stylesheets/app/_date-picker.scss +193 -0
  90. data/assets/stylesheets/app/_daterangepicker.scss +269 -0
  91. data/assets/stylesheets/app/_dropdown-menu.scss +137 -0
  92. data/assets/stylesheets/app/_error.scss +84 -0
  93. data/assets/stylesheets/app/_file-upload.scss +16 -0
  94. data/assets/stylesheets/app/_footer.scss +59 -0
  95. data/assets/stylesheets/app/_form-elements.scss +273 -0
  96. data/assets/stylesheets/app/_gallery.scss +205 -0
  97. data/assets/stylesheets/app/_header.scss +158 -0
  98. data/assets/stylesheets/app/_horizontal-menu.scss +169 -0
  99. data/assets/stylesheets/app/_icons.scss +47 -0
  100. data/assets/stylesheets/app/_inputlimiter.scss +34 -0
  101. data/assets/stylesheets/app/_invoice.scss +53 -0
  102. data/assets/stylesheets/app/_lock-screen.scss +72 -0
  103. data/assets/stylesheets/app/_login.scss +105 -0
  104. data/assets/stylesheets/app/_main-container.scss +297 -0
  105. data/assets/stylesheets/app/_messages.scss +311 -0
  106. data/assets/stylesheets/app/_pageslide_left.scss +283 -0
  107. data/assets/stylesheets/app/_pageslide_right.scss +350 -0
  108. data/assets/stylesheets/app/_pagination.scss +254 -0
  109. data/assets/stylesheets/app/_panels.scss +589 -0
  110. data/assets/stylesheets/app/_perfect-scrollbar.scss +111 -0
  111. data/assets/stylesheets/app/_slidingbar.scss +42 -0
  112. data/assets/stylesheets/app/_subview.scss +342 -0
  113. data/assets/stylesheets/app/_tables.scss +68 -0
  114. data/assets/stylesheets/app/_tabs.scss +251 -0
  115. data/assets/stylesheets/app/_tags-input.scss +46 -0
  116. data/assets/stylesheets/app/_theme-style8.scss +308 -0
  117. data/assets/stylesheets/app/_timeline.scss +359 -0
  118. data/assets/stylesheets/app/_user-profile.scss +99 -0
  119. data/assets/stylesheets/app/_utilities.scss +643 -0
  120. data/assets/stylesheets/bootstrap/_alerts.scss +73 -0
  121. data/assets/stylesheets/bootstrap/_badges.scss +68 -0
  122. data/assets/stylesheets/bootstrap/_breadcrumbs.scss +28 -0
  123. data/assets/stylesheets/bootstrap/_button-groups.scss +244 -0
  124. data/assets/stylesheets/bootstrap/_buttons.scss +168 -0
  125. data/assets/stylesheets/bootstrap/_carousel.scss +271 -0
  126. data/assets/stylesheets/bootstrap/_close.scss +37 -0
  127. data/assets/stylesheets/bootstrap/_code.scss +69 -0
  128. data/assets/stylesheets/bootstrap/_component-animations.scss +38 -0
  129. data/assets/stylesheets/bootstrap/_dropdowns.scss +213 -0
  130. data/assets/stylesheets/bootstrap/_forms.scss +607 -0
  131. data/assets/stylesheets/bootstrap/_glyphicons.scss +307 -0
  132. data/assets/stylesheets/bootstrap/_grid.scss +94 -0
  133. data/assets/stylesheets/bootstrap/_input-groups.scss +171 -0
  134. data/assets/stylesheets/bootstrap/_jumbotron.scss +54 -0
  135. data/assets/stylesheets/bootstrap/_labels.scss +66 -0
  136. data/assets/stylesheets/bootstrap/_list-group.scss +128 -0
  137. data/assets/stylesheets/bootstrap/_media.scss +66 -0
  138. data/assets/stylesheets/bootstrap/_mixins.scss +40 -0
  139. data/assets/stylesheets/bootstrap/_modals.scss +150 -0
  140. data/assets/stylesheets/bootstrap/_navbar.scss +656 -0
  141. data/assets/stylesheets/bootstrap/_navs.scss +242 -0
  142. data/assets/stylesheets/bootstrap/_normalize.scss +427 -0
  143. data/assets/stylesheets/bootstrap/_pager.scss +54 -0
  144. data/assets/stylesheets/bootstrap/_pagination.scss +86 -0
  145. data/assets/stylesheets/bootstrap/_panels.scss +271 -0
  146. data/assets/stylesheets/bootstrap/_popovers.scss +126 -0
  147. data/assets/stylesheets/bootstrap/_print.scss +99 -0
  148. data/assets/stylesheets/bootstrap/_progress-bars.scss +87 -0
  149. data/assets/stylesheets/bootstrap/_responsive-embed.scss +35 -0
  150. data/assets/stylesheets/bootstrap/_responsive-utilities.scss +179 -0
  151. data/assets/stylesheets/bootstrap/_scaffolding.scss +161 -0
  152. data/assets/stylesheets/bootstrap/_tables.scss +234 -0
  153. data/assets/stylesheets/bootstrap/_theme.scss +295 -0
  154. data/assets/stylesheets/bootstrap/_thumbnails.scss +38 -0
  155. data/assets/stylesheets/bootstrap/_tooltip.scss +112 -0
  156. data/assets/stylesheets/bootstrap/_type.scss +298 -0
  157. data/assets/stylesheets/bootstrap/_utilities.scss +55 -0
  158. data/assets/stylesheets/bootstrap/_variables.scss +874 -0
  159. data/assets/stylesheets/bootstrap/_wells.scss +29 -0
  160. data/assets/stylesheets/bootstrap/mixins/_alerts.scss +15 -0
  161. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +12 -0
  162. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  163. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +61 -0
  164. data/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  165. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  166. data/assets/stylesheets/bootstrap/mixins/_forms.scss +88 -0
  167. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +56 -0
  168. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  169. data/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  170. data/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  171. data/assets/stylesheets/bootstrap/mixins/_image.scss +28 -0
  172. data/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  173. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +32 -0
  174. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  175. data/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  176. data/assets/stylesheets/bootstrap/mixins/_opacity.scss +7 -0
  177. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +24 -0
  178. data/assets/stylesheets/bootstrap/mixins/_panels.scss +24 -0
  179. data/assets/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
  180. data/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  181. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +18 -0
  182. data/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  183. data/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +17 -0
  184. data/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
  185. data/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  186. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  187. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +12 -0
  188. data/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  189. data/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
  190. data/assets/stylesheets/font-awesome/_animated.scss +20 -0
  191. data/assets/stylesheets/font-awesome/_bordered-pulled.scss +20 -0
  192. data/assets/stylesheets/font-awesome/_core.scss +21 -0
  193. data/assets/stylesheets/font-awesome/_fixed-width.scss +6 -0
  194. data/assets/stylesheets/font-awesome/_icons.scss +1462 -0
  195. data/assets/stylesheets/font-awesome/_larger.scss +23 -0
  196. data/assets/stylesheets/font-awesome/_list.scss +18 -0
  197. data/assets/stylesheets/font-awesome/_mixins.scss +56 -0
  198. data/assets/stylesheets/font-awesome/_path.scss +56 -0
  199. data/assets/stylesheets/font-awesome/_rotated-flipped.scss +24 -0
  200. data/assets/stylesheets/font-awesome/_screen-reader.scss +5 -0
  201. data/assets/stylesheets/font-awesome/_shims.scss +2066 -0
  202. data/assets/stylesheets/font-awesome/_stacked.scss +31 -0
  203. data/assets/stylesheets/font-awesome/_variables.scss +1482 -0
  204. data/bin/console +14 -0
  205. data/bin/setup +8 -0
  206. data/lib/asset_box.rb +89 -0
  207. data/lib/asset_box/rails/engine.rb +22 -0
  208. data/lib/asset_box/rails/helpers.rb +17 -0
  209. data/lib/asset_box/rails/railtie.rb +13 -0
  210. data/lib/asset_box/version.rb +3 -0
  211. metadata +301 -0
@@ -0,0 +1,22 @@
1
+ /* ========================================================================
2
+ * bootstrap-switch - v3.3.2
3
+ * http://www.bootstrap-switch.org
4
+ * ========================================================================
5
+ * Copyright 2012-2013 Mattia Larentis
6
+ *
7
+ * ========================================================================
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ * ========================================================================
20
+ */
21
+
22
+ (function(){var t=[].slice;!function(e,i){"use strict";var n;return n=function(){function t(t,i){null==i&&(i={}),this.$element=e(t),this.options=e.extend({},e.fn.bootstrapSwitch.defaults,{state:this.$element.is(":checked"),size:this.$element.data("size"),animate:this.$element.data("animate"),disabled:this.$element.is(":disabled"),readonly:this.$element.is("[readonly]"),indeterminate:this.$element.data("indeterminate"),inverse:this.$element.data("inverse"),radioAllOff:this.$element.data("radio-all-off"),onColor:this.$element.data("on-color"),offColor:this.$element.data("off-color"),onText:this.$element.data("on-text"),offText:this.$element.data("off-text"),labelText:this.$element.data("label-text"),handleWidth:this.$element.data("handle-width"),labelWidth:this.$element.data("label-width"),baseClass:this.$element.data("base-class"),wrapperClass:this.$element.data("wrapper-class")},i),this.$wrapper=e("<div>",{"class":function(t){return function(){var e;return e=[""+t.options.baseClass].concat(t._getClasses(t.options.wrapperClass)),e.push(t.options.state?""+t.options.baseClass+"-on":""+t.options.baseClass+"-off"),null!=t.options.size&&e.push(""+t.options.baseClass+"-"+t.options.size),t.options.disabled&&e.push(""+t.options.baseClass+"-disabled"),t.options.readonly&&e.push(""+t.options.baseClass+"-readonly"),t.options.indeterminate&&e.push(""+t.options.baseClass+"-indeterminate"),t.options.inverse&&e.push(""+t.options.baseClass+"-inverse"),t.$element.attr("id")&&e.push(""+t.options.baseClass+"-id-"+t.$element.attr("id")),e.join(" ")}}(this)()}),this.$container=e("<div>",{"class":""+this.options.baseClass+"-container"}),this.$on=e("<span>",{html:this.options.onText,"class":""+this.options.baseClass+"-handle-on "+this.options.baseClass+"-"+this.options.onColor}),this.$off=e("<span>",{html:this.options.offText,"class":""+this.options.baseClass+"-handle-off "+this.options.baseClass+"-"+this.options.offColor}),this.$label=e("<span>",{html:this.options.labelText,"class":""+this.options.baseClass+"-label"}),this.$element.on("init.bootstrapSwitch",function(e){return function(){return e.options.onInit.apply(t,arguments)}}(this)),this.$element.on("switchChange.bootstrapSwitch",function(e){return function(){return e.options.onSwitchChange.apply(t,arguments)}}(this)),this.$container=this.$element.wrap(this.$container).parent(),this.$wrapper=this.$container.wrap(this.$wrapper).parent(),this.$element.before(this.options.inverse?this.$off:this.$on).before(this.$label).before(this.options.inverse?this.$on:this.$off),this.options.indeterminate&&this.$element.prop("indeterminate",!0),this._init(),this._elementHandlers(),this._handleHandlers(),this._labelHandlers(),this._formHandler(),this._externalLabelHandler(),this.$element.trigger("init.bootstrapSwitch")}return t.prototype._constructor=t,t.prototype.state=function(t,e){return"undefined"==typeof t?this.options.state:this.options.disabled||this.options.readonly?this.$element:this.options.state&&!this.options.radioAllOff&&this.$element.is(":radio")?this.$element:(this.options.indeterminate&&this.indeterminate(!1),t=!!t,this.$element.prop("checked",t).trigger("change.bootstrapSwitch",e),this.$element)},t.prototype.toggleState=function(t){return this.options.disabled||this.options.readonly?this.$element:this.options.indeterminate?(this.indeterminate(!1),this.state(!0)):this.$element.prop("checked",!this.options.state).trigger("change.bootstrapSwitch",t)},t.prototype.size=function(t){return"undefined"==typeof t?this.options.size:(null!=this.options.size&&this.$wrapper.removeClass(""+this.options.baseClass+"-"+this.options.size),t&&this.$wrapper.addClass(""+this.options.baseClass+"-"+t),this._width(),this._containerPosition(),this.options.size=t,this.$element)},t.prototype.animate=function(t){return"undefined"==typeof t?this.options.animate:(t=!!t,t===this.options.animate?this.$element:this.toggleAnimate())},t.prototype.toggleAnimate=function(){return this.options.animate=!this.options.animate,this.$wrapper.toggleClass(""+this.options.baseClass+"-animate"),this.$element},t.prototype.disabled=function(t){return"undefined"==typeof t?this.options.disabled:(t=!!t,t===this.options.disabled?this.$element:this.toggleDisabled())},t.prototype.toggleDisabled=function(){return this.options.disabled=!this.options.disabled,this.$element.prop("disabled",this.options.disabled),this.$wrapper.toggleClass(""+this.options.baseClass+"-disabled"),this.$element},t.prototype.readonly=function(t){return"undefined"==typeof t?this.options.readonly:(t=!!t,t===this.options.readonly?this.$element:this.toggleReadonly())},t.prototype.toggleReadonly=function(){return this.options.readonly=!this.options.readonly,this.$element.prop("readonly",this.options.readonly),this.$wrapper.toggleClass(""+this.options.baseClass+"-readonly"),this.$element},t.prototype.indeterminate=function(t){return"undefined"==typeof t?this.options.indeterminate:(t=!!t,t===this.options.indeterminate?this.$element:this.toggleIndeterminate())},t.prototype.toggleIndeterminate=function(){return this.options.indeterminate=!this.options.indeterminate,this.$element.prop("indeterminate",this.options.indeterminate),this.$wrapper.toggleClass(""+this.options.baseClass+"-indeterminate"),this._containerPosition(),this.$element},t.prototype.inverse=function(t){return"undefined"==typeof t?this.options.inverse:(t=!!t,t===this.options.inverse?this.$element:this.toggleInverse())},t.prototype.toggleInverse=function(){var t,e;return this.$wrapper.toggleClass(""+this.options.baseClass+"-inverse"),e=this.$on.clone(!0),t=this.$off.clone(!0),this.$on.replaceWith(t),this.$off.replaceWith(e),this.$on=t,this.$off=e,this.options.inverse=!this.options.inverse,this.$element},t.prototype.onColor=function(t){var e;return e=this.options.onColor,"undefined"==typeof t?e:(null!=e&&this.$on.removeClass(""+this.options.baseClass+"-"+e),this.$on.addClass(""+this.options.baseClass+"-"+t),this.options.onColor=t,this.$element)},t.prototype.offColor=function(t){var e;return e=this.options.offColor,"undefined"==typeof t?e:(null!=e&&this.$off.removeClass(""+this.options.baseClass+"-"+e),this.$off.addClass(""+this.options.baseClass+"-"+t),this.options.offColor=t,this.$element)},t.prototype.onText=function(t){return"undefined"==typeof t?this.options.onText:(this.$on.html(t),this._width(),this._containerPosition(),this.options.onText=t,this.$element)},t.prototype.offText=function(t){return"undefined"==typeof t?this.options.offText:(this.$off.html(t),this._width(),this._containerPosition(),this.options.offText=t,this.$element)},t.prototype.labelText=function(t){return"undefined"==typeof t?this.options.labelText:(this.$label.html(t),this._width(),this.options.labelText=t,this.$element)},t.prototype.handleWidth=function(t){return"undefined"==typeof t?this.options.handleWidth:(this.options.handleWidth=t,this._width(),this._containerPosition(),this.$element)},t.prototype.labelWidth=function(t){return"undefined"==typeof t?this.options.labelWidth:(this.options.labelWidth=t,this._width(),this._containerPosition(),this.$element)},t.prototype.baseClass=function(){return this.options.baseClass},t.prototype.wrapperClass=function(t){return"undefined"==typeof t?this.options.wrapperClass:(t||(t=e.fn.bootstrapSwitch.defaults.wrapperClass),this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(" ")),this.$wrapper.addClass(this._getClasses(t).join(" ")),this.options.wrapperClass=t,this.$element)},t.prototype.radioAllOff=function(t){return"undefined"==typeof t?this.options.radioAllOff:(t=!!t,t===this.options.radioAllOff?this.$element:(this.options.radioAllOff=t,this.$element))},t.prototype.onInit=function(t){return"undefined"==typeof t?this.options.onInit:(t||(t=e.fn.bootstrapSwitch.defaults.onInit),this.options.onInit=t,this.$element)},t.prototype.onSwitchChange=function(t){return"undefined"==typeof t?this.options.onSwitchChange:(t||(t=e.fn.bootstrapSwitch.defaults.onSwitchChange),this.options.onSwitchChange=t,this.$element)},t.prototype.destroy=function(){var t;return t=this.$element.closest("form"),t.length&&t.off("reset.bootstrapSwitch").removeData("bootstrap-switch"),this.$container.children().not(this.$element).remove(),this.$element.unwrap().unwrap().off(".bootstrapSwitch").removeData("bootstrap-switch"),this.$element},t.prototype._width=function(){var t,e;return t=this.$on.add(this.$off),t.add(this.$label).css("width",""),e="auto"===this.options.handleWidth?Math.max(this.$on.width(),this.$off.width()):this.options.handleWidth,t.width(e),this.$label.width(function(t){return function(i,n){return"auto"!==t.options.labelWidth?t.options.labelWidth:e>n?e:n}}(this)),this._handleWidth=this.$on.outerWidth(),this._labelWidth=this.$label.outerWidth(),this.$container.width(2*this._handleWidth+this._labelWidth),this.$wrapper.width(this._handleWidth+this._labelWidth)},t.prototype._containerPosition=function(t,e){return null==t&&(t=this.options.state),this.$container.css("margin-left",function(e){return function(){var i;return i=[0,"-"+e._handleWidth+"px"],e.options.indeterminate?"-"+e._handleWidth/2+"px":t?e.options.inverse?i[1]:i[0]:e.options.inverse?i[0]:i[1]}}(this)),e?setTimeout(function(){return e()},50):void 0},t.prototype._init=function(){var t,e;return t=function(t){return function(){return t._width(),t._containerPosition(null,function(){return t.options.animate?t.$wrapper.addClass(""+t.options.baseClass+"-animate"):void 0})}}(this),this.$wrapper.is(":visible")?t():e=i.setInterval(function(n){return function(){return n.$wrapper.is(":visible")?(t(),i.clearInterval(e)):void 0}}(this),50)},t.prototype._elementHandlers=function(){return this.$element.on({"change.bootstrapSwitch":function(t){return function(i,n){var o;return i.preventDefault(),i.stopImmediatePropagation(),o=t.$element.is(":checked"),t._containerPosition(o),o!==t.options.state?(t.options.state=o,t.$wrapper.toggleClass(""+t.options.baseClass+"-off").toggleClass(""+t.options.baseClass+"-on"),n?void 0:(t.$element.is(":radio")&&e("[name='"+t.$element.attr("name")+"']").not(t.$element).prop("checked",!1).trigger("change.bootstrapSwitch",!0),t.$element.trigger("switchChange.bootstrapSwitch",[o]))):void 0}}(this),"focus.bootstrapSwitch":function(t){return function(e){return e.preventDefault(),t.$wrapper.addClass(""+t.options.baseClass+"-focused")}}(this),"blur.bootstrapSwitch":function(t){return function(e){return e.preventDefault(),t.$wrapper.removeClass(""+t.options.baseClass+"-focused")}}(this),"keydown.bootstrapSwitch":function(t){return function(e){if(e.which&&!t.options.disabled&&!t.options.readonly)switch(e.which){case 37:return e.preventDefault(),e.stopImmediatePropagation(),t.state(!1);case 39:return e.preventDefault(),e.stopImmediatePropagation(),t.state(!0)}}}(this)})},t.prototype._handleHandlers=function(){return this.$on.on("click.bootstrapSwitch",function(t){return function(e){return e.preventDefault(),e.stopPropagation(),t.state(!1),t.$element.trigger("focus.bootstrapSwitch")}}(this)),this.$off.on("click.bootstrapSwitch",function(t){return function(e){return e.preventDefault(),e.stopPropagation(),t.state(!0),t.$element.trigger("focus.bootstrapSwitch")}}(this))},t.prototype._labelHandlers=function(){return this.$label.on({"mousedown.bootstrapSwitch touchstart.bootstrapSwitch":function(t){return function(e){return t._dragStart||t.options.disabled||t.options.readonly?void 0:(e.preventDefault(),e.stopPropagation(),t._dragStart=(e.pageX||e.originalEvent.touches[0].pageX)-parseInt(t.$container.css("margin-left"),10),t.options.animate&&t.$wrapper.removeClass(""+t.options.baseClass+"-animate"),t.$element.trigger("focus.bootstrapSwitch"))}}(this),"mousemove.bootstrapSwitch touchmove.bootstrapSwitch":function(t){return function(e){var i;if(null!=t._dragStart&&(e.preventDefault(),i=(e.pageX||e.originalEvent.touches[0].pageX)-t._dragStart,!(i<-t._handleWidth||i>0)))return t._dragEnd=i,t.$container.css("margin-left",""+t._dragEnd+"px")}}(this),"mouseup.bootstrapSwitch touchend.bootstrapSwitch":function(t){return function(e){var i;if(t._dragStart)return e.preventDefault(),t.options.animate&&t.$wrapper.addClass(""+t.options.baseClass+"-animate"),t._dragEnd?(i=t._dragEnd>-(t._handleWidth/2),t._dragEnd=!1,t.state(t.options.inverse?!i:i)):t.state(!t.options.state),t._dragStart=!1}}(this),"mouseleave.bootstrapSwitch":function(t){return function(){return t.$label.trigger("mouseup.bootstrapSwitch")}}(this)})},t.prototype._externalLabelHandler=function(){var t;return t=this.$element.closest("label"),t.on("click",function(e){return function(i){return i.preventDefault(),i.stopImmediatePropagation(),i.target===t[0]?e.toggleState():void 0}}(this))},t.prototype._formHandler=function(){var t;return t=this.$element.closest("form"),t.data("bootstrap-switch")?void 0:t.on("reset.bootstrapSwitch",function(){return i.setTimeout(function(){return t.find("input").filter(function(){return e(this).data("bootstrap-switch")}).each(function(){return e(this).bootstrapSwitch("state",this.checked)})},1)}).data("bootstrap-switch",!0)},t.prototype._getClasses=function(t){var i,n,o,s;if(!e.isArray(t))return[""+this.options.baseClass+"-"+t];for(n=[],o=0,s=t.length;s>o;o++)i=t[o],n.push(""+this.options.baseClass+"-"+i);return n},t}(),e.fn.bootstrapSwitch=function(){var i,o,s;return o=arguments[0],i=2<=arguments.length?t.call(arguments,1):[],s=this,this.each(function(){var t,a;return t=e(this),a=t.data("bootstrap-switch"),a||t.data("bootstrap-switch",a=new n(this,o)),"string"==typeof o?s=a[o].apply(a,i):void 0}),s},e.fn.bootstrapSwitch.Constructor=n,e.fn.bootstrapSwitch.defaults={state:!0,size:null,animate:!0,disabled:!1,readonly:!1,indeterminate:!1,inverse:!1,radioAllOff:!1,onColor:"primary",offColor:"default",onText:"ON",offText:"OFF",labelText:"&nbsp;",handleWidth:"auto",labelWidth:"auto",baseClass:"bootstrap-switch",wrapperClass:"wrapper",onInit:function(){},onSwitchChange:function(){}}}(window.jQuery,window)}).call(this);
@@ -0,0 +1,1635 @@
1
+ /**
2
+ * @version: 2.1.24
3
+ * @author: Dan Grossman http://www.dangrossman.info/
4
+ * @copyright: Copyright (c) 2012-2016 Dan Grossman. All rights reserved.
5
+ * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
6
+ * @website: https://www.improvely.com/
7
+ */
8
+ // Follow the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
9
+ (function (root, factory) {
10
+ if (typeof define === 'function' && define.amd) {
11
+ // AMD. Make globaly available as well
12
+ define(['moment', 'jquery'], function (moment, jquery) {
13
+ return (root.daterangepicker = factory(moment, jquery));
14
+ });
15
+ } else if (typeof module === 'object' && module.exports) {
16
+ // Node / Browserify
17
+ //isomorphic issue
18
+ var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined;
19
+ if (!jQuery) {
20
+ jQuery = require('jquery');
21
+ if (!jQuery.fn) jQuery.fn = {};
22
+ }
23
+ module.exports = factory(require('moment'), jQuery);
24
+ } else {
25
+ // Browser globals
26
+ root.daterangepicker = factory(root.moment, root.jQuery);
27
+ }
28
+ }(this, function(moment, $) {
29
+ var DateRangePicker = function(element, options, cb) {
30
+
31
+ //default settings for options
32
+ this.parentEl = 'body';
33
+ this.element = $(element);
34
+ this.startDate = moment().startOf('day');
35
+ this.endDate = moment().endOf('day');
36
+ this.minDate = false;
37
+ this.maxDate = false;
38
+ this.dateLimit = false;
39
+ this.autoApply = false;
40
+ this.singleDatePicker = false;
41
+ this.showDropdowns = false;
42
+ this.showWeekNumbers = false;
43
+ this.showISOWeekNumbers = false;
44
+ this.showCustomRangeLabel = true;
45
+ this.timePicker = false;
46
+ this.timePicker24Hour = false;
47
+ this.timePickerIncrement = 1;
48
+ this.timePickerSeconds = false;
49
+ this.linkedCalendars = true;
50
+ this.autoUpdateInput = true;
51
+ this.alwaysShowCalendars = false;
52
+ this.ranges = {};
53
+
54
+ this.showDefault = true;
55
+
56
+ this.opens = 'right';
57
+ if (this.element.hasClass('pull-right'))
58
+ this.opens = 'left';
59
+
60
+ this.drops = 'down';
61
+ if (this.element.hasClass('dropup'))
62
+ this.drops = 'up';
63
+
64
+ this.buttonClasses = 'btn btn-sm';
65
+ this.applyClass = 'btn-success';
66
+ this.cancelClass = 'btn-default';
67
+
68
+ this.locale = {
69
+ direction: 'ltr',
70
+ format: moment.localeData().longDateFormat('L'),
71
+ separator: ' - ',
72
+ applyLabel: 'Apply',
73
+ cancelLabel: 'Cancel',
74
+ weekLabel: 'W',
75
+ customRangeLabel: 'Custom Range',
76
+ daysOfWeek: moment.weekdaysMin(),
77
+ monthNames: moment.monthsShort(),
78
+ firstDay: moment.localeData().firstDayOfWeek()
79
+ };
80
+
81
+ this.callback = function() { };
82
+
83
+ //some state information
84
+ this.isShowing = false;
85
+ this.leftCalendar = {};
86
+ this.rightCalendar = {};
87
+ this.noneDefaultValue = false;
88
+
89
+ //custom options from user
90
+ if (typeof options !== 'object' || options === null)
91
+ options = {};
92
+
93
+ //allow setting options with data attributes
94
+ //data-api options will be overwritten with custom javascript options
95
+ options = $.extend(this.element.data(), options);
96
+
97
+ //html template for the picker UI
98
+ if (typeof options.template !== 'string' && !(options.template instanceof $))
99
+ options.template = '<div class="daterangepicker dropdown-menu">' +
100
+ '<div class="calendar left">' +
101
+ '<div class="daterangepicker_input">' +
102
+ '<input class="input-mini form-control" type="text" name="daterangepicker_start" value="" />' +
103
+ '<i class="fa fa-calendar glyphicon glyphicon-calendar"></i>' +
104
+ '<div class="calendar-time">' +
105
+ '<div></div>' +
106
+ '<i class="fa fa-clock-o glyphicon glyphicon-time"></i>' +
107
+ '</div>' +
108
+ '</div>' +
109
+ '<div class="calendar-table"></div>' +
110
+ '</div>' +
111
+ '<div class="calendar right">' +
112
+ '<div class="daterangepicker_input">' +
113
+ '<input class="input-mini form-control" type="text" name="daterangepicker_end" value="" />' +
114
+ '<i class="fa fa-calendar glyphicon glyphicon-calendar"></i>' +
115
+ '<div class="calendar-time">' +
116
+ '<div></div>' +
117
+ '<i class="fa fa-clock-o glyphicon glyphicon-time"></i>' +
118
+ '</div>' +
119
+ '</div>' +
120
+ '<div class="calendar-table"></div>' +
121
+ '</div>' +
122
+ '<div class="ranges">' +
123
+ '<div class="range_inputs">' +
124
+ '<button class="applyBtn" disabled="disabled" type="button"></button> ' +
125
+ '<button class="cancelBtn" type="button"></button>' +
126
+ '</div>' +
127
+ '</div>' +
128
+ '</div>';
129
+
130
+ this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
131
+ this.container = $(options.template).appendTo(this.parentEl);
132
+
133
+ //
134
+ // handle all the possible options overriding defaults
135
+ //
136
+
137
+ if (typeof options.locale === 'object') {
138
+
139
+ if (typeof options.locale.direction === 'string')
140
+ this.locale.direction = options.locale.direction;
141
+
142
+ if (typeof options.locale.format === 'string')
143
+ this.locale.format = options.locale.format;
144
+
145
+ if (typeof options.locale.separator === 'string')
146
+ this.locale.separator = options.locale.separator;
147
+
148
+ if (typeof options.locale.daysOfWeek === 'object')
149
+ this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
150
+
151
+ if (typeof options.locale.monthNames === 'object')
152
+ this.locale.monthNames = options.locale.monthNames.slice();
153
+
154
+ if (typeof options.locale.firstDay === 'number')
155
+ this.locale.firstDay = options.locale.firstDay;
156
+
157
+ if (typeof options.locale.applyLabel === 'string')
158
+ this.locale.applyLabel = options.locale.applyLabel;
159
+
160
+ if (typeof options.locale.cancelLabel === 'string')
161
+ this.locale.cancelLabel = options.locale.cancelLabel;
162
+
163
+ if (typeof options.locale.weekLabel === 'string')
164
+ this.locale.weekLabel = options.locale.weekLabel;
165
+
166
+ if (typeof options.locale.customRangeLabel === 'string')
167
+ this.locale.customRangeLabel = options.locale.customRangeLabel;
168
+
169
+ }
170
+ this.container.addClass(this.locale.direction);
171
+
172
+ if (typeof options.startDate === 'string')
173
+ this.startDate = moment(options.startDate, this.locale.format);
174
+
175
+ if (typeof options.endDate === 'string')
176
+ this.endDate = moment(options.endDate, this.locale.format);
177
+
178
+ if (typeof options.minDate === 'string')
179
+ this.minDate = moment(options.minDate, this.locale.format);
180
+
181
+ if (typeof options.maxDate === 'string')
182
+ this.maxDate = moment(options.maxDate, this.locale.format);
183
+
184
+ if (typeof options.startDate === 'object')
185
+ this.startDate = moment(options.startDate);
186
+
187
+ if (typeof options.endDate === 'object')
188
+ this.endDate = moment(options.endDate);
189
+
190
+ if (typeof options.minDate === 'object')
191
+ this.minDate = moment(options.minDate);
192
+
193
+ if (typeof options.maxDate === 'object')
194
+ this.maxDate = moment(options.maxDate);
195
+
196
+ // sanity check for bad options
197
+ if (this.minDate && this.startDate.isBefore(this.minDate))
198
+ this.startDate = this.minDate.clone();
199
+
200
+ // sanity check for bad options
201
+ if (this.maxDate && this.endDate.isAfter(this.maxDate))
202
+ this.endDate = this.maxDate.clone();
203
+
204
+ if (typeof options.applyClass === 'string')
205
+ this.applyClass = options.applyClass;
206
+
207
+ if (typeof options.cancelClass === 'string')
208
+ this.cancelClass = options.cancelClass;
209
+
210
+ if (typeof options.dateLimit === 'object')
211
+ this.dateLimit = options.dateLimit;
212
+
213
+ if (typeof options.opens === 'string')
214
+ this.opens = options.opens;
215
+
216
+ if (typeof options.drops === 'string')
217
+ this.drops = options.drops;
218
+
219
+ if (typeof options.showWeekNumbers === 'boolean')
220
+ this.showWeekNumbers = options.showWeekNumbers;
221
+
222
+ if (typeof options.showISOWeekNumbers === 'boolean')
223
+ this.showISOWeekNumbers = options.showISOWeekNumbers;
224
+
225
+ if (typeof options.buttonClasses === 'string')
226
+ this.buttonClasses = options.buttonClasses;
227
+
228
+ if (typeof options.buttonClasses === 'object')
229
+ this.buttonClasses = options.buttonClasses.join(' ');
230
+
231
+ if (typeof options.showDropdowns === 'boolean')
232
+ this.showDropdowns = options.showDropdowns;
233
+
234
+ if (typeof options.showCustomRangeLabel === 'boolean')
235
+ this.showCustomRangeLabel = options.showCustomRangeLabel;
236
+
237
+ if (typeof options.singleDatePicker === 'boolean') {
238
+ this.singleDatePicker = options.singleDatePicker;
239
+ if (this.singleDatePicker)
240
+ this.endDate = this.startDate.clone();
241
+ }
242
+
243
+ if (typeof options.timePicker === 'boolean')
244
+ this.timePicker = options.timePicker;
245
+
246
+ if (typeof options.timePickerSeconds === 'boolean')
247
+ this.timePickerSeconds = options.timePickerSeconds;
248
+
249
+ if (typeof options.timePickerIncrement === 'number')
250
+ this.timePickerIncrement = options.timePickerIncrement;
251
+
252
+ if (typeof options.timePicker24Hour === 'boolean')
253
+ this.timePicker24Hour = options.timePicker24Hour;
254
+
255
+ if (typeof options.autoApply === 'boolean')
256
+ this.autoApply = options.autoApply;
257
+
258
+ if (typeof options.autoUpdateInput === 'boolean')
259
+ this.autoUpdateInput = options.autoUpdateInput;
260
+
261
+ if (typeof options.linkedCalendars === 'boolean')
262
+ this.linkedCalendars = options.linkedCalendars;
263
+
264
+ if (typeof options.isInvalidDate === 'function')
265
+ this.isInvalidDate = options.isInvalidDate;
266
+
267
+ if (typeof options.isCustomDate === 'function')
268
+ this.isCustomDate = options.isCustomDate;
269
+
270
+ if (typeof options.alwaysShowCalendars === 'boolean')
271
+ this.alwaysShowCalendars = options.alwaysShowCalendars;
272
+
273
+ if(typeof options.showDefault === 'boolean')
274
+ this.showDefault = options.showDefault;
275
+
276
+ // update day names order to firstDay
277
+ if (this.locale.firstDay != 0) {
278
+ var iterator = this.locale.firstDay;
279
+ while (iterator > 0) {
280
+ this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
281
+ iterator--;
282
+ }
283
+ }
284
+
285
+ var start, end, range;
286
+
287
+ //if no start/end dates set, check if an input element contains initial values
288
+ if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
289
+ if ($(this.element).is('input[type=text]')) {
290
+ var val = $(this.element).val(),
291
+ split = val.split(this.locale.separator);
292
+
293
+ start = end = null;
294
+
295
+ if (split.length == 2) {
296
+ start = moment(split[0], this.locale.format);
297
+ end = moment(split[1], this.locale.format);
298
+ } else if (this.singleDatePicker && val !== "") {
299
+ start = moment(val, this.locale.format);
300
+ end = moment(val, this.locale.format);
301
+ }
302
+ if(start === null && end === null)
303
+ this.noneDefaultValue = true;
304
+
305
+ if (start !== null && end !== null) {
306
+ this.setStartDate(start);
307
+ this.setEndDate(end);
308
+ }
309
+ }
310
+ }
311
+
312
+ if (typeof options.ranges === 'object') {
313
+ for (range in options.ranges) {
314
+
315
+ if (typeof options.ranges[range][0] === 'string')
316
+ start = moment(options.ranges[range][0], this.locale.format);
317
+ else
318
+ start = moment(options.ranges[range][0]);
319
+
320
+ if (typeof options.ranges[range][1] === 'string')
321
+ end = moment(options.ranges[range][1], this.locale.format);
322
+ else
323
+ end = moment(options.ranges[range][1]);
324
+
325
+ // If the start or end date exceed those allowed by the minDate or dateLimit
326
+ // options, shorten the range to the allowable period.
327
+ if (this.minDate && start.isBefore(this.minDate))
328
+ start = this.minDate.clone();
329
+
330
+ var maxDate = this.maxDate;
331
+ if (this.dateLimit && maxDate && start.clone().add(this.dateLimit).isAfter(maxDate))
332
+ maxDate = start.clone().add(this.dateLimit);
333
+ if (maxDate && end.isAfter(maxDate))
334
+ end = maxDate.clone();
335
+
336
+ // If the end of the range is before the minimum or the start of the range is
337
+ // after the maximum, don't display this range option at all.
338
+ if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day'))
339
+ || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day')))
340
+ continue;
341
+
342
+ //Support unicode chars in the range names.
343
+ var elem = document.createElement('textarea');
344
+ elem.innerHTML = range;
345
+ var rangeHtml = elem.value;
346
+
347
+ this.ranges[rangeHtml] = [start, end];
348
+ }
349
+
350
+ var list = '<ul>';
351
+ for (range in this.ranges) {
352
+ list += '<li data-range-key="' + range + '">' + range + '</li>';
353
+ }
354
+ if (this.showCustomRangeLabel) {
355
+ list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>';
356
+ }
357
+ list += '</ul>';
358
+ this.container.find('.ranges').prepend(list);
359
+ }
360
+
361
+ if (typeof cb === 'function') {
362
+ this.callback = cb;
363
+ }
364
+
365
+ if (!this.timePicker) {
366
+ this.startDate = this.startDate.startOf('day');
367
+ this.endDate = this.endDate.endOf('day');
368
+ this.container.find('.calendar-time').hide();
369
+ }
370
+
371
+ //can't be used together for now
372
+ if (this.timePicker && this.autoApply)
373
+ this.autoApply = false;
374
+
375
+ if (this.autoApply && typeof options.ranges !== 'object') {
376
+ this.container.find('.ranges').hide();
377
+ } else if (this.autoApply) {
378
+ this.container.find('.applyBtn, .cancelBtn').addClass('hide');
379
+ }
380
+
381
+ if (this.singleDatePicker) {
382
+ this.container.addClass('single');
383
+ this.container.find('.calendar.left').addClass('single');
384
+ this.container.find('.calendar.left').show();
385
+ this.container.find('.calendar.right').hide();
386
+ this.container.find('.daterangepicker_input input, .daterangepicker_input > i').hide();
387
+ if (this.timePicker) {
388
+ this.container.find('.ranges ul').hide();
389
+ } else {
390
+ this.container.find('.ranges').hide();
391
+ }
392
+ }
393
+
394
+ if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) {
395
+ this.container.addClass('show-calendar');
396
+ }
397
+
398
+ this.container.addClass('opens' + this.opens);
399
+
400
+ //swap the position of the predefined ranges if opens right
401
+ if (typeof options.ranges !== 'undefined' && this.opens == 'right') {
402
+ this.container.find('.ranges').prependTo( this.container.find('.calendar.left').parent() );
403
+ }
404
+
405
+ //apply CSS classes and labels to buttons
406
+ this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
407
+ if (this.applyClass.length)
408
+ this.container.find('.applyBtn').addClass(this.applyClass);
409
+ if (this.cancelClass.length)
410
+ this.container.find('.cancelBtn').addClass(this.cancelClass);
411
+ this.container.find('.applyBtn').html(this.locale.applyLabel);
412
+ this.container.find('.cancelBtn').html(this.locale.cancelLabel);
413
+
414
+ //
415
+ // event listeners
416
+ //
417
+
418
+ this.container.find('.calendar')
419
+ .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
420
+ .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
421
+ .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
422
+ .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))
423
+ .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this))
424
+ .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this))
425
+ .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
426
+ .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this))
427
+ .on('click.daterangepicker', '.daterangepicker_input input', $.proxy(this.showCalendars, this))
428
+ .on('focus.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsFocused, this))
429
+ .on('blur.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsBlurred, this))
430
+ .on('change.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this));
431
+
432
+ this.container.find('.ranges')
433
+ .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
434
+ .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))
435
+ .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))
436
+ .on('mouseenter.daterangepicker', 'li', $.proxy(this.hoverRange, this))
437
+ .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this));
438
+
439
+ if (this.element.is('input') || this.element.is('button')) {
440
+ this.element.on({
441
+ 'click.daterangepicker': $.proxy(this.show, this),
442
+ 'focus.daterangepicker': $.proxy(this.show, this),
443
+ 'keyup.daterangepicker': $.proxy(this.elementChanged, this),
444
+ 'keydown.daterangepicker': $.proxy(this.keydown, this)
445
+ });
446
+ } else {
447
+ this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
448
+ }
449
+
450
+ //
451
+ // if attached to a text input, set the initial value
452
+ //
453
+
454
+ if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput && this.showDefault) {
455
+ this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
456
+ this.element.trigger('change');
457
+ } else if (this.element.is('input') && this.autoUpdateInput && this.showDefault) {
458
+ this.element.val(this.startDate.format(this.locale.format));
459
+ this.element.trigger('change');
460
+ }
461
+
462
+ };
463
+
464
+ DateRangePicker.prototype = {
465
+
466
+ constructor: DateRangePicker,
467
+
468
+ setStartDate: function(startDate) {
469
+ if (typeof startDate === 'string')
470
+ this.startDate = moment(startDate, this.locale.format);
471
+
472
+ if (typeof startDate === 'object')
473
+ this.startDate = moment(startDate);
474
+
475
+ if (!this.timePicker)
476
+ this.startDate = this.startDate.startOf('day');
477
+
478
+ if (this.timePicker && this.timePickerIncrement)
479
+ this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
480
+
481
+ if (this.minDate && this.startDate.isBefore(this.minDate)) {
482
+ this.startDate = this.minDate.clone();
483
+ if (this.timePicker && this.timePickerIncrement)
484
+ this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
485
+ }
486
+
487
+ if (this.maxDate && this.startDate.isAfter(this.maxDate)) {
488
+ this.startDate = this.maxDate.clone();
489
+ if (this.timePicker && this.timePickerIncrement)
490
+ this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
491
+ }
492
+
493
+ if (!this.isShowing)
494
+ this.updateElement();
495
+
496
+ this.updateMonthsInView();
497
+ },
498
+
499
+ setEndDate: function(endDate) {
500
+ if (typeof endDate === 'string')
501
+ this.endDate = moment(endDate, this.locale.format);
502
+
503
+ if (typeof endDate === 'object')
504
+ this.endDate = moment(endDate);
505
+
506
+ if (!this.timePicker)
507
+ this.endDate = this.endDate.endOf('day');
508
+
509
+ if (this.timePicker && this.timePickerIncrement)
510
+ this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
511
+
512
+ if (this.endDate.isBefore(this.startDate))
513
+ this.endDate = this.startDate.clone();
514
+
515
+ if (this.maxDate && this.endDate.isAfter(this.maxDate))
516
+ this.endDate = this.maxDate.clone();
517
+
518
+ if (this.dateLimit && this.startDate.clone().add(this.dateLimit).isBefore(this.endDate))
519
+ this.endDate = this.startDate.clone().add(this.dateLimit);
520
+
521
+ this.previousRightTime = this.endDate.clone();
522
+
523
+ if (!this.isShowing)
524
+ this.updateElement();
525
+
526
+ this.updateMonthsInView();
527
+ },
528
+
529
+ isInvalidDate: function() {
530
+ return false;
531
+ },
532
+
533
+ isCustomDate: function() {
534
+ return false;
535
+ },
536
+
537
+ updateView: function() {
538
+ if (this.timePicker) {
539
+ this.renderTimePicker('left');
540
+ this.renderTimePicker('right');
541
+ if (!this.endDate) {
542
+ this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled');
543
+ } else {
544
+ this.container.find('.right .calendar-time select').removeAttr('disabled').removeClass('disabled');
545
+ }
546
+ }
547
+ if (this.endDate) {
548
+ this.container.find('input[name="daterangepicker_end"]').removeClass('active');
549
+ this.container.find('input[name="daterangepicker_start"]').addClass('active');
550
+ } else {
551
+ this.container.find('input[name="daterangepicker_end"]').addClass('active');
552
+ this.container.find('input[name="daterangepicker_start"]').removeClass('active');
553
+ }
554
+ this.updateMonthsInView();
555
+ this.updateCalendars();
556
+ this.updateFormInputs();
557
+ },
558
+
559
+ updateMonthsInView: function() {
560
+ if (this.endDate) {
561
+
562
+ //if both dates are visible already, do nothing
563
+ if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month &&
564
+ (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
565
+ &&
566
+ (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
567
+ ) {
568
+ return;
569
+ }
570
+
571
+ this.leftCalendar.month = this.startDate.clone().date(2);
572
+ if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
573
+ this.rightCalendar.month = this.endDate.clone().date(2);
574
+ } else {
575
+ this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
576
+ }
577
+
578
+ } else {
579
+ if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
580
+ this.leftCalendar.month = this.startDate.clone().date(2);
581
+ this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
582
+ }
583
+ }
584
+ if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) {
585
+ this.rightCalendar.month = this.maxDate.clone().date(2);
586
+ this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month');
587
+ }
588
+ },
589
+
590
+ updateCalendars: function() {
591
+
592
+ if (this.timePicker) {
593
+ var hour, minute, second;
594
+ if (this.endDate) {
595
+ hour = parseInt(this.container.find('.left .hourselect').val(), 10);
596
+ minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
597
+ second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
598
+ if (!this.timePicker24Hour) {
599
+ var ampm = this.container.find('.left .ampmselect').val();
600
+ if (ampm === 'PM' && hour < 12)
601
+ hour += 12;
602
+ if (ampm === 'AM' && hour === 12)
603
+ hour = 0;
604
+ }
605
+ } else {
606
+ hour = parseInt(this.container.find('.right .hourselect').val(), 10);
607
+ minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
608
+ second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
609
+ if (!this.timePicker24Hour) {
610
+ var ampm = this.container.find('.right .ampmselect').val();
611
+ if (ampm === 'PM' && hour < 12)
612
+ hour += 12;
613
+ if (ampm === 'AM' && hour === 12)
614
+ hour = 0;
615
+ }
616
+ }
617
+ this.leftCalendar.month.hour(hour).minute(minute).second(second);
618
+ this.rightCalendar.month.hour(hour).minute(minute).second(second);
619
+ }
620
+
621
+ this.renderCalendar('left');
622
+ this.renderCalendar('right');
623
+
624
+ //highlight any predefined range matching the current start and end dates
625
+ this.container.find('.ranges li').removeClass('active');
626
+ if (this.endDate == null) return;
627
+
628
+ this.calculateChosenLabel();
629
+ },
630
+
631
+ renderCalendar: function(side) {
632
+
633
+ //
634
+ // Build the matrix of dates that will populate the calendar
635
+ //
636
+
637
+ var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar;
638
+ var month = calendar.month.month();
639
+ var year = calendar.month.year();
640
+ var hour = calendar.month.hour();
641
+ var minute = calendar.month.minute();
642
+ var second = calendar.month.second();
643
+ var daysInMonth = moment([year, month]).daysInMonth();
644
+ var firstDay = moment([year, month, 1]);
645
+ var lastDay = moment([year, month, daysInMonth]);
646
+ var lastMonth = moment(firstDay).subtract(1, 'month').month();
647
+ var lastYear = moment(firstDay).subtract(1, 'month').year();
648
+ var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
649
+ var dayOfWeek = firstDay.day();
650
+
651
+ //initialize a 6 rows x 7 columns array for the calendar
652
+ var calendar = [];
653
+ calendar.firstDay = firstDay;
654
+ calendar.lastDay = lastDay;
655
+
656
+ for (var i = 0; i < 6; i++) {
657
+ calendar[i] = [];
658
+ }
659
+
660
+ //populate the calendar with date objects
661
+ var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
662
+ if (startDay > daysInLastMonth)
663
+ startDay -= 7;
664
+
665
+ if (dayOfWeek == this.locale.firstDay)
666
+ startDay = daysInLastMonth - 6;
667
+
668
+ var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]);
669
+
670
+ var col, row;
671
+ for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
672
+ if (i > 0 && col % 7 === 0) {
673
+ col = 0;
674
+ row++;
675
+ }
676
+ calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second);
677
+ curDate.hour(12);
678
+
679
+ if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') {
680
+ calendar[row][col] = this.minDate.clone();
681
+ }
682
+
683
+ if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') {
684
+ calendar[row][col] = this.maxDate.clone();
685
+ }
686
+
687
+ }
688
+
689
+ //make the calendar object available to hoverDate/clickDate
690
+ if (side == 'left') {
691
+ this.leftCalendar.calendar = calendar;
692
+ } else {
693
+ this.rightCalendar.calendar = calendar;
694
+ }
695
+
696
+ //
697
+ // Display the calendar
698
+ //
699
+
700
+ var minDate = side == 'left' ? this.minDate : this.startDate;
701
+ var maxDate = this.maxDate;
702
+ var selected = side == 'left' ? this.startDate : this.endDate;
703
+ var arrow = this.locale.direction == 'ltr' ? {left: 'chevron-left', right: 'chevron-right'} : {left: 'chevron-right', right: 'chevron-left'};
704
+
705
+ var html = '<table class="table-condensed">';
706
+ html += '<thead>';
707
+ html += '<tr>';
708
+
709
+ // add empty cell for week number
710
+ if (this.showWeekNumbers || this.showISOWeekNumbers)
711
+ html += '<th></th>';
712
+
713
+ if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) {
714
+ html += '<th class="prev available"><i class="fa fa-' + arrow.left + ' glyphicon glyphicon-' + arrow.left + '"></i></th>';
715
+ } else {
716
+ html += '<th></th>';
717
+ }
718
+
719
+ var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
720
+
721
+ if (this.showDropdowns) {
722
+ var currentMonth = calendar[1][1].month();
723
+ var currentYear = calendar[1][1].year();
724
+ var maxYear = (maxDate && maxDate.year()) || (currentYear + 5);
725
+ var minYear = (minDate && minDate.year()) || (currentYear - 50);
726
+ var inMinYear = currentYear == minYear;
727
+ var inMaxYear = currentYear == maxYear;
728
+
729
+ var monthHtml = '<select class="monthselect">';
730
+ for (var m = 0; m < 12; m++) {
731
+ if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {
732
+ monthHtml += "<option value='" + m + "'" +
733
+ (m === currentMonth ? " selected='selected'" : "") +
734
+ ">" + this.locale.monthNames[m] + "</option>";
735
+ } else {
736
+ monthHtml += "<option value='" + m + "'" +
737
+ (m === currentMonth ? " selected='selected'" : "") +
738
+ " disabled='disabled'>" + this.locale.monthNames[m] + "</option>";
739
+ }
740
+ }
741
+ monthHtml += "</select>";
742
+
743
+ var yearHtml = '<select class="yearselect">';
744
+ for (var y = minYear; y <= maxYear; y++) {
745
+ yearHtml += '<option value="' + y + '"' +
746
+ (y === currentYear ? ' selected="selected"' : '') +
747
+ '>' + y + '</option>';
748
+ }
749
+ yearHtml += '</select>';
750
+
751
+ dateHtml = monthHtml + yearHtml;
752
+ }
753
+
754
+ html += '<th colspan="5" class="month">' + dateHtml + '</th>';
755
+ if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) {
756
+ html += '<th class="next available"><i class="fa fa-' + arrow.right + ' glyphicon glyphicon-' + arrow.right + '"></i></th>';
757
+ } else {
758
+ html += '<th></th>';
759
+ }
760
+
761
+ html += '</tr>';
762
+ html += '<tr>';
763
+
764
+ // add week number label
765
+ if (this.showWeekNumbers || this.showISOWeekNumbers)
766
+ html += '<th class="week">' + this.locale.weekLabel + '</th>';
767
+
768
+ $.each(this.locale.daysOfWeek, function(index, dayOfWeek) {
769
+ html += '<th>' + dayOfWeek + '</th>';
770
+ });
771
+
772
+ html += '</tr>';
773
+ html += '</thead>';
774
+ html += '<tbody>';
775
+
776
+ //adjust maxDate to reflect the dateLimit setting in order to
777
+ //grey out end dates beyond the dateLimit
778
+ if (this.endDate == null && this.dateLimit) {
779
+ var maxLimit = this.startDate.clone().add(this.dateLimit).endOf('day');
780
+ if (!maxDate || maxLimit.isBefore(maxDate)) {
781
+ maxDate = maxLimit;
782
+ }
783
+ }
784
+
785
+ for (var row = 0; row < 6; row++) {
786
+ html += '<tr>';
787
+
788
+ // add week number
789
+ if (this.showWeekNumbers)
790
+ html += '<td class="week">' + calendar[row][0].week() + '</td>';
791
+ else if (this.showISOWeekNumbers)
792
+ html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>';
793
+
794
+ for (var col = 0; col < 7; col++) {
795
+
796
+ var classes = [];
797
+
798
+ //highlight today's date
799
+ if (calendar[row][col].isSame(new Date(), "day"))
800
+ classes.push('today');
801
+
802
+ //highlight weekends
803
+ if (calendar[row][col].isoWeekday() > 5)
804
+ classes.push('weekend');
805
+
806
+ //grey out the dates in other months displayed at beginning and end of this calendar
807
+ if (calendar[row][col].month() != calendar[1][1].month())
808
+ classes.push('off');
809
+
810
+ //don't allow selection of dates before the minimum date
811
+ if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day'))
812
+ classes.push('off', 'disabled');
813
+
814
+ //don't allow selection of dates after the maximum date
815
+ if (maxDate && calendar[row][col].isAfter(maxDate, 'day'))
816
+ classes.push('off', 'disabled');
817
+
818
+ //don't allow selection of date if a custom function decides it's invalid
819
+ if (this.isInvalidDate(calendar[row][col]))
820
+ classes.push('off', 'disabled');
821
+
822
+ //highlight the currently selected start date
823
+ if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD'))
824
+ classes.push('active', 'start-date');
825
+
826
+ //highlight the currently selected end date
827
+ if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD'))
828
+ classes.push('active', 'end-date');
829
+
830
+ //highlight dates in-between the selected dates
831
+ if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate)
832
+ classes.push('in-range');
833
+
834
+ //apply custom classes for this date
835
+ var isCustom = this.isCustomDate(calendar[row][col]);
836
+ if (isCustom !== false) {
837
+ if (typeof isCustom === 'string')
838
+ classes.push(isCustom);
839
+ else
840
+ Array.prototype.push.apply(classes, isCustom);
841
+ }
842
+
843
+ var cname = '', disabled = false;
844
+ for (var i = 0; i < classes.length; i++) {
845
+ cname += classes[i] + ' ';
846
+ if (classes[i] == 'disabled')
847
+ disabled = true;
848
+ }
849
+ if (!disabled)
850
+ cname += 'available';
851
+
852
+ html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '</td>';
853
+
854
+ }
855
+ html += '</tr>';
856
+ }
857
+
858
+ html += '</tbody>';
859
+ html += '</table>';
860
+
861
+ this.container.find('.calendar.' + side + ' .calendar-table').html(html);
862
+
863
+ },
864
+
865
+ renderTimePicker: function(side) {
866
+
867
+ // Don't bother updating the time picker if it's currently disabled
868
+ // because an end date hasn't been clicked yet
869
+ if (side == 'right' && !this.endDate) return;
870
+
871
+ var html, selected, minDate, maxDate = this.maxDate;
872
+
873
+ if (this.dateLimit && (!this.maxDate || this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate)))
874
+ maxDate = this.startDate.clone().add(this.dateLimit);
875
+
876
+ if (side == 'left') {
877
+ selected = this.startDate.clone();
878
+ minDate = this.minDate;
879
+ } else if (side == 'right') {
880
+ selected = this.endDate.clone();
881
+ minDate = this.startDate;
882
+
883
+ //Preserve the time already selected
884
+ var timeSelector = this.container.find('.calendar.right .calendar-time div');
885
+ if (!this.endDate && timeSelector.html() != '') {
886
+
887
+ selected.hour(timeSelector.find('.hourselect option:selected').val() || selected.hour());
888
+ selected.minute(timeSelector.find('.minuteselect option:selected').val() || selected.minute());
889
+ selected.second(timeSelector.find('.secondselect option:selected').val() || selected.second());
890
+
891
+ if (!this.timePicker24Hour) {
892
+ var ampm = timeSelector.find('.ampmselect option:selected').val();
893
+ if (ampm === 'PM' && selected.hour() < 12)
894
+ selected.hour(selected.hour() + 12);
895
+ if (ampm === 'AM' && selected.hour() === 12)
896
+ selected.hour(0);
897
+ }
898
+
899
+ }
900
+
901
+ if (selected.isBefore(this.startDate))
902
+ selected = this.startDate.clone();
903
+
904
+ if (maxDate && selected.isAfter(maxDate))
905
+ selected = maxDate.clone();
906
+
907
+ }
908
+
909
+ //
910
+ // hours
911
+ //
912
+
913
+ html = '<select class="hourselect">';
914
+
915
+ var start = this.timePicker24Hour ? 0 : 1;
916
+ var end = this.timePicker24Hour ? 23 : 12;
917
+
918
+ for (var i = start; i <= end; i++) {
919
+ var i_in_24 = i;
920
+ if (!this.timePicker24Hour)
921
+ i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i);
922
+
923
+ var time = selected.clone().hour(i_in_24);
924
+ var disabled = false;
925
+ if (minDate && time.minute(59).isBefore(minDate))
926
+ disabled = true;
927
+ if (maxDate && time.minute(0).isAfter(maxDate))
928
+ disabled = true;
929
+
930
+ if (i_in_24 == selected.hour() && !disabled) {
931
+ html += '<option value="' + i + '" selected="selected">' + i + '</option>';
932
+ } else if (disabled) {
933
+ html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>';
934
+ } else {
935
+ html += '<option value="' + i + '">' + i + '</option>';
936
+ }
937
+ }
938
+
939
+ html += '</select> ';
940
+
941
+ //
942
+ // minutes
943
+ //
944
+
945
+ html += ': <select class="minuteselect">';
946
+
947
+ for (var i = 0; i < 60; i += this.timePickerIncrement) {
948
+ var padded = i < 10 ? '0' + i : i;
949
+ var time = selected.clone().minute(i);
950
+
951
+ var disabled = false;
952
+ if (minDate && time.second(59).isBefore(minDate))
953
+ disabled = true;
954
+ if (maxDate && time.second(0).isAfter(maxDate))
955
+ disabled = true;
956
+
957
+ if (selected.minute() == i && !disabled) {
958
+ html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
959
+ } else if (disabled) {
960
+ html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
961
+ } else {
962
+ html += '<option value="' + i + '">' + padded + '</option>';
963
+ }
964
+ }
965
+
966
+ html += '</select> ';
967
+
968
+ //
969
+ // seconds
970
+ //
971
+
972
+ if (this.timePickerSeconds) {
973
+ html += ': <select class="secondselect">';
974
+
975
+ for (var i = 0; i < 60; i++) {
976
+ var padded = i < 10 ? '0' + i : i;
977
+ var time = selected.clone().second(i);
978
+
979
+ var disabled = false;
980
+ if (minDate && time.isBefore(minDate))
981
+ disabled = true;
982
+ if (maxDate && time.isAfter(maxDate))
983
+ disabled = true;
984
+
985
+ if (selected.second() == i && !disabled) {
986
+ html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
987
+ } else if (disabled) {
988
+ html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
989
+ } else {
990
+ html += '<option value="' + i + '">' + padded + '</option>';
991
+ }
992
+ }
993
+
994
+ html += '</select> ';
995
+ }
996
+
997
+ //
998
+ // AM/PM
999
+ //
1000
+
1001
+ if (!this.timePicker24Hour) {
1002
+ html += '<select class="ampmselect">';
1003
+
1004
+ var am_html = '';
1005
+ var pm_html = '';
1006
+
1007
+ if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate))
1008
+ am_html = ' disabled="disabled" class="disabled"';
1009
+
1010
+ if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate))
1011
+ pm_html = ' disabled="disabled" class="disabled"';
1012
+
1013
+ if (selected.hour() >= 12) {
1014
+ html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>';
1015
+ } else {
1016
+ html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>';
1017
+ }
1018
+
1019
+ html += '</select>';
1020
+ }
1021
+
1022
+ this.container.find('.calendar.' + side + ' .calendar-time div').html(html);
1023
+
1024
+ },
1025
+
1026
+ updateFormInputs: function() {
1027
+
1028
+ //ignore mouse movements while an above-calendar text input has focus
1029
+ if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
1030
+ return;
1031
+
1032
+ this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.locale.format));
1033
+ if (this.endDate)
1034
+ this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.locale.format));
1035
+
1036
+ if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) {
1037
+ this.container.find('button.applyBtn').removeAttr('disabled');
1038
+ } else {
1039
+ this.container.find('button.applyBtn').attr('disabled', 'disabled');
1040
+ }
1041
+
1042
+ },
1043
+
1044
+ move: function() {
1045
+ var parentOffset = { top: 0, left: 0 },
1046
+ containerTop;
1047
+ var parentRightEdge = $(window).width();
1048
+ if (!this.parentEl.is('body')) {
1049
+ parentOffset = {
1050
+ top: this.parentEl.offset().top - this.parentEl.scrollTop(),
1051
+ left: this.parentEl.offset().left - this.parentEl.scrollLeft()
1052
+ };
1053
+ parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
1054
+ }
1055
+
1056
+ if (this.drops == 'up')
1057
+ containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1058
+ else
1059
+ containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1060
+ this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('dropup');
1061
+
1062
+ if (this.opens == 'left') {
1063
+ this.container.css({
1064
+ top: containerTop,
1065
+ right: parentRightEdge - this.element.offset().left - this.element.outerWidth(),
1066
+ left: 'auto'
1067
+ });
1068
+ if (this.container.offset().left < 0) {
1069
+ this.container.css({
1070
+ right: 'auto',
1071
+ left: 9
1072
+ });
1073
+ }
1074
+ } else if (this.opens == 'center') {
1075
+ this.container.css({
1076
+ top: containerTop,
1077
+ left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2
1078
+ - this.container.outerWidth() / 2,
1079
+ right: 'auto'
1080
+ });
1081
+ if (this.container.offset().left < 0) {
1082
+ this.container.css({
1083
+ right: 'auto',
1084
+ left: 9
1085
+ });
1086
+ }
1087
+ } else {
1088
+ this.container.css({
1089
+ top: containerTop,
1090
+ left: this.element.offset().left - parentOffset.left,
1091
+ right: 'auto'
1092
+ });
1093
+ if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {
1094
+ this.container.css({
1095
+ left: 'auto',
1096
+ right: 0
1097
+ });
1098
+ }
1099
+ }
1100
+ },
1101
+
1102
+ show: function(e) {
1103
+ if (this.isShowing) return;
1104
+
1105
+ // Create a click proxy that is private to this instance of datepicker, for unbinding
1106
+ this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this);
1107
+
1108
+ // Bind global datepicker mousedown for hiding and
1109
+ $(document)
1110
+ .on('mousedown.daterangepicker', this._outsideClickProxy)
1111
+ // also support mobile devices
1112
+ .on('touchend.daterangepicker', this._outsideClickProxy)
1113
+ // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
1114
+ .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
1115
+ // and also close when focus changes to outside the picker (eg. tabbing between controls)
1116
+ .on('focusin.daterangepicker', this._outsideClickProxy);
1117
+
1118
+ // Reposition the picker if the window is resized while it's open
1119
+ $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this));
1120
+
1121
+ this.oldStartDate = this.startDate.clone();
1122
+ this.oldEndDate = this.endDate.clone();
1123
+ this.previousRightTime = this.endDate.clone();
1124
+
1125
+ this.updateView();
1126
+ this.container.show();
1127
+ this.move();
1128
+ this.element.trigger('show.daterangepicker', this);
1129
+ this.isShowing = true;
1130
+ },
1131
+
1132
+ hide: function(e) {
1133
+ if (!this.isShowing) return;
1134
+
1135
+ //incomplete date selection, revert to last values
1136
+ if (!this.endDate) {
1137
+ this.startDate = this.oldStartDate.clone();
1138
+ this.endDate = this.oldEndDate.clone();
1139
+ }
1140
+
1141
+ //if a new date range was selected, invoke the user callback function
1142
+ if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
1143
+ this.callback(this.startDate, this.endDate, this.chosenLabel);
1144
+
1145
+ //if picker is attached to a text input, update it
1146
+ this.updateElement();
1147
+
1148
+ $(document).off('.daterangepicker');
1149
+ $(window).off('.daterangepicker');
1150
+ this.container.hide();
1151
+ this.element.trigger('hide.daterangepicker', this);
1152
+ this.isShowing = false;
1153
+ },
1154
+
1155
+ toggle: function(e) {
1156
+ if (this.isShowing) {
1157
+ this.hide();
1158
+ } else {
1159
+ this.show();
1160
+ }
1161
+ },
1162
+
1163
+ outsideClick: function(e) {
1164
+ var target = $(e.target);
1165
+ // if the page is clicked anywhere except within the daterangerpicker/button
1166
+ // itself then call this.hide()
1167
+ if (
1168
+ // ie modal dialog fix
1169
+ e.type == "focusin" ||
1170
+ target.closest(this.element).length ||
1171
+ target.closest(this.container).length ||
1172
+ target.closest('.calendar-table').length
1173
+ ) return;
1174
+ this.hide();
1175
+ this.element.trigger('outsideClick.daterangepicker', this);
1176
+ },
1177
+
1178
+ showCalendars: function() {
1179
+ this.container.addClass('show-calendar');
1180
+ this.move();
1181
+ this.element.trigger('showCalendar.daterangepicker', this);
1182
+ },
1183
+
1184
+ hideCalendars: function() {
1185
+ this.container.removeClass('show-calendar');
1186
+ this.element.trigger('hideCalendar.daterangepicker', this);
1187
+ },
1188
+
1189
+ hoverRange: function(e) {
1190
+
1191
+ //ignore mouse movements while an above-calendar text input has focus
1192
+ if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
1193
+ return;
1194
+
1195
+ var label = e.target.getAttribute('data-range-key');
1196
+
1197
+ if (label == this.locale.customRangeLabel) {
1198
+ this.updateView();
1199
+ } else {
1200
+ var dates = this.ranges[label];
1201
+ this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.locale.format));
1202
+ this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.locale.format));
1203
+ }
1204
+
1205
+ },
1206
+
1207
+ clickRange: function(e) {
1208
+ var label = e.target.getAttribute('data-range-key');
1209
+ this.chosenLabel = label;
1210
+ if (label == this.locale.customRangeLabel) {
1211
+ this.showCalendars();
1212
+ } else {
1213
+ var dates = this.ranges[label];
1214
+ this.startDate = dates[0];
1215
+ this.endDate = dates[1];
1216
+
1217
+ if (!this.timePicker) {
1218
+ this.startDate.startOf('day');
1219
+ this.endDate.endOf('day');
1220
+ }
1221
+
1222
+ if (!this.alwaysShowCalendars)
1223
+ this.hideCalendars();
1224
+ this.clickApply();
1225
+ }
1226
+ },
1227
+
1228
+ clickPrev: function(e) {
1229
+ var cal = $(e.target).parents('.calendar');
1230
+ if (cal.hasClass('left')) {
1231
+ this.leftCalendar.month.subtract(1, 'month');
1232
+ if (this.linkedCalendars)
1233
+ this.rightCalendar.month.subtract(1, 'month');
1234
+ } else {
1235
+ this.rightCalendar.month.subtract(1, 'month');
1236
+ }
1237
+ this.updateCalendars();
1238
+ },
1239
+
1240
+ clickNext: function(e) {
1241
+ var cal = $(e.target).parents('.calendar');
1242
+ if (cal.hasClass('left')) {
1243
+ this.leftCalendar.month.add(1, 'month');
1244
+ } else {
1245
+ this.rightCalendar.month.add(1, 'month');
1246
+ if (this.linkedCalendars)
1247
+ this.leftCalendar.month.add(1, 'month');
1248
+ }
1249
+ this.updateCalendars();
1250
+ },
1251
+
1252
+ hoverDate: function(e) {
1253
+
1254
+ //ignore mouse movements while an above-calendar text input has focus
1255
+ //if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
1256
+ // return;
1257
+
1258
+ //ignore dates that can't be selected
1259
+ if (!$(e.target).hasClass('available')) return;
1260
+
1261
+ //have the text inputs above calendars reflect the date being hovered over
1262
+ var title = $(e.target).attr('data-title');
1263
+ var row = title.substr(1, 1);
1264
+ var col = title.substr(3, 1);
1265
+ var cal = $(e.target).parents('.calendar');
1266
+ var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1267
+
1268
+ if (this.endDate && !this.container.find('input[name=daterangepicker_start]').is(":focus")) {
1269
+ this.container.find('input[name=daterangepicker_start]').val(date.format(this.locale.format));
1270
+ } else if (!this.endDate && !this.container.find('input[name=daterangepicker_end]').is(":focus")) {
1271
+ this.container.find('input[name=daterangepicker_end]').val(date.format(this.locale.format));
1272
+ }
1273
+
1274
+ //highlight the dates between the start date and the date being hovered as a potential end date
1275
+ var leftCalendar = this.leftCalendar;
1276
+ var rightCalendar = this.rightCalendar;
1277
+ var startDate = this.startDate;
1278
+ if (!this.endDate) {
1279
+ this.container.find('.calendar td').each(function(index, el) {
1280
+
1281
+ //skip week numbers, only look at dates
1282
+ if ($(el).hasClass('week')) return;
1283
+
1284
+ var title = $(el).attr('data-title');
1285
+ var row = title.substr(1, 1);
1286
+ var col = title.substr(3, 1);
1287
+ var cal = $(el).parents('.calendar');
1288
+ var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1289
+
1290
+ if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) {
1291
+ $(el).addClass('in-range');
1292
+ } else {
1293
+ $(el).removeClass('in-range');
1294
+ }
1295
+
1296
+ });
1297
+ }
1298
+
1299
+ },
1300
+
1301
+ clickDate: function(e) {
1302
+
1303
+ if (!$(e.target).hasClass('available')) return;
1304
+
1305
+ var title = $(e.target).attr('data-title');
1306
+ var row = title.substr(1, 1);
1307
+ var col = title.substr(3, 1);
1308
+ var cal = $(e.target).parents('.calendar');
1309
+ var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1310
+
1311
+ //
1312
+ // this function needs to do a few things:
1313
+ // * alternate between selecting a start and end date for the range,
1314
+ // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date
1315
+ // * if autoapply is enabled, and an end date was chosen, apply the selection
1316
+ // * if single date picker mode, and time picker isn't enabled, apply the selection immediately
1317
+ // * if one of the inputs above the calendars was focused, cancel that manual input
1318
+ //
1319
+
1320
+ if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start
1321
+ if (this.timePicker) {
1322
+ var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
1323
+ if (!this.timePicker24Hour) {
1324
+ var ampm = this.container.find('.left .ampmselect').val();
1325
+ if (ampm === 'PM' && hour < 12)
1326
+ hour += 12;
1327
+ if (ampm === 'AM' && hour === 12)
1328
+ hour = 0;
1329
+ }
1330
+ var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
1331
+ var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
1332
+ date = date.clone().hour(hour).minute(minute).second(second);
1333
+ }
1334
+ this.endDate = null;
1335
+ this.setStartDate(date.clone());
1336
+ } else if (!this.endDate && date.isBefore(this.startDate)) {
1337
+ //special case: clicking the same date for start/end,
1338
+ //but the time of the end date is before the start date
1339
+ this.setEndDate(this.startDate.clone());
1340
+ } else { // picking end
1341
+ if (this.timePicker) {
1342
+ var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
1343
+ if (!this.timePicker24Hour) {
1344
+ var ampm = this.container.find('.right .ampmselect').val();
1345
+ if (ampm === 'PM' && hour < 12)
1346
+ hour += 12;
1347
+ if (ampm === 'AM' && hour === 12)
1348
+ hour = 0;
1349
+ }
1350
+ var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
1351
+ var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
1352
+ date = date.clone().hour(hour).minute(minute).second(second);
1353
+ }
1354
+ this.setEndDate(date.clone());
1355
+ if (this.autoApply) {
1356
+ this.calculateChosenLabel();
1357
+ this.clickApply();
1358
+ }
1359
+ }
1360
+
1361
+ if (this.singleDatePicker) {
1362
+ this.setEndDate(this.startDate);
1363
+ if (!this.timePicker)
1364
+ this.clickApply();
1365
+ }
1366
+
1367
+ this.updateView();
1368
+
1369
+ //This is to cancel the blur event handler if the mouse was in one of the inputs
1370
+ e.stopPropagation();
1371
+
1372
+ },
1373
+
1374
+ calculateChosenLabel: function () {
1375
+ var customRange = true;
1376
+ var i = 0;
1377
+ for (var range in this.ranges) {
1378
+ if (this.timePicker) {
1379
+ if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) {
1380
+ customRange = false;
1381
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html();
1382
+ break;
1383
+ }
1384
+ } else {
1385
+ //ignore times when comparing dates if time picker is not enabled
1386
+ if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {
1387
+ customRange = false;
1388
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html();
1389
+ break;
1390
+ }
1391
+ }
1392
+ i++;
1393
+ }
1394
+ if (customRange) {
1395
+ if (this.showCustomRangeLabel) {
1396
+ this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html();
1397
+ } else {
1398
+ this.chosenLabel = null;
1399
+ }
1400
+ this.showCalendars();
1401
+ }
1402
+ },
1403
+
1404
+ clickApply: function(e) {
1405
+ this.hide();
1406
+ this.noneDefaultValue = false;
1407
+ this.element.trigger('apply.daterangepicker', this);
1408
+ },
1409
+
1410
+ clickCancel: function(e) {
1411
+ this.startDate = this.oldStartDate;
1412
+ this.endDate = this.oldEndDate;
1413
+ this.hide();
1414
+ if(this.noneDefaultValue){
1415
+ this.element.val("");
1416
+ }
1417
+ this.element.trigger('cancel.daterangepicker', this);
1418
+ },
1419
+
1420
+ monthOrYearChanged: function(e) {
1421
+ var isLeft = $(e.target).closest('.calendar').hasClass('left'),
1422
+ leftOrRight = isLeft ? 'left' : 'right',
1423
+ cal = this.container.find('.calendar.'+leftOrRight);
1424
+
1425
+ // Month must be Number for new moment versions
1426
+ var month = parseInt(cal.find('.monthselect').val(), 10);
1427
+ var year = cal.find('.yearselect').val();
1428
+
1429
+ if (!isLeft) {
1430
+ if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {
1431
+ month = this.startDate.month();
1432
+ year = this.startDate.year();
1433
+ }
1434
+ }
1435
+
1436
+ if (this.minDate) {
1437
+ if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) {
1438
+ month = this.minDate.month();
1439
+ year = this.minDate.year();
1440
+ }
1441
+ }
1442
+
1443
+ if (this.maxDate) {
1444
+ if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) {
1445
+ month = this.maxDate.month();
1446
+ year = this.maxDate.year();
1447
+ }
1448
+ }
1449
+
1450
+ if (isLeft) {
1451
+ this.leftCalendar.month.month(month).year(year);
1452
+ if (this.linkedCalendars)
1453
+ this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month');
1454
+ } else {
1455
+ this.rightCalendar.month.month(month).year(year);
1456
+ if (this.linkedCalendars)
1457
+ this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month');
1458
+ }
1459
+ this.updateCalendars();
1460
+ },
1461
+
1462
+ timeChanged: function(e) {
1463
+
1464
+ var cal = $(e.target).closest('.calendar'),
1465
+ isLeft = cal.hasClass('left');
1466
+
1467
+ var hour = parseInt(cal.find('.hourselect').val(), 10);
1468
+ var minute = parseInt(cal.find('.minuteselect').val(), 10);
1469
+ var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0;
1470
+
1471
+ if (!this.timePicker24Hour) {
1472
+ var ampm = cal.find('.ampmselect').val();
1473
+ if (ampm === 'PM' && hour < 12)
1474
+ hour += 12;
1475
+ if (ampm === 'AM' && hour === 12)
1476
+ hour = 0;
1477
+ }
1478
+
1479
+ if (isLeft) {
1480
+ var start = this.startDate.clone();
1481
+ start.hour(hour);
1482
+ start.minute(minute);
1483
+ start.second(second);
1484
+ this.setStartDate(start);
1485
+ if (this.singleDatePicker) {
1486
+ this.endDate = this.startDate.clone();
1487
+ } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) {
1488
+ this.setEndDate(start.clone());
1489
+ }
1490
+ } else if (this.endDate) {
1491
+ var end = this.endDate.clone();
1492
+ end.hour(hour);
1493
+ end.minute(minute);
1494
+ end.second(second);
1495
+ this.setEndDate(end);
1496
+ }
1497
+
1498
+ //update the calendars so all clickable dates reflect the new time component
1499
+ this.updateCalendars();
1500
+
1501
+ //update the form inputs above the calendars with the new time
1502
+ this.updateFormInputs();
1503
+
1504
+ //re-render the time pickers because changing one selection can affect what's enabled in another
1505
+ this.renderTimePicker('left');
1506
+ this.renderTimePicker('right');
1507
+
1508
+ },
1509
+
1510
+ formInputsChanged: function(e) {
1511
+ var isRight = $(e.target).closest('.calendar').hasClass('right');
1512
+ var start = moment(this.container.find('input[name="daterangepicker_start"]').val(), this.locale.format);
1513
+ var end = moment(this.container.find('input[name="daterangepicker_end"]').val(), this.locale.format);
1514
+
1515
+ if (start.isValid() && end.isValid()) {
1516
+
1517
+ if (isRight && end.isBefore(start))
1518
+ start = end.clone();
1519
+
1520
+ this.setStartDate(start);
1521
+ this.setEndDate(end);
1522
+
1523
+ if (isRight) {
1524
+ this.container.find('input[name="daterangepicker_start"]').val(this.startDate.format(this.locale.format));
1525
+ } else {
1526
+ this.container.find('input[name="daterangepicker_end"]').val(this.endDate.format(this.locale.format));
1527
+ }
1528
+
1529
+ }
1530
+
1531
+ this.updateView();
1532
+ },
1533
+
1534
+ formInputsFocused: function(e) {
1535
+
1536
+ // Highlight the focused input
1537
+ this.container.find('input[name="daterangepicker_start"], input[name="daterangepicker_end"]').removeClass('active');
1538
+ $(e.target).addClass('active');
1539
+
1540
+ // Set the state such that if the user goes back to using a mouse,
1541
+ // the calendars are aware we're selecting the end of the range, not
1542
+ // the start. This allows someone to edit the end of a date range without
1543
+ // re-selecting the beginning, by clicking on the end date input then
1544
+ // using the calendar.
1545
+ var isRight = $(e.target).closest('.calendar').hasClass('right');
1546
+ if (isRight) {
1547
+ this.endDate = null;
1548
+ this.setStartDate(this.startDate.clone());
1549
+ this.updateView();
1550
+ }
1551
+
1552
+ },
1553
+
1554
+ formInputsBlurred: function(e) {
1555
+
1556
+ // this function has one purpose right now: if you tab from the first
1557
+ // text input to the second in the UI, the endDate is nulled so that
1558
+ // you can click another, but if you tab out without clicking anything
1559
+ // or changing the input value, the old endDate should be retained
1560
+
1561
+ if (!this.endDate) {
1562
+ var val = this.container.find('input[name="daterangepicker_end"]').val();
1563
+ var end = moment(val, this.locale.format);
1564
+ if (end.isValid()) {
1565
+ this.setEndDate(end);
1566
+ this.updateView();
1567
+ }
1568
+ }
1569
+
1570
+ },
1571
+
1572
+ elementChanged: function() {
1573
+ if (!this.element.is('input')) return;
1574
+ if (!this.element.val().length) return;
1575
+ if (this.element.val().length < this.locale.format.length) return;
1576
+
1577
+ var dateString = this.element.val().split(this.locale.separator),
1578
+ start = null,
1579
+ end = null;
1580
+
1581
+ if (dateString.length === 2) {
1582
+ start = moment(dateString[0], this.locale.format);
1583
+ end = moment(dateString[1], this.locale.format);
1584
+ }
1585
+
1586
+ if (this.singleDatePicker || start === null || end === null) {
1587
+ start = moment(this.element.val(), this.locale.format);
1588
+ end = start;
1589
+ }
1590
+
1591
+ if (!start.isValid() || !end.isValid()) return;
1592
+
1593
+ this.setStartDate(start);
1594
+ this.setEndDate(end);
1595
+ this.updateView();
1596
+ },
1597
+
1598
+ keydown: function(e) {
1599
+ //hide on tab or enter
1600
+ if ((e.keyCode === 9) || (e.keyCode === 13)) {
1601
+ this.hide();
1602
+ }
1603
+ },
1604
+
1605
+ updateElement: function() {
1606
+ if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) {
1607
+ this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
1608
+ this.element.trigger('change');
1609
+ } else if (this.element.is('input') && this.autoUpdateInput) {
1610
+ this.element.val(this.startDate.format(this.locale.format));
1611
+ this.element.trigger('change');
1612
+ }
1613
+ },
1614
+
1615
+ remove: function() {
1616
+ this.container.remove();
1617
+ this.element.off('.daterangepicker');
1618
+ this.element.removeData();
1619
+ }
1620
+
1621
+ };
1622
+
1623
+ $.fn.daterangepicker = function(options, callback) {
1624
+ this.each(function() {
1625
+ var el = $(this);
1626
+ if (el.data('daterangepicker'))
1627
+ el.data('daterangepicker').remove();
1628
+ el.data('daterangepicker', new DateRangePicker(el, options, callback));
1629
+ });
1630
+ return this;
1631
+ };
1632
+
1633
+ return DateRangePicker;
1634
+
1635
+ }));