@ntlab/ntjs-assets 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/assets/js/bootstrap-icons/bootstrap-icons.svg +1 -1
  2. package/assets/js/bootstrap-icons/folder-plus.svg +2 -2
  3. package/assets/js/bootstrap-icons/font/bootstrap-icons.css +1981 -0
  4. package/assets/js/bootstrap-icons/font/bootstrap-icons.json +1955 -0
  5. package/assets/js/bootstrap-icons/font/bootstrap-icons.min.css +5 -0
  6. package/assets/js/bootstrap-icons/font/bootstrap-icons.scss +1993 -0
  7. package/assets/js/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
  8. package/assets/js/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
  9. package/assets/js/bootstrap-icons/postcard-heart-fill.svg +1 -1
  10. package/assets/js/bootstrap-icons/trash.svg +2 -2
  11. package/assets/js/jquery/jquery.js +840 -1045
  12. package/assets/js/jquery/jquery.min.js +2 -2
  13. package/assets/js/jquery/jquery.min.map +1 -1
  14. package/assets/js/jquery/jquery.slim.js +834 -1039
  15. package/assets/js/jquery/jquery.slim.min.js +2 -2
  16. package/assets/js/jquery/jquery.slim.min.map +1 -1
  17. package/assets/js/popper.js/cjs/enums.js +1 -1
  18. package/assets/js/popper.js/cjs/popper-base.js +12 -170
  19. package/assets/js/popper.js/cjs/popper-base.js.map +1 -1
  20. package/assets/js/popper.js/cjs/popper-lite.js +14 -184
  21. package/assets/js/popper.js/cjs/popper-lite.js.map +1 -1
  22. package/assets/js/popper.js/cjs/popper.js +14 -197
  23. package/assets/js/popper.js/cjs/popper.js.map +1 -1
  24. package/assets/js/popper.js/esm/createPopper.js +6 -66
  25. package/assets/js/popper.js/esm/modifiers/arrow.js +1 -12
  26. package/assets/js/popper.js/esm/modifiers/computeStyles.js +2 -14
  27. package/assets/js/popper.js/esm/utils/computeAutoPlacement.js +0 -4
  28. package/assets/js/popper.js/esm/utils/userAgent.js +1 -1
  29. package/assets/js/popper.js/umd/enums.js +1 -1
  30. package/assets/js/popper.js/umd/enums.min.js +1 -1
  31. package/assets/js/popper.js/umd/popper-base.js +12 -170
  32. package/assets/js/popper.js/umd/popper-base.js.map +1 -1
  33. package/assets/js/popper.js/umd/popper-base.min.js +2 -2
  34. package/assets/js/popper.js/umd/popper-base.min.js.map +1 -1
  35. package/assets/js/popper.js/umd/popper-lite.js +14 -184
  36. package/assets/js/popper.js/umd/popper-lite.js.map +1 -1
  37. package/assets/js/popper.js/umd/popper-lite.min.js +2 -2
  38. package/assets/js/popper.js/umd/popper-lite.min.js.map +1 -1
  39. package/assets/js/popper.js/umd/popper.js +14 -197
  40. package/assets/js/popper.js/umd/popper.js.map +1 -1
  41. package/assets/js/popper.js/umd/popper.min.js +2 -2
  42. package/assets/js/popper.js/umd/popper.min.js.map +1 -1
  43. package/assets/js/semantic-ui/components/accordion.css +196 -74
  44. package/assets/js/semantic-ui/components/accordion.js +570 -591
  45. package/assets/js/semantic-ui/components/accordion.min.css +4 -4
  46. package/assets/js/semantic-ui/components/accordion.min.js +6 -6
  47. package/assets/js/semantic-ui/components/ad.css +40 -51
  48. package/assets/js/semantic-ui/components/ad.min.css +4 -4
  49. package/assets/js/semantic-ui/components/api.js +1154 -1117
  50. package/assets/js/semantic-ui/components/api.min.js +6 -6
  51. package/assets/js/semantic-ui/components/breadcrumb.css +7 -7
  52. package/assets/js/semantic-ui/components/breadcrumb.min.css +4 -4
  53. package/assets/js/semantic-ui/components/button.css +895 -1227
  54. package/assets/js/semantic-ui/components/button.min.css +4 -4
  55. package/assets/js/semantic-ui/components/calendar.css +60 -33
  56. package/assets/js/semantic-ui/components/calendar.js +1952 -1575
  57. package/assets/js/semantic-ui/components/calendar.min.css +4 -4
  58. package/assets/js/semantic-ui/components/calendar.min.js +6 -6
  59. package/assets/js/semantic-ui/components/card.css +1004 -441
  60. package/assets/js/semantic-ui/components/card.min.css +4 -4
  61. package/assets/js/semantic-ui/components/checkbox.css +275 -303
  62. package/assets/js/semantic-ui/components/checkbox.js +863 -855
  63. package/assets/js/semantic-ui/components/checkbox.min.css +4 -4
  64. package/assets/js/semantic-ui/components/checkbox.min.js +6 -6
  65. package/assets/js/semantic-ui/components/comment.css +45 -63
  66. package/assets/js/semantic-ui/components/comment.min.css +4 -4
  67. package/assets/js/semantic-ui/components/container.css +98 -4
  68. package/assets/js/semantic-ui/components/container.min.css +4 -4
  69. package/assets/js/semantic-ui/components/dimmer.css +95 -196
  70. package/assets/js/semantic-ui/components/dimmer.js +698 -717
  71. package/assets/js/semantic-ui/components/dimmer.min.css +4 -4
  72. package/assets/js/semantic-ui/components/dimmer.min.js +6 -6
  73. package/assets/js/semantic-ui/components/divider.css +75 -93
  74. package/assets/js/semantic-ui/components/divider.min.css +4 -4
  75. package/assets/js/semantic-ui/components/dropdown.css +490 -413
  76. package/assets/js/semantic-ui/components/dropdown.js +4203 -4068
  77. package/assets/js/semantic-ui/components/dropdown.min.css +4 -4
  78. package/assets/js/semantic-ui/components/dropdown.min.js +6 -6
  79. package/assets/js/semantic-ui/components/embed.css +27 -38
  80. package/assets/js/semantic-ui/components/embed.js +647 -673
  81. package/assets/js/semantic-ui/components/embed.min.css +4 -4
  82. package/assets/js/semantic-ui/components/embed.min.js +6 -6
  83. package/assets/js/semantic-ui/components/emoji.css +11156 -9192
  84. package/assets/js/semantic-ui/components/emoji.min.css +3 -3
  85. package/assets/js/semantic-ui/components/feed.css +56 -78
  86. package/assets/js/semantic-ui/components/feed.min.css +4 -4
  87. package/assets/js/semantic-ui/components/flag.css +1037 -929
  88. package/assets/js/semantic-ui/components/flag.min.css +4 -4
  89. package/assets/js/semantic-ui/components/flyout.css +552 -0
  90. package/assets/js/semantic-ui/components/flyout.js +1567 -0
  91. package/assets/js/semantic-ui/components/flyout.min.css +9 -0
  92. package/assets/js/semantic-ui/components/flyout.min.js +11 -0
  93. package/assets/js/semantic-ui/components/form.css +536 -530
  94. package/assets/js/semantic-ui/components/form.js +2037 -1945
  95. package/assets/js/semantic-ui/components/form.min.css +4 -4
  96. package/assets/js/semantic-ui/components/form.min.js +6 -6
  97. package/assets/js/semantic-ui/components/grid.css +218 -345
  98. package/assets/js/semantic-ui/components/grid.min.css +4 -4
  99. package/assets/js/semantic-ui/components/header.css +137 -154
  100. package/assets/js/semantic-ui/components/header.min.css +4 -4
  101. package/assets/js/semantic-ui/components/icon.css +3000 -2750
  102. package/assets/js/semantic-ui/components/icon.min.css +4 -4
  103. package/assets/js/semantic-ui/components/image.css +54 -49
  104. package/assets/js/semantic-ui/components/image.min.css +4 -4
  105. package/assets/js/semantic-ui/components/input.css +1081 -227
  106. package/assets/js/semantic-ui/components/input.min.css +4 -4
  107. package/assets/js/semantic-ui/components/item.css +91 -138
  108. package/assets/js/semantic-ui/components/item.min.css +4 -4
  109. package/assets/js/semantic-ui/components/label.css +470 -481
  110. package/assets/js/semantic-ui/components/label.min.css +4 -4
  111. package/assets/js/semantic-ui/components/list.css +93 -114
  112. package/assets/js/semantic-ui/components/list.min.css +4 -4
  113. package/assets/js/semantic-ui/components/loader.css +452 -536
  114. package/assets/js/semantic-ui/components/loader.min.css +4 -4
  115. package/assets/js/semantic-ui/components/menu.css +408 -510
  116. package/assets/js/semantic-ui/components/menu.min.css +9 -1
  117. package/assets/js/semantic-ui/components/message.css +188 -213
  118. package/assets/js/semantic-ui/components/message.min.css +4 -4
  119. package/assets/js/semantic-ui/components/modal.css +174 -166
  120. package/assets/js/semantic-ui/components/modal.js +1558 -1146
  121. package/assets/js/semantic-ui/components/modal.min.css +4 -4
  122. package/assets/js/semantic-ui/components/modal.min.js +6 -6
  123. package/assets/js/semantic-ui/components/nag.css +183 -41
  124. package/assets/js/semantic-ui/components/nag.js +527 -467
  125. package/assets/js/semantic-ui/components/nag.min.css +4 -4
  126. package/assets/js/semantic-ui/components/nag.min.js +6 -6
  127. package/assets/js/semantic-ui/components/placeholder.css +62 -76
  128. package/assets/js/semantic-ui/components/placeholder.min.css +4 -4
  129. package/assets/js/semantic-ui/components/popup.css +681 -312
  130. package/assets/js/semantic-ui/components/popup.js +1470 -1463
  131. package/assets/js/semantic-ui/components/popup.min.css +4 -4
  132. package/assets/js/semantic-ui/components/popup.min.js +6 -6
  133. package/assets/js/semantic-ui/components/progress.css +149 -217
  134. package/assets/js/semantic-ui/components/progress.js +945 -1002
  135. package/assets/js/semantic-ui/components/progress.min.css +4 -4
  136. package/assets/js/semantic-ui/components/progress.min.js +6 -6
  137. package/assets/js/semantic-ui/components/rail.css +17 -22
  138. package/assets/js/semantic-ui/components/rail.min.css +3 -3
  139. package/assets/js/semantic-ui/components/rating.css +89 -184
  140. package/assets/js/semantic-ui/components/rating.js +509 -521
  141. package/assets/js/semantic-ui/components/rating.min.css +4 -4
  142. package/assets/js/semantic-ui/components/rating.min.js +6 -6
  143. package/assets/js/semantic-ui/components/reset.css +12 -17
  144. package/assets/js/semantic-ui/components/reset.min.css +4 -4
  145. package/assets/js/semantic-ui/components/reveal.css +46 -85
  146. package/assets/js/semantic-ui/components/reveal.min.css +4 -4
  147. package/assets/js/semantic-ui/components/search.css +157 -96
  148. package/assets/js/semantic-ui/components/search.js +1522 -1479
  149. package/assets/js/semantic-ui/components/search.min.css +4 -4
  150. package/assets/js/semantic-ui/components/search.min.js +6 -6
  151. package/assets/js/semantic-ui/components/segment.css +317 -249
  152. package/assets/js/semantic-ui/components/segment.min.css +4 -4
  153. package/assets/js/semantic-ui/components/shape.css +16 -32
  154. package/assets/js/semantic-ui/components/shape.js +763 -812
  155. package/assets/js/semantic-ui/components/shape.min.css +4 -4
  156. package/assets/js/semantic-ui/components/shape.min.js +6 -6
  157. package/assets/js/semantic-ui/components/sidebar.css +128 -216
  158. package/assets/js/semantic-ui/components/sidebar.js +1042 -1003
  159. package/assets/js/semantic-ui/components/sidebar.min.css +4 -4
  160. package/assets/js/semantic-ui/components/sidebar.min.js +6 -6
  161. package/assets/js/semantic-ui/components/site.css +123 -48
  162. package/assets/js/semantic-ui/components/site.js +438 -478
  163. package/assets/js/semantic-ui/components/site.min.css +4 -4
  164. package/assets/js/semantic-ui/components/site.min.js +6 -6
  165. package/assets/js/semantic-ui/components/slider.css +133 -141
  166. package/assets/js/semantic-ui/components/slider.js +1312 -1274
  167. package/assets/js/semantic-ui/components/slider.min.css +9 -1
  168. package/assets/js/semantic-ui/components/slider.min.js +6 -6
  169. package/assets/js/semantic-ui/components/state.js +640 -659
  170. package/assets/js/semantic-ui/components/state.min.js +6 -6
  171. package/assets/js/semantic-ui/components/statistic.css +83 -124
  172. package/assets/js/semantic-ui/components/statistic.min.css +4 -4
  173. package/assets/js/semantic-ui/components/step.css +118 -184
  174. package/assets/js/semantic-ui/components/step.min.css +4 -4
  175. package/assets/js/semantic-ui/components/sticky.css +3 -8
  176. package/assets/js/semantic-ui/components/sticky.js +849 -892
  177. package/assets/js/semantic-ui/components/sticky.min.css +4 -4
  178. package/assets/js/semantic-ui/components/sticky.min.js +6 -6
  179. package/assets/js/semantic-ui/components/tab.css +16 -20
  180. package/assets/js/semantic-ui/components/tab.js +896 -941
  181. package/assets/js/semantic-ui/components/tab.min.css +4 -4
  182. package/assets/js/semantic-ui/components/tab.min.js +6 -6
  183. package/assets/js/semantic-ui/components/table.css +2073 -884
  184. package/assets/js/semantic-ui/components/table.min.css +4 -4
  185. package/assets/js/semantic-ui/components/text.css +51 -30
  186. package/assets/js/semantic-ui/components/text.min.css +4 -4
  187. package/assets/js/semantic-ui/components/toast.css +200 -137
  188. package/assets/js/semantic-ui/components/toast.js +912 -832
  189. package/assets/js/semantic-ui/components/toast.min.css +4 -4
  190. package/assets/js/semantic-ui/components/toast.min.js +6 -6
  191. package/assets/js/semantic-ui/components/transition.css +371 -1282
  192. package/assets/js/semantic-ui/components/transition.js +999 -1074
  193. package/assets/js/semantic-ui/components/transition.min.css +4 -4
  194. package/assets/js/semantic-ui/components/transition.min.js +6 -6
  195. package/assets/js/semantic-ui/components/visibility.js +1215 -1247
  196. package/assets/js/semantic-ui/components/visibility.min.js +6 -6
  197. package/assets/js/semantic-ui/semantic.css +43777 -37429
  198. package/assets/js/semantic-ui/semantic.js +29152 -26694
  199. package/assets/js/semantic-ui/semantic.min.css +6 -399
  200. package/assets/js/semantic-ui/semantic.min.js +6 -6
  201. package/assets/js/semantic-ui/themes/basic/assets/fonts/icons.woff2 +0 -0
  202. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Bold.woff +0 -0
  203. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Bold.woff2 +0 -0
  204. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff +0 -0
  205. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  206. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Italic.woff +0 -0
  207. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Italic.woff2 +0 -0
  208. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Regular.woff +0 -0
  209. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Regular.woff2 +0 -0
  210. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  211. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  212. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff +0 -0
  213. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff2 +0 -0
  214. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff +0 -0
  215. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff2 +0 -0
  216. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  217. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  218. package/assets/js/semantic-ui/themes/default/assets/fonts/brand-icons.woff +0 -0
  219. package/assets/js/semantic-ui/themes/default/assets/fonts/brand-icons.woff2 +0 -0
  220. package/assets/js/semantic-ui/themes/default/assets/fonts/icons.woff +0 -0
  221. package/assets/js/semantic-ui/themes/default/assets/fonts/icons.woff2 +0 -0
  222. package/assets/js/semantic-ui/themes/default/assets/fonts/outline-icons.woff +0 -0
  223. package/assets/js/semantic-ui/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  224. package/assets/js/semantic-ui/themes/famfamfam/assets/images/flags.png +0 -0
  225. package/assets/js/semantic-ui/themes/github/assets/fonts/octicons.woff2 +0 -0
  226. package/assets/js/socket.io/socket.io.esm.min.js +3 -3
  227. package/assets/js/socket.io/socket.io.esm.min.js.map +1 -1
  228. package/assets/js/socket.io/socket.io.js +841 -333
  229. package/assets/js/socket.io/socket.io.js.map +1 -1
  230. package/assets/js/socket.io/socket.io.min.js +3 -3
  231. package/assets/js/socket.io/socket.io.min.js.map +1 -1
  232. package/assets/js/socket.io/socket.io.msgpack.min.js +3 -3
  233. package/assets/js/socket.io/socket.io.msgpack.min.js.map +1 -1
  234. package/cdn.json +19 -4
  235. package/package.json +1 -1
@@ -1,1638 +1,2015 @@
1
1
  /*!
2
- * # Fomantic-UI - Calendar
3
- * http://github.com/fomantic/Fomantic-UI/
2
+ * # Fomantic-UI 2.9.2 - Calendar
3
+ * https://github.com/fomantic/Fomantic-UI/
4
4
  *
5
5
  *
6
6
  * Released under the MIT license
7
- * http://opensource.org/licenses/MIT
7
+ * https://opensource.org/licenses/MIT
8
8
  *
9
9
  */
10
10
 
11
- ;(function ($, window, document, undefined) {
11
+ (function ($, window, document) {
12
+ 'use strict';
12
13
 
13
- 'use strict';
14
+ function isFunction(obj) {
15
+ return typeof obj === 'function' && typeof obj.nodeType !== 'number';
16
+ }
14
17
 
15
- $.isFunction = $.isFunction || function(obj) {
16
- return typeof obj === "function" && typeof obj.nodeType !== "number";
17
- };
18
+ window = window !== undefined && window.Math === Math
19
+ ? window
20
+ : globalThis;
21
+
22
+ $.fn.calendar = function (parameters) {
23
+ var
24
+ $allModules = $(this),
25
+ $document = $(document),
26
+
27
+ moduleSelector = $allModules.selector || '',
28
+
29
+ time = Date.now(),
30
+ performance = [],
31
+
32
+ query = arguments[0],
33
+ methodInvoked = typeof query === 'string',
34
+ queryArguments = [].slice.call(arguments, 1),
35
+ returnedValue,
36
+ timeGapTable = {
37
+ 5: { row: 4, column: 3 },
38
+ 10: { row: 3, column: 2 },
39
+ 15: { row: 2, column: 2 },
40
+ 20: { row: 3, column: 1 },
41
+ 30: { row: 2, column: 1 },
42
+ },
43
+ numberText = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
44
+ ;
45
+
46
+ $allModules.each(function () {
47
+ var
48
+ settings = $.isPlainObject(parameters)
49
+ ? $.extend(true, {}, $.fn.calendar.settings, parameters)
50
+ : $.extend({}, $.fn.calendar.settings),
51
+
52
+ className = settings.className,
53
+ namespace = settings.namespace,
54
+ selector = settings.selector,
55
+ formatter = settings.formatter,
56
+ parser = settings.parser,
57
+ metadata = settings.metadata,
58
+ timeGap = timeGapTable[settings.minTimeGap],
59
+ error = settings.error,
60
+
61
+ eventNamespace = '.' + namespace,
62
+ moduleNamespace = 'module-' + namespace,
63
+
64
+ $module = $(this),
65
+ $input = $module.find(selector.input),
66
+ $activator = $module.find(selector.activator),
67
+
68
+ element = this,
69
+ instance = $module.data(moduleNamespace),
70
+ $container = instance && instance.popupId ? $document.find('#' + instance.popupId) : $module.find(selector.popup),
71
+
72
+ isTouch,
73
+ isTouchDown = false,
74
+ isInverted = $module.hasClass(className.inverted),
75
+ focusDateUsedForRange = false,
76
+ selectionComplete = false,
77
+ classObserver,
78
+ module
79
+ ;
18
80
 
19
- window = (typeof window != 'undefined' && window.Math == Math)
20
- ? window
21
- : (typeof self != 'undefined' && self.Math == Math)
22
- ? self
23
- : Function('return this')()
24
- ;
81
+ module = {
82
+
83
+ initialize: function () {
84
+ module.debug('Initializing calendar for', element, $module);
85
+
86
+ isTouch = module.get.isTouch();
87
+ module.setup.config();
88
+ module.setup.popup();
89
+ module.setup.inline();
90
+ module.setup.input();
91
+ module.setup.date();
92
+ module.create.calendar();
93
+
94
+ module.bind.events();
95
+ module.observeChanges();
96
+ module.instantiate();
97
+ },
98
+
99
+ instantiate: function () {
100
+ module.verbose('Storing instance of calendar');
101
+ instance = module;
102
+ $module.data(moduleNamespace, instance);
103
+ },
104
+
105
+ destroy: function () {
106
+ module.verbose('Destroying previous calendar for', element);
107
+ $module.removeData(moduleNamespace);
108
+ module.unbind.events();
109
+ module.disconnect.classObserver();
110
+ },
111
+
112
+ setup: {
113
+ config: function () {
114
+ if (module.get.minDate() !== null) {
115
+ module.set.minDate($module.data(metadata.minDate));
116
+ }
117
+ if (module.get.maxDate() !== null) {
118
+ module.set.maxDate($module.data(metadata.maxDate));
119
+ }
120
+ module.setting('type', module.get.type());
121
+ module.setting('on', settings.on || 'click');
122
+ },
123
+ popup: function () {
124
+ if (settings.inline) {
125
+ return;
126
+ }
127
+ if ($activator.length === 0) {
128
+ $activator = $module.children().first();
129
+ if ($activator.length === 0) {
130
+ return;
131
+ }
132
+ }
133
+ if ($.fn.popup === undefined) {
134
+ module.error(error.popup);
135
+
136
+ return;
137
+ }
138
+ if ($container.length === 0) {
139
+ if (settings.context) {
140
+ module.popupId = namespace + '_popup_' + (Math.random().toString(16) + '000000000').slice(2, 10);
141
+ $container = $('<div/>', { id: module.popupId }).addClass(className.popup).appendTo($document.find(settings.context));
142
+ } else {
143
+ // prepend the popup element to the activator's parent so that it has less chance of messing with
144
+ // the styling (eg input action button needs to be the last child to have correct border radius)
145
+ var
146
+ $activatorParent = $activator.parent(),
147
+ domPositionFunction = $activatorParent.closest(selector.append).length > 0 ? 'appendTo' : 'prependTo'
148
+ ;
149
+ $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent);
150
+ }
151
+ }
152
+ $container.addClass(className.calendar);
153
+ if (isInverted) {
154
+ $container.addClass(className.inverted);
155
+ }
156
+ var onVisible = function () {
157
+ module.refreshTooltips();
158
+
159
+ return settings.onVisible.apply($container, arguments);
160
+ };
161
+ var onHidden = function () {
162
+ module.blur();
163
+
164
+ return settings.onHidden.apply($container, arguments);
165
+ };
166
+ if ($input.length === 0) {
167
+ // no input, $container has to handle focus/blur
168
+ $container.attr('tabindex', '0');
169
+ onVisible = function () {
170
+ module.refreshTooltips();
171
+ module.focus();
172
+
173
+ return settings.onVisible.apply($container, arguments);
174
+ };
175
+ }
176
+ var onShow = function () {
177
+ // reset the focus date onShow
178
+ module.set.focusDate(module.get.date());
179
+ module.set.mode(module.get.validatedMode(settings.startMode));
180
+
181
+ return settings.onShow.apply($container, arguments);
182
+ };
183
+ var on = module.setting('on');
184
+ var options = $.extend({}, settings.popupOptions, {
185
+ popup: $container,
186
+ movePopup: !settings.context,
187
+ on: on,
188
+ hoverable: on === 'hover',
189
+ closable: on === 'click',
190
+ onShow: onShow,
191
+ onVisible: onVisible,
192
+ onHide: settings.onHide,
193
+ onHidden: onHidden,
194
+ });
195
+ module.popup(options);
196
+ },
197
+ inline: function () {
198
+ if ($activator.length > 0 && !settings.inline) {
199
+ return;
200
+ }
201
+ settings.inline = true;
202
+ $container = $('<div/>').addClass(className.calendar).appendTo($module);
203
+ if ($input.length === 0) {
204
+ $container.attr('tabindex', '0');
205
+ }
206
+ },
207
+ input: function () {
208
+ if (settings.touchReadonly && $input.length > 0 && isTouch) {
209
+ $input.prop('readonly', true);
210
+ }
211
+ module.check.disabled();
212
+ },
213
+ date: function () {
214
+ var date;
215
+ if (settings.initialDate) {
216
+ date = parser.date(settings.initialDate, settings);
217
+ } else if ($module.data(metadata.date) !== undefined) {
218
+ date = parser.date($module.data(metadata.date), settings);
219
+ } else if ($input.length > 0) {
220
+ date = parser.date($input.val(), settings);
221
+ }
222
+ module.set.date(date, settings.formatInput, false);
223
+ module.set.mode(module.get.mode(), false);
224
+ },
225
+ },
226
+
227
+ trigger: {
228
+ change: function () {
229
+ var
230
+ inputElement = $input[0]
231
+ ;
232
+ if (inputElement) {
233
+ var events = document.createEvent('HTMLEvents');
234
+ module.verbose('Triggering native change event');
235
+ events.initEvent('change', true, false);
236
+ inputElement.dispatchEvent(events);
237
+ }
238
+ },
239
+ },
240
+
241
+ create: {
242
+ calendar: function () {
243
+ var
244
+ i,
245
+ r,
246
+ c,
247
+ p,
248
+ row,
249
+ cell,
250
+ pageGrid
251
+ ;
252
+
253
+ var
254
+ mode = module.get.mode(),
255
+ today = new Date(),
256
+ date = module.get.date(),
257
+ focusDate = module.get.focusDate(),
258
+ display = module.helper.dateInRange(focusDate || date || parser.date(settings.initialDate, settings) || today)
259
+ ;
260
+
261
+ if (!focusDate) {
262
+ focusDate = display;
263
+ module.set.focusDate(focusDate, false, false);
264
+ }
265
+
266
+ var
267
+ isYear = mode === 'year',
268
+ isMonth = mode === 'month',
269
+ isDay = mode === 'day',
270
+ isHour = mode === 'hour',
271
+ isMinute = mode === 'minute',
272
+ isTimeOnly = settings.type === 'time'
273
+ ;
274
+
275
+ var multiMonth = Math.max(settings.multiMonth, 1);
276
+ var monthOffset = !isDay ? 0 : module.get.monthOffset();
277
+
278
+ var
279
+ minute = display.getMinutes(),
280
+ hour = display.getHours(),
281
+ day = display.getDate(),
282
+ startMonth = display.getMonth() + monthOffset,
283
+ year = display.getFullYear()
284
+ ;
285
+
286
+ var columns = isDay
287
+ ? (settings.showWeekNumbers ? 8 : 7)
288
+ : (isHour ? 4 : timeGap.column);
289
+ var rows = isDay || isHour ? 6 : timeGap.row;
290
+ var pages = isDay ? multiMonth : 1;
291
+
292
+ var container = $container;
293
+ var tooltipPosition = container.hasClass('left') ? 'right center' : 'left center';
294
+ container.empty();
295
+ if (pages > 1) {
296
+ pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
297
+ }
298
+
299
+ for (p = 0; p < pages; p++) {
300
+ if (pages > 1) {
301
+ var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
302
+ container = pageColumn;
303
+ }
304
+
305
+ var month = startMonth + p;
306
+ var firstMonthDayColumn = (new Date(year, month, 1).getDay() - (settings.firstDayOfWeek % 7) + 7) % 7;
307
+ if (!settings.constantHeight && isDay) {
308
+ var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
309
+ rows = Math.ceil(requiredCells / 7);
310
+ }
311
+
312
+ var
313
+ yearChange = isYear ? 10 : (isMonth ? 1 : 0),
314
+ monthChange = isDay ? 1 : 0,
315
+ dayChange = isHour || isMinute ? 1 : 0,
316
+ prevNextDay = isHour || isMinute ? day : 1,
317
+ prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour),
318
+ nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour),
319
+ prevLast = isYear
320
+ ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0)
321
+ : (isMonth
322
+ ? new Date(year, 0, 0)
323
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
324
+ ? new Date(year, month, 0)
325
+ : new Date(year, month, day, -1))),
326
+ nextFirst = isYear
327
+ ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1)
328
+ : (isMonth
329
+ ? new Date(year + 1, 0, 1)
330
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
331
+ ? new Date(year, month + 1, 1)
332
+ : new Date(year, month, day + 1)))
333
+ ;
334
+
335
+ var tempMode = mode;
336
+ if (isDay && settings.showWeekNumbers) {
337
+ tempMode += ' andweek';
338
+ }
339
+ var table = $('<table/>').addClass(className.table).addClass(tempMode).addClass(numberText[columns] + ' column')
340
+ .appendTo(container);
341
+ if (isInverted) {
342
+ table.addClass(className.inverted);
343
+ }
344
+ var textColumns = columns;
345
+ // no header for time-only mode
346
+ if (!isTimeOnly) {
347
+ var thead = $('<thead/>').appendTo(table);
348
+
349
+ row = $('<tr/>').appendTo(thead);
350
+ cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
351
+
352
+ var headerDate = isYear || isMonth
353
+ ? new Date(year, 0, 1)
354
+ : (isDay
355
+ ? new Date(year, month, 1)
356
+ : new Date(year, month, day, hour, minute));
357
+ var headerText = $('<span/>').addClass(className.link).appendTo(cell);
358
+ headerText.text(module.helper.dateFormat(formatter[mode + 'Header'], headerDate));
359
+ var newMode = isMonth
360
+ ? (settings.disableYear ? 'day' : 'year')
361
+ : (isDay
362
+ ? (settings.disableMonth ? 'year' : 'month') // eslint-disable-line unicorn/no-nested-ternary
363
+ : 'day');
364
+ headerText.data(metadata.mode, newMode);
365
+
366
+ if (p === 0) {
367
+ var prev = $('<span/>').addClass(className.prev).appendTo(cell);
368
+ prev.data(metadata.focusDate, prevDate);
369
+ prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
370
+ $('<i/>').addClass(className.prevIcon).appendTo(prev);
371
+ }
372
+
373
+ if (p === pages - 1) {
374
+ var next = $('<span/>').addClass(className.next).appendTo(cell);
375
+ next.data(metadata.focusDate, nextDate);
376
+ next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
377
+ $('<i/>').addClass(className.nextIcon).appendTo(next);
378
+ }
379
+ if (isDay) {
380
+ row = $('<tr/>').appendTo(thead);
381
+ if (settings.showWeekNumbers) {
382
+ cell = $('<th/>').appendTo(row);
383
+ cell.text(settings.text.weekNo);
384
+ cell.addClass(className.weekCell);
385
+ textColumns--;
386
+ }
387
+ for (i = 0; i < textColumns; i++) {
388
+ cell = $('<th/>').appendTo(row);
389
+ cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
390
+ }
391
+ }
392
+ }
393
+
394
+ var tbody = $('<tbody/>').appendTo(table);
395
+ i = isYear
396
+ ? Math.ceil(year / 10) * 10 - 9
397
+ : (isDay ? 1 - firstMonthDayColumn : 0);
398
+ for (r = 0; r < rows; r++) {
399
+ row = $('<tr/>').appendTo(tbody);
400
+ if (isDay && settings.showWeekNumbers) {
401
+ cell = $('<th/>').appendTo(row);
402
+ cell.text(module.get.weekOfYear(year, month, i + 1 - settings.firstDayOfWeek));
403
+ cell.addClass(className.weekCell);
404
+ }
405
+ for (c = 0; c < textColumns; c++, i++) {
406
+ var cellDate = isYear
407
+ ? new Date(i, month, 1, hour, minute)
408
+ : (isMonth
409
+ ? new Date(year, i, 1, hour, minute)
410
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
411
+ ? new Date(year, month, i, hour, minute)
412
+ : (isHour
413
+ ? new Date(year, month, day, i)
414
+ : new Date(year, month, day, hour, i * settings.minTimeGap))));
415
+ var cellText = isYear
416
+ ? i
417
+ : (isMonth
418
+ ? settings.text.monthsShort[i]
419
+ : (isDay // eslint-disable-line unicorn/no-nested-ternary
420
+ ? cellDate.getDate()
421
+ : module.helper.dateFormat(formatter.cellTime, cellDate)));
422
+ cell = $('<td/>').addClass(className.cell).appendTo(row);
423
+ cell.text(cellText);
424
+ cell.data(metadata.date, cellDate);
425
+ var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
426
+ var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode);
427
+ var eventDate;
428
+ if (disabled) {
429
+ var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates);
430
+ if (disabledDate !== null && disabledDate[metadata.message]) {
431
+ cell.attr('data-tooltip', disabledDate[metadata.message]);
432
+ cell.attr('data-position', disabledDate[metadata.position] || tooltipPosition);
433
+ if (disabledDate[metadata.inverted] || (isInverted && disabledDate[metadata.inverted] === undefined)) {
434
+ cell.attr('data-inverted', '');
435
+ }
436
+ if (disabledDate[metadata.variation]) {
437
+ cell.attr('data-variation', disabledDate[metadata.variation]);
438
+ }
439
+ }
440
+ if (mode === 'hour') {
441
+ var disabledHour = module.helper.findHourAsObject(cellDate, mode, settings.disabledHours);
442
+ if (disabledHour !== null && disabledHour[metadata.message]) {
443
+ cell.attr('data-tooltip', disabledHour[metadata.message]);
444
+ cell.attr('data-position', disabledHour[metadata.position] || tooltipPosition);
445
+ if (disabledHour[metadata.inverted] || (isInverted && disabledHour[metadata.inverted] === undefined)) {
446
+ cell.attr('data-inverted', '');
447
+ }
448
+ if (disabledHour[metadata.variation]) {
449
+ cell.attr('data-variation', disabledHour[metadata.variation]);
450
+ }
451
+ }
452
+ }
453
+ } else {
454
+ eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates);
455
+ if (eventDate !== null) {
456
+ cell.addClass(eventDate[metadata.class] || settings.eventClass);
457
+ if (eventDate[metadata.message]) {
458
+ cell.attr('data-tooltip', eventDate[metadata.message]);
459
+ cell.attr('data-position', eventDate[metadata.position] || tooltipPosition);
460
+ if (eventDate[metadata.inverted] || (isInverted && eventDate[metadata.inverted] === undefined)) {
461
+ cell.attr('data-inverted', '');
462
+ }
463
+ if (eventDate[metadata.variation]) {
464
+ cell.attr('data-variation', eventDate[metadata.variation]);
465
+ }
466
+ }
467
+ }
468
+ }
469
+ var active = module.helper.dateEqual(cellDate, date, mode);
470
+ var isToday = module.helper.dateEqual(cellDate, today, mode);
471
+ cell.toggleClass(className.adjacentCell, adjacent && !eventDate);
472
+ cell.toggleClass(className.disabledCell, disabled);
473
+ cell.toggleClass(className.activeCell, active && !(adjacent && disabled));
474
+ if (!isHour && !isMinute) {
475
+ cell.toggleClass(className.todayCell, !adjacent && isToday);
476
+ }
477
+
478
+ // Allow for external modifications of each cell
479
+ var cellOptions = {
480
+ mode: mode,
481
+ adjacent: adjacent,
482
+ disabled: disabled,
483
+ active: active,
484
+ today: isToday,
485
+ };
486
+ formatter.cell(cell, cellDate, cellOptions);
487
+
488
+ if (module.helper.dateEqual(cellDate, focusDate, mode)) {
489
+ // ensure that the focus date is exactly equal to the cell date
490
+ // so that, if selected, the correct value is set
491
+ module.set.focusDate(cellDate, false, false);
492
+ }
493
+ }
494
+ }
495
+
496
+ if (settings.today) {
497
+ var todayRow = $('<tr/>').appendTo(tbody);
498
+ var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
499
+ todayButton.text(formatter.today(settings));
500
+ todayButton.data(metadata.date, today);
501
+ }
502
+
503
+ module.update.focus(false, table);
504
+
505
+ if (settings.inline) {
506
+ module.refreshTooltips();
507
+ }
508
+ }
509
+ },
510
+ },
511
+
512
+ update: {
513
+ focus: function (updateRange, container) {
514
+ container = container || $container;
515
+ var mode = module.get.mode();
516
+ var date = module.get.date();
517
+ var focusDate = module.get.focusDate();
518
+ var startDate = module.get.startDate();
519
+ var endDate = module.get.endDate();
520
+ var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
521
+
522
+ container.find('td').each(function () {
523
+ var $cell = $(this);
524
+ var cellDate = $cell.data(metadata.date);
525
+ if (!cellDate) {
526
+ return;
527
+ }
528
+ var disabled = $cell.hasClass(className.disabledCell);
529
+ var active = $cell.hasClass(className.activeCell);
530
+ var adjacent = $cell.hasClass(className.adjacentCell);
531
+ var focused = module.helper.dateEqual(cellDate, focusDate, mode);
532
+ var inRange = !rangeDate
533
+ ? false
534
+ : (!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate))
535
+ || (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate));
536
+ $cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled);
537
+
538
+ if (module.helper.isTodayButton($cell)) {
539
+ return;
540
+ }
541
+ $cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
542
+ });
543
+ },
544
+ },
545
+
546
+ refresh: function () {
547
+ module.create.calendar();
548
+ },
549
+
550
+ refreshTooltips: function () {
551
+ var winWidth = $(window).width();
552
+ $container.find('td[data-position]').each(function () {
553
+ var $cell = $(this);
554
+ var tooltipWidth = window.getComputedStyle($cell[0], '::after').width.replace(/[^\d.]/g, '');
555
+ var tooltipPosition = $cell.attr('data-position');
556
+ // use a fallback width of 250 (calendar width) for IE/Edge (which return "auto")
557
+ var calcPosition = (winWidth - $cell.width() - (parseInt(tooltipWidth, 10) || 250)) > $cell.offset().left ? 'right' : 'left';
558
+ if (tooltipPosition.indexOf(calcPosition) === -1) {
559
+ $cell.attr('data-position', tooltipPosition.replace(/(left|right)/, calcPosition));
560
+ }
561
+ });
562
+ },
563
+
564
+ bind: {
565
+ events: function () {
566
+ module.debug('Binding events');
567
+ $container.on('mousedown' + eventNamespace, module.event.mousedown);
568
+ $container.on('touchstart' + eventNamespace, module.event.mousedown);
569
+ $container.on('mouseup' + eventNamespace, module.event.mouseup);
570
+ $container.on('touchend' + eventNamespace, module.event.mouseup);
571
+ $container.on('mouseover' + eventNamespace, module.event.mouseover);
572
+ if ($input.length > 0) {
573
+ $input.on('input' + eventNamespace, module.event.inputChange);
574
+ $input.on('focus' + eventNamespace, module.event.inputFocus);
575
+ $input.on('blur' + eventNamespace, module.event.inputBlur);
576
+ $input.on('keydown' + eventNamespace, module.event.keydown);
577
+ } else {
578
+ $container.on('keydown' + eventNamespace, module.event.keydown);
579
+ }
580
+ },
581
+ },
582
+
583
+ unbind: {
584
+ events: function () {
585
+ module.debug('Unbinding events');
586
+ $container.off(eventNamespace);
587
+ if ($input.length > 0) {
588
+ $input.off(eventNamespace);
589
+ }
590
+ },
591
+ },
592
+
593
+ event: {
594
+ mouseover: function (event) {
595
+ var target = $(event.target);
596
+ var date = target.data(metadata.date);
597
+ var mousedown = event.buttons === 1;
598
+ if (date) {
599
+ module.set.focusDate(date, false, true, mousedown);
600
+ }
601
+ },
602
+ mousedown: function (event) {
603
+ if ($input.length > 0) {
604
+ // prevent the mousedown on the calendar causing the input to lose focus
605
+ event.preventDefault();
606
+ }
607
+ isTouchDown = event.type.indexOf('touch') >= 0;
608
+ var target = $(event.target);
609
+ var date = target.data(metadata.date);
610
+ if (date) {
611
+ module.set.focusDate(date, false, true, true);
612
+ }
613
+ },
614
+ mouseup: function (event) {
615
+ // ensure input has focus so that it receives keydown events for calendar navigation
616
+ module.focus();
617
+ event.preventDefault();
618
+ event.stopPropagation();
619
+ isTouchDown = false;
620
+ var target = $(event.target);
621
+ if (target.hasClass('disabled')) {
622
+ return;
623
+ }
624
+ var parent = target.parent();
625
+ if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
626
+ // clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
627
+ target = parent;
628
+ }
629
+ var date = target.data(metadata.date);
630
+ var focusDate = target.data(metadata.focusDate);
631
+ var mode = target.data(metadata.mode);
632
+ if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) {
633
+ var forceSet = target.hasClass(className.today);
634
+ module.selectDate(date, forceSet);
635
+ } else if (focusDate) {
636
+ module.set.focusDate(focusDate);
637
+ } else if (mode) {
638
+ module.set.mode(mode);
639
+ }
640
+ },
641
+ keydown: function (event) {
642
+ var keyCode = event.which;
643
+ if (keyCode === 9) {
644
+ // tab
645
+ module.popup('hide');
646
+ }
647
+
648
+ if (module.popup('is visible')) {
649
+ var mode = module.get.mode();
650
+ switch (keyCode) {
651
+ // arrow keys
652
+ case 37:
653
+ case 38:
654
+ case 39:
655
+ case 40: {
656
+ var bigIncrement = mode === 'day'
657
+ ? 7
658
+ : (mode === 'hour'
659
+ ? 4
660
+ : (mode === 'minute' ? timeGap.column : 3)); // eslint-disable-line unicorn/no-nested-ternary
661
+ var increment = keyCode === 37
662
+ ? -1
663
+ : (keyCode === 38
664
+ ? -bigIncrement
665
+ : (keyCode === 39 ? 1 : bigIncrement)); // eslint-disable-line unicorn/no-nested-ternary
666
+ increment *= mode === 'minute' ? settings.minTimeGap : 1;
667
+ var focusDate = module.get.focusDate() || module.get.date() || new Date();
668
+ var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
669
+ var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
670
+ var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
671
+ var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
672
+ var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
673
+ var newFocusDate = new Date(year, month, day, hour, minute);
674
+ if (settings.type === 'time') {
675
+ newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
676
+ }
677
+ if (module.helper.isDateInRange(newFocusDate, mode)) {
678
+ module.set.focusDate(newFocusDate);
679
+ }
680
+
681
+ break;
682
+ }
683
+ // enter key
684
+ case 13: {
685
+ var date = module.get.focusDate();
686
+ if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) {
687
+ if (settings.onSelect.call(element, date, module.get.mode()) !== false) {
688
+ module.selectDate(date);
689
+ }
690
+ }
691
+ // disable form submission:
692
+ event.preventDefault();
693
+ event.stopPropagation();
694
+
695
+ break;
696
+ }
697
+ // escape key
698
+ case 27: {
699
+ module.popup('hide');
700
+ event.stopPropagation();
701
+
702
+ break;
703
+ }
704
+ }
705
+ }
706
+
707
+ if (keyCode === 38 || keyCode === 40) {
708
+ // arrow-up || arrow-down
709
+ event.preventDefault(); // don't scroll
710
+ module.popup('show');
711
+ }
712
+ },
713
+ inputChange: function () {
714
+ var val = $input.val();
715
+ var date = parser.date(val, settings);
716
+ module.set.date(date, false);
717
+ },
718
+ inputFocus: function () {
719
+ $container.addClass(className.active);
720
+ },
721
+ inputBlur: function () {
722
+ $container.removeClass(className.active);
723
+ if (settings.formatInput) {
724
+ var date = module.get.date();
725
+ var text = module.helper.dateFormat(formatter[settings.type], date);
726
+ $input.val(text);
727
+ }
728
+ if (selectionComplete) {
729
+ module.trigger.change();
730
+ selectionComplete = false;
731
+ }
732
+ },
733
+ class: {
734
+ mutation: function (mutations) {
735
+ mutations.forEach(function (mutation) {
736
+ if (mutation.attributeName === 'class') {
737
+ module.check.disabled();
738
+ }
739
+ });
740
+ },
741
+ },
742
+ },
743
+
744
+ observeChanges: function () {
745
+ if ('MutationObserver' in window) {
746
+ classObserver = new MutationObserver(module.event.class.mutation);
747
+ module.debug('Setting up mutation observer', classObserver);
748
+ module.observe.class();
749
+ }
750
+ },
751
+
752
+ disconnect: {
753
+ classObserver: function () {
754
+ if ($input.length > 0 && classObserver) {
755
+ classObserver.disconnect();
756
+ }
757
+ },
758
+ },
759
+
760
+ observe: {
761
+ class: function () {
762
+ if ($input.length > 0 && classObserver) {
763
+ classObserver.observe($module[0], {
764
+ attributes: true,
765
+ });
766
+ }
767
+ },
768
+ },
769
+
770
+ is: {
771
+ disabled: function () {
772
+ return $module.hasClass(className.disabled);
773
+ },
774
+ },
775
+
776
+ check: {
777
+ disabled: function () {
778
+ $input.attr('tabindex', module.is.disabled() ? -1 : 0);
779
+ },
780
+ },
781
+
782
+ get: {
783
+ weekOfYear: function (weekYear, weekMonth, weekDay) {
784
+ // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
785
+ var ms1d = 24 * 3600 * 1000,
786
+ ms7d = 7 * ms1d,
787
+ DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an absolute day number
788
+ AWN = Math.floor(DC3 / 7), // an absolute week number
789
+ Wyr = new Date(AWN * ms7d).getUTCFullYear()
790
+ ;
791
+
792
+ return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
793
+ },
794
+ formattedDate: function (format, date) {
795
+ return module.helper.dateFormat(format || formatter[settings.type], date || module.get.date());
796
+ },
797
+ date: function () {
798
+ return module.helper.sanitiseDate($module.data(metadata.date)) || null;
799
+ },
800
+ inputDate: function () {
801
+ return $input.val();
802
+ },
803
+ focusDate: function () {
804
+ return $module.data(metadata.focusDate) || null;
805
+ },
806
+ startDate: function () {
807
+ var startModule = module.get.calendarModule(settings.startCalendar);
808
+
809
+ return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
810
+ },
811
+ endDate: function () {
812
+ var endModule = module.get.calendarModule(settings.endCalendar);
813
+
814
+ return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
815
+ },
816
+ minDate: function () {
817
+ return $module.data(metadata.minDate) || null;
818
+ },
819
+ maxDate: function () {
820
+ return $module.data(metadata.maxDate) || null;
821
+ },
822
+ monthOffset: function () {
823
+ return $module.data(metadata.monthOffset) || settings.monthOffset || 0;
824
+ },
825
+ mode: function () {
826
+ // only returns valid modes for the current settings
827
+ var mode = $module.data(metadata.mode) || settings.startMode;
828
+
829
+ return module.get.validatedMode(mode);
830
+ },
831
+ validatedMode: function (mode) {
832
+ var validModes = module.get.validModes();
833
+ if ($.inArray(mode, validModes) >= 0) {
834
+ return mode;
835
+ }
836
+
837
+ return settings.type === 'time'
838
+ ? 'hour'
839
+ : (settings.type === 'month'
840
+ ? 'month'
841
+ : (settings.type === 'year' ? 'year' : 'day')); // eslint-disable-line unicorn/no-nested-ternary
842
+ },
843
+ type: function () {
844
+ return $module.data(metadata.type) || settings.type;
845
+ },
846
+ validModes: function () {
847
+ var validModes = [];
848
+ if (settings.type !== 'time') {
849
+ if (!settings.disableYear || settings.type === 'year') {
850
+ validModes.push('year');
851
+ }
852
+ if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
853
+ validModes.push('month');
854
+ }
855
+ if (settings.type.indexOf('date') >= 0) {
856
+ validModes.push('day');
857
+ }
858
+ }
859
+ if (settings.type.indexOf('time') >= 0) {
860
+ validModes.push('hour');
861
+ if (!settings.disableMinute) {
862
+ validModes.push('minute');
863
+ }
864
+ }
865
+
866
+ return validModes;
867
+ },
868
+ isTouch: function () {
869
+ try {
870
+ document.createEvent('TouchEvent');
871
+
872
+ return true;
873
+ } catch (e) {
874
+ return false;
875
+ }
876
+ },
877
+ calendarModule: function (selector) {
878
+ if (!selector) {
879
+ return null;
880
+ }
881
+ if (!(selector instanceof $)) {
882
+ selector = $document.find(selector).first();
883
+ }
884
+
885
+ // assume range related calendars are using the same namespace
886
+ return selector.data(moduleNamespace);
887
+ },
888
+ },
889
+
890
+ set: {
891
+ date: function (date, updateInput, fireChange) {
892
+ updateInput = updateInput !== false;
893
+ fireChange = fireChange !== false;
894
+ date = module.helper.sanitiseDate(date);
895
+ date = module.helper.dateInRange(date);
896
+
897
+ var mode = module.get.mode();
898
+ var text = module.helper.dateFormat(formatter[settings.type], date);
899
+
900
+ if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) {
901
+ return false;
902
+ }
903
+
904
+ module.set.focusDate(date);
905
+
906
+ if (settings.isDisabled(date, mode)) {
907
+ return false;
908
+ }
909
+
910
+ var endDate = module.get.endDate();
911
+ if (!!endDate && !!date && date > endDate) {
912
+ // selected date is greater than end date in range, so clear end date
913
+ module.set.endDate();
914
+ }
915
+ module.set.dataKeyValue(metadata.date, date);
916
+
917
+ if (updateInput && $input.length > 0) {
918
+ $input.val(text);
919
+ }
920
+
921
+ if (fireChange) {
922
+ settings.onChange.call(element, date, text, mode);
923
+ }
924
+ },
925
+ startDate: function (date, refreshCalendar) {
926
+ date = module.helper.sanitiseDate(date);
927
+ var startModule = module.get.calendarModule(settings.startCalendar);
928
+ if (startModule) {
929
+ startModule.set.date(date);
930
+ }
931
+ module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
932
+ },
933
+ endDate: function (date, refreshCalendar) {
934
+ date = module.helper.sanitiseDate(date);
935
+ var endModule = module.get.calendarModule(settings.endCalendar);
936
+ if (endModule) {
937
+ endModule.set.date(date);
938
+ }
939
+ module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
940
+ },
941
+ focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
942
+ date = module.helper.sanitiseDate(date);
943
+ date = module.helper.dateInRange(date);
944
+ var isDay = module.get.mode() === 'day';
945
+ var oldFocusDate = module.get.focusDate();
946
+ if (isDay && date && oldFocusDate) {
947
+ var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
948
+ var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
949
+ if (monthDelta) {
950
+ var monthOffset = module.get.monthOffset() - monthDelta;
951
+ module.set.monthOffset(monthOffset, false);
952
+ }
953
+ }
954
+ var changed = module.set.dataKeyValue(metadata.focusDate, date, !!date && refreshCalendar);
955
+ updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
956
+ focusDateUsedForRange = updateRange;
957
+ if (updateFocus) {
958
+ module.update.focus(updateRange);
959
+ }
960
+ },
961
+ minDate: function (date) {
962
+ date = module.helper.sanitiseDate(date);
963
+ if (settings.maxDate !== null && settings.maxDate <= date) {
964
+ module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
965
+ } else {
966
+ module.setting('minDate', date);
967
+ module.set.dataKeyValue(metadata.minDate, date);
968
+ }
969
+ },
970
+ maxDate: function (date) {
971
+ date = module.helper.sanitiseDate(date);
972
+ if (settings.minDate !== null && settings.minDate >= date) {
973
+ module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
974
+ } else {
975
+ module.setting('maxDate', date);
976
+ module.set.dataKeyValue(metadata.maxDate, date);
977
+ }
978
+ },
979
+ monthOffset: function (monthOffset, refreshCalendar) {
980
+ var multiMonth = Math.max(settings.multiMonth, 1);
981
+ monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
982
+ module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
983
+ },
984
+ mode: function (mode, refreshCalendar) {
985
+ module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
986
+ },
987
+ dataKeyValue: function (key, value, refreshCalendar) {
988
+ var oldValue = $module.data(key);
989
+ var equal = oldValue === value || (oldValue <= value && oldValue >= value); // equality test for dates and string objects
990
+ if (value) {
991
+ $module.data(key, value);
992
+ } else {
993
+ $module.removeData(key);
994
+ }
995
+ refreshCalendar = refreshCalendar !== false && !equal;
996
+ if (refreshCalendar) {
997
+ module.refresh();
998
+ }
999
+
1000
+ return !equal;
1001
+ },
1002
+ },
1003
+
1004
+ selectDate: function (date, forceSet) {
1005
+ module.verbose('New date selection', date);
1006
+ var mode = module.get.mode();
1007
+ var complete = forceSet || mode === 'minute'
1008
+ || (settings.disableMinute && mode === 'hour')
1009
+ || (settings.type === 'date' && mode === 'day')
1010
+ || (settings.type === 'month' && mode === 'month')
1011
+ || (settings.type === 'year' && mode === 'year');
1012
+ if (complete) {
1013
+ var canceled = module.set.date(date) === false;
1014
+ if (!canceled) {
1015
+ selectionComplete = true;
1016
+ if (settings.closable) {
1017
+ module.popup('hide');
1018
+ // if this is a range calendar, focus the container or input. This will open the popup from its event listeners.
1019
+ var endModule = module.get.calendarModule(settings.endCalendar);
1020
+ if (endModule) {
1021
+ endModule.refresh();
1022
+ if (endModule.setting('on') !== 'focus') {
1023
+ endModule.popup('show');
1024
+ }
1025
+ endModule.focus();
1026
+ }
1027
+ }
1028
+ }
1029
+ } else {
1030
+ var newMode = mode === 'year'
1031
+ ? (!settings.disableMonth ? 'month' : 'day')
1032
+ : (mode === 'month'
1033
+ ? 'day'
1034
+ : (mode === 'day' ? 'hour' : 'minute')); // eslint-disable-line unicorn/no-nested-ternary
1035
+ module.set.mode(newMode);
1036
+ if (mode === 'hour' || (mode === 'day' && module.get.date())) {
1037
+ // the user has chosen enough to consider a valid date/time has been chosen
1038
+ module.set.date(date, true, false);
1039
+ } else {
1040
+ module.set.focusDate(date);
1041
+ }
1042
+ }
1043
+ },
25
1044
 
26
- $.fn.calendar = function(parameters) {
27
- var
28
- $allModules = $(this),
1045
+ changeDate: function (date) {
1046
+ module.set.date(date);
1047
+ },
29
1048
 
30
- moduleSelector = $allModules.selector || '',
1049
+ clear: function () {
1050
+ module.set.date();
1051
+ },
31
1052
 
32
- time = new Date().getTime(),
33
- performance = [],
1053
+ popup: function () {
1054
+ return $activator.popup.apply($activator, arguments);
1055
+ },
34
1056
 
35
- query = arguments[0],
36
- methodInvoked = (typeof query == 'string'),
37
- queryArguments = [].slice.call(arguments, 1),
38
- returnedValue,
39
- timeGapTable = {
40
- '5': {'row': 4, 'column': 3 },
41
- '10': {'row': 3, 'column': 2 },
42
- '15': {'row': 2, 'column': 2 },
43
- '20': {'row': 3, 'column': 1 },
44
- '30': {'row': 2, 'column': 1 }
45
- }
46
- ;
47
-
48
- $allModules
49
- .each(function () {
50
- var
51
- settings = ( $.isPlainObject(parameters) )
52
- ? $.extend(true, {}, $.fn.calendar.settings, parameters)
53
- : $.extend({}, $.fn.calendar.settings),
54
-
55
- className = settings.className,
56
- namespace = settings.namespace,
57
- selector = settings.selector,
58
- formatter = settings.formatter,
59
- parser = settings.parser,
60
- metadata = settings.metadata,
61
- timeGap = timeGapTable[settings.minTimeGap],
62
- error = settings.error,
63
-
64
- eventNamespace = '.' + namespace,
65
- moduleNamespace = 'module-' + namespace,
66
-
67
- $module = $(this),
68
- $input = $module.find(selector.input),
69
- $container = $module.find(selector.popup),
70
- $activator = $module.find(selector.activator),
71
-
72
- element = this,
73
- instance = $module.data(moduleNamespace),
74
-
75
- isTouch,
76
- isTouchDown = false,
77
- focusDateUsedForRange = false,
78
- module
79
- ;
80
-
81
- module = {
82
-
83
- initialize: function () {
84
- module.debug('Initializing calendar for', element, $module);
85
-
86
- isTouch = module.get.isTouch();
87
- module.setup.config();
88
- module.setup.popup();
89
- module.setup.inline();
90
- module.setup.input();
91
- module.setup.date();
92
- module.create.calendar();
93
-
94
- module.bind.events();
95
- module.instantiate();
96
- },
1057
+ focus: function () {
1058
+ if ($input.length > 0) {
1059
+ $input.trigger('focus');
1060
+ } else {
1061
+ $container.trigger('focus');
1062
+ }
1063
+ },
1064
+ blur: function () {
1065
+ if ($input.length > 0) {
1066
+ $input.trigger('blur');
1067
+ } else {
1068
+ $container.trigger('blur');
1069
+ }
1070
+ },
1071
+
1072
+ helper: {
1073
+ dateFormat: function (format, date) {
1074
+ if (!(date instanceof Date)) {
1075
+ return '';
1076
+ }
1077
+ if (typeof format === 'function') {
1078
+ return format.call(module, date, settings);
1079
+ }
1080
+
1081
+ var
1082
+ D = date.getDate(),
1083
+ M = date.getMonth(),
1084
+ Y = date.getFullYear(),
1085
+ d = date.getDay(),
1086
+ H = date.getHours(),
1087
+ m = date.getMinutes(),
1088
+ s = date.getSeconds(),
1089
+ w = module.get.weekOfYear(Y, M, D + 1 - settings.firstDayOfWeek),
1090
+ h = H % 12 || 12,
1091
+ a = H < 12 ? settings.text.am.toLowerCase() : settings.text.pm.toLowerCase(),
1092
+ tokens = {
1093
+ D: D,
1094
+ DD: ('0' + D).slice(-2),
1095
+ M: M + 1,
1096
+ MM: ('0' + (M + 1)).slice(-2),
1097
+ MMM: settings.text.monthsShort[M],
1098
+ MMMM: settings.text.months[M],
1099
+ Y: Y,
1100
+ YY: String(Y).slice(2),
1101
+ YYYY: Y,
1102
+ d: d,
1103
+ dd: settings.text.dayNamesShort[d].slice(0, 2),
1104
+ ddd: settings.text.dayNamesShort[d],
1105
+ dddd: settings.text.dayNames[d],
1106
+ h: h,
1107
+ hh: ('0' + h).slice(-2),
1108
+ H: H,
1109
+ HH: ('0' + H).slice(-2),
1110
+ m: m,
1111
+ mm: ('0' + m).slice(-2),
1112
+ s: s,
1113
+ ss: ('0' + s).slice(-2),
1114
+ a: a,
1115
+ A: a.toUpperCase(),
1116
+ S: ['th', 'st', 'nd', 'rd'][(D % 10) > 3 ? 0 : ((D % 100) - (D % 10) === 10 ? 0 : D % 10)],
1117
+ w: w,
1118
+ ww: ('0' + w).slice(-2),
1119
+ }
1120
+ ;
1121
+
1122
+ return format.replace(settings.regExp.token, function (match) {
1123
+ if (match in tokens) {
1124
+ return tokens[match];
1125
+ }
1126
+
1127
+ return match.slice(1, -1);
1128
+ });
1129
+ },
1130
+ isDisabled: function (date, mode) {
1131
+ return (mode === 'day' || mode === 'month' || mode === 'year' || mode === 'hour') && (((mode === 'day' && settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function (d) {
1132
+ var blocked = false;
1133
+
1134
+ if (typeof d === 'string') {
1135
+ d = module.helper.sanitiseDate(d);
1136
+ }
1137
+ if (d instanceof Date) {
1138
+ blocked = module.helper.dateEqual(date, d, mode);
1139
+ } else if (d !== null && typeof d === 'object') {
1140
+ if (d[metadata.year]) {
1141
+ if (typeof d[metadata.year] === 'number') {
1142
+ blocked = date.getFullYear() === d[metadata.year];
1143
+ } else if (Array.isArray(d[metadata.year])) {
1144
+ blocked = d[metadata.year].indexOf(date.getFullYear()) > -1;
1145
+ }
1146
+ } else if (d[metadata.month]) {
1147
+ if (typeof d[metadata.month] === 'number') {
1148
+ blocked = date.getMonth() === d[metadata.month];
1149
+ } else if (Array.isArray(d[metadata.month])) {
1150
+ blocked = d[metadata.month].indexOf(date.getMonth()) > -1;
1151
+ } else if (d[metadata.month] instanceof Date) {
1152
+ var sdate = module.helper.sanitiseDate(d[metadata.month]);
1153
+
1154
+ blocked = (date.getMonth() === sdate.getMonth()) && (date.getFullYear() === sdate.getFullYear());
1155
+ }
1156
+ } else if (d[metadata.date] && mode === 'day') {
1157
+ if (d[metadata.date] instanceof Date) {
1158
+ blocked = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1159
+ } else if (Array.isArray(d[metadata.date])) {
1160
+ blocked = d[metadata.date].some(function (idate) {
1161
+ return module.helper.dateEqual(date, idate, mode);
1162
+ });
1163
+ }
1164
+ }
1165
+ }
1166
+
1167
+ return blocked;
1168
+ })) || (mode === 'hour' && settings.disabledHours.some(function (d) {
1169
+ var blocked = false;
1170
+
1171
+ if (typeof d === 'string') {
1172
+ d = module.helper.sanitiseDate(d);
1173
+ }
1174
+ if (d instanceof Date) {
1175
+ blocked = module.helper.dateEqual(date, d, mode);
1176
+ } else if (typeof d === 'number') {
1177
+ blocked = date.getHours() === d;
1178
+ } else if (d !== null && typeof d === 'object') {
1179
+ if (d[metadata.date]) {
1180
+ if (d[metadata.date] instanceof Date) {
1181
+ blocked = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]));
1182
+ } else if (Array.isArray(d[metadata.date])) {
1183
+ blocked = d[metadata.date].some(function (idate) {
1184
+ return module.helper.dateEqual(date, idate, mode);
1185
+ });
1186
+ }
1187
+ }
1188
+
1189
+ if (d[metadata.days]) {
1190
+ if (typeof d[metadata.days] === 'number') {
1191
+ blocked = date.getDay() === d[metadata.days];
1192
+ } else if (Array.isArray(d[metadata.days])) {
1193
+ blocked = d[metadata.days].indexOf(date.getDay()) > -1;
1194
+ }
1195
+ }
1196
+
1197
+ if (d[metadata.hours]) {
1198
+ if (typeof d[metadata.hours] === 'number') {
1199
+ blocked = blocked && date.getHours() === d[metadata.hours];
1200
+ } else if (Array.isArray(d[metadata.hours])) {
1201
+ blocked = blocked && d[metadata.hours].indexOf(date.getHours()) > -1;
1202
+ }
1203
+ }
1204
+ }
1205
+
1206
+ return blocked;
1207
+ })));
1208
+ },
1209
+ isEnabled: function (date, mode) {
1210
+ if (mode === 'day') {
1211
+ return settings.enabledDates.length === 0 || settings.enabledDates.some(function (d) {
1212
+ var enabled = false;
1213
+
1214
+ if (typeof d === 'string') {
1215
+ d = module.helper.sanitiseDate(d);
1216
+ }
1217
+ if (d instanceof Date) {
1218
+ enabled = module.helper.dateEqual(date, d, mode);
1219
+ } else if (d !== null && typeof d === 'object' && d[metadata.date]) {
1220
+ enabled = module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
1221
+ }
1222
+
1223
+ return enabled;
1224
+ });
1225
+ }
1226
+
1227
+ return true;
1228
+ },
1229
+ findDayAsObject: function (date, mode, dates) {
1230
+ if (mode === 'day' || mode === 'month' || mode === 'year') {
1231
+ var d;
1232
+ for (var i = 0; i < dates.length; i++) {
1233
+ d = dates[i];
1234
+ if (typeof d === 'string') {
1235
+ d = module.helper.sanitiseDate(d);
1236
+ }
1237
+ if (d instanceof Date && module.helper.dateEqual(date, d, mode)) {
1238
+ var dateObject = {};
1239
+ dateObject[metadata.date] = d;
1240
+
1241
+ return dateObject;
1242
+ }
1243
+ if (d !== null && typeof d === 'object') {
1244
+ if (d[metadata.year]) {
1245
+ if (typeof d[metadata.year] === 'number' && date.getFullYear() === d[metadata.year]) {
1246
+ return d;
1247
+ }
1248
+ if (Array.isArray(d[metadata.year])) {
1249
+ if (d[metadata.year].indexOf(date.getFullYear()) > -1) {
1250
+ return d;
1251
+ }
1252
+ }
1253
+ } else if (d[metadata.month]) {
1254
+ if (typeof d[metadata.month] === 'number' && date.getMonth() === d[metadata.month]) {
1255
+ return d;
1256
+ }
1257
+ if (Array.isArray(d[metadata.month])) {
1258
+ if (d[metadata.month].indexOf(date.getMonth()) > -1) {
1259
+ return d;
1260
+ }
1261
+ } else if (d[metadata.month] instanceof Date) {
1262
+ var sdate = module.helper.sanitiseDate(d[metadata.month]);
1263
+ if ((date.getMonth() === sdate.getMonth()) && (date.getFullYear() === sdate.getFullYear())) {
1264
+ return d;
1265
+ }
1266
+ }
1267
+ } else if (d[metadata.date] && mode === 'day') {
1268
+ if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) {
1269
+ return d;
1270
+ }
1271
+ if (Array.isArray(d[metadata.date])) {
1272
+ if (d[metadata.date].some(function (idate) {
1273
+ return module.helper.dateEqual(date, idate, mode);
1274
+ })) {
1275
+ return d;
1276
+ }
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ return null;
1284
+ },
1285
+ findHourAsObject: function (date, mode, hours) {
1286
+ if (mode === 'hour') {
1287
+ var d;
1288
+ var hourCheck = function (date, d) {
1289
+ if (d[metadata.hours]) {
1290
+ if (typeof d[metadata.hours] === 'number' && date.getHours() === d[metadata.hours]) {
1291
+ return d;
1292
+ }
1293
+ if (Array.isArray(d[metadata.hours])) {
1294
+ if (d[metadata.hours].indexOf(date.getHours()) > -1) {
1295
+ return d;
1296
+ }
1297
+ }
1298
+ }
1299
+ };
1300
+ for (var i = 0; i < hours.length; i++) {
1301
+ d = hours[i];
1302
+ if (typeof d === 'number' && date.getHours() === d) {
1303
+ return null;
1304
+ }
1305
+ if (d !== null && typeof d === 'object') {
1306
+ if (d[metadata.days] && hourCheck(date, d)) {
1307
+ if (typeof d[metadata.days] === 'number' && date.getDay() === d[metadata.days]) {
1308
+ return d;
1309
+ }
1310
+ if (Array.isArray(d[metadata.days])) {
1311
+ if (d[metadata.days].indexOf(date.getDay()) > -1) {
1312
+ return d;
1313
+ }
1314
+ }
1315
+ } else if (d[metadata.date] && hourCheck(date, d)) {
1316
+ if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]))) {
1317
+ return d;
1318
+ }
1319
+ if (Array.isArray(d[metadata.date])) {
1320
+ if (d[metadata.date].some(function (idate) {
1321
+ return module.helper.dateEqual(date, idate, mode);
1322
+ })) {
1323
+ return d;
1324
+ }
1325
+ }
1326
+ } else if (hourCheck(date, d)) {
1327
+ return d;
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1332
+
1333
+ return null;
1334
+ },
1335
+ sanitiseDate: function (date) {
1336
+ if (!(date instanceof Date)) {
1337
+ date = parser.date('' + date, settings);
1338
+ }
1339
+ if (!date || isNaN(date.getTime())) {
1340
+ return null;
1341
+ }
1342
+
1343
+ return date;
1344
+ },
1345
+ dateDiff: function (date1, date2, mode) {
1346
+ if (!mode) {
1347
+ mode = 'day';
1348
+ }
1349
+
1350
+ var isTimeOnly = settings.type === 'time';
1351
+ var isYear = mode === 'year';
1352
+ var isYearOrMonth = isYear || mode === 'month';
1353
+ var isMinute = mode === 'minute';
1354
+ var isHourOrMinute = isMinute || mode === 'hour';
1355
+ // only care about a minute accuracy of settings.minTimeGap
1356
+ date1 = new Date(
1357
+ isTimeOnly ? 2000 : date1.getFullYear(),
1358
+ isTimeOnly ? 0 : (isYear ? 0 : date1.getMonth()),
1359
+ isTimeOnly ? 1 : (isYearOrMonth ? 1 : date1.getDate()),
1360
+ !isHourOrMinute ? 0 : date1.getHours(),
1361
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap)
1362
+ );
1363
+ date2 = new Date(
1364
+ isTimeOnly ? 2000 : date2.getFullYear(),
1365
+ isTimeOnly ? 0 : (isYear ? 0 : date2.getMonth()),
1366
+ isTimeOnly ? 1 : (isYearOrMonth ? 1 : date2.getDate()),
1367
+ !isHourOrMinute ? 0 : date2.getHours(),
1368
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap)
1369
+ );
1370
+
1371
+ return date2.getTime() - date1.getTime();
1372
+ },
1373
+ dateEqual: function (date1, date2, mode) {
1374
+ return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
1375
+ },
1376
+ isDateInRange: function (date, mode, minDate, maxDate) {
1377
+ if (!minDate && !maxDate) {
1378
+ var startDate = module.get.startDate();
1379
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1380
+ maxDate = settings.maxDate;
1381
+ }
1382
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1383
+
1384
+ return !(!date
1385
+ || (minDate && module.helper.dateDiff(date, minDate, mode) > 0)
1386
+ || (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
1387
+ },
1388
+ dateInRange: function (date, minDate, maxDate) {
1389
+ if (!minDate && !maxDate) {
1390
+ var startDate = module.get.startDate();
1391
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1392
+ maxDate = settings.maxDate;
1393
+ }
1394
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1395
+ var isTimeOnly = settings.type === 'time';
1396
+
1397
+ return !date
1398
+ ? date
1399
+ : (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0
1400
+ ? (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) // eslint-disable-line unicorn/no-nested-ternary
1401
+ : (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0 // eslint-disable-line unicorn/no-nested-ternary
1402
+ ? (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate)
1403
+ : date));
1404
+ },
1405
+ mergeDateTime: function (date, time) {
1406
+ return !date || !time
1407
+ ? time
1408
+ : new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
1409
+ },
1410
+ isTodayButton: function (element) {
1411
+ return element.text() === settings.text.today;
1412
+ },
1413
+ },
1414
+
1415
+ setting: function (name, value) {
1416
+ module.debug('Changing setting', name, value);
1417
+ if ($.isPlainObject(name)) {
1418
+ $.extend(true, settings, name);
1419
+ } else if (value !== undefined) {
1420
+ if ($.isPlainObject(settings[name])) {
1421
+ $.extend(true, settings[name], value);
1422
+ } else {
1423
+ settings[name] = value;
1424
+ }
1425
+ } else {
1426
+ return settings[name];
1427
+ }
1428
+ },
1429
+ internal: function (name, value) {
1430
+ if ($.isPlainObject(name)) {
1431
+ $.extend(true, module, name);
1432
+ } else if (value !== undefined) {
1433
+ module[name] = value;
1434
+ } else {
1435
+ return module[name];
1436
+ }
1437
+ },
1438
+ debug: function () {
1439
+ if (!settings.silent && settings.debug) {
1440
+ if (settings.performance) {
1441
+ module.performance.log(arguments);
1442
+ } else {
1443
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1444
+ module.debug.apply(console, arguments);
1445
+ }
1446
+ }
1447
+ },
1448
+ verbose: function () {
1449
+ if (!settings.silent && settings.verbose && settings.debug) {
1450
+ if (settings.performance) {
1451
+ module.performance.log(arguments);
1452
+ } else {
1453
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1454
+ module.verbose.apply(console, arguments);
1455
+ }
1456
+ }
1457
+ },
1458
+ error: function () {
1459
+ if (!settings.silent) {
1460
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1461
+ module.error.apply(console, arguments);
1462
+ }
1463
+ },
1464
+ performance: {
1465
+ log: function (message) {
1466
+ var
1467
+ currentTime,
1468
+ executionTime,
1469
+ previousTime
1470
+ ;
1471
+ if (settings.performance) {
1472
+ currentTime = Date.now();
1473
+ previousTime = time || currentTime;
1474
+ executionTime = currentTime - previousTime;
1475
+ time = currentTime;
1476
+ performance.push({
1477
+ Name: message[0],
1478
+ Arguments: [].slice.call(message, 1) || '',
1479
+ Element: element,
1480
+ 'Execution Time': executionTime,
1481
+ });
1482
+ }
1483
+ clearTimeout(module.performance.timer);
1484
+ module.performance.timer = setTimeout(module.performance.display, 500);
1485
+ },
1486
+ display: function () {
1487
+ var
1488
+ title = settings.name + ':',
1489
+ totalTime = 0
1490
+ ;
1491
+ time = false;
1492
+ clearTimeout(module.performance.timer);
1493
+ $.each(performance, function (index, data) {
1494
+ totalTime += data['Execution Time'];
1495
+ });
1496
+ title += ' ' + totalTime + 'ms';
1497
+ if (moduleSelector) {
1498
+ title += ' \'' + moduleSelector + '\'';
1499
+ }
1500
+ if (performance.length > 0) {
1501
+ console.groupCollapsed(title);
1502
+ if (console.table) {
1503
+ console.table(performance);
1504
+ } else {
1505
+ $.each(performance, function (index, data) {
1506
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
1507
+ });
1508
+ }
1509
+ console.groupEnd();
1510
+ }
1511
+ performance = [];
1512
+ },
1513
+ },
1514
+ invoke: function (query, passedArguments, context) {
1515
+ var
1516
+ object = instance,
1517
+ maxDepth,
1518
+ found,
1519
+ response
1520
+ ;
1521
+ passedArguments = passedArguments || queryArguments;
1522
+ context = context || element;
1523
+ if (typeof query === 'string' && object !== undefined) {
1524
+ query = query.split(/[ .]/);
1525
+ maxDepth = query.length - 1;
1526
+ $.each(query, function (depth, value) {
1527
+ var camelCaseValue = depth !== maxDepth
1528
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1529
+ : query
1530
+ ;
1531
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
1532
+ object = object[camelCaseValue];
1533
+ } else if (object[camelCaseValue] !== undefined) {
1534
+ found = object[camelCaseValue];
1535
+
1536
+ return false;
1537
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
1538
+ object = object[value];
1539
+ } else if (object[value] !== undefined) {
1540
+ found = object[value];
1541
+
1542
+ return false;
1543
+ } else {
1544
+ module.error(error.method, query);
1545
+
1546
+ return false;
1547
+ }
1548
+ });
1549
+ }
1550
+ if (isFunction(found)) {
1551
+ response = found.apply(context, passedArguments);
1552
+ } else if (found !== undefined) {
1553
+ response = found;
1554
+ }
1555
+ if (Array.isArray(returnedValue)) {
1556
+ returnedValue.push(response);
1557
+ } else if (returnedValue !== undefined) {
1558
+ returnedValue = [returnedValue, response];
1559
+ } else if (response !== undefined) {
1560
+ returnedValue = response;
1561
+ }
1562
+
1563
+ return found;
1564
+ },
1565
+ };
97
1566
 
98
- instantiate: function () {
99
- module.verbose('Storing instance of calendar');
100
- instance = module;
101
- $module.data(moduleNamespace, instance);
1567
+ if (methodInvoked) {
1568
+ if (instance === undefined) {
1569
+ module.initialize();
1570
+ }
1571
+ module.invoke(query);
1572
+ } else {
1573
+ if (instance !== undefined) {
1574
+ instance.invoke('destroy');
1575
+ }
1576
+ module.initialize();
1577
+ }
1578
+ });
1579
+
1580
+ return returnedValue !== undefined
1581
+ ? returnedValue
1582
+ : this;
1583
+ };
1584
+
1585
+ $.fn.calendar.settings = {
1586
+
1587
+ name: 'Calendar',
1588
+ namespace: 'calendar',
1589
+
1590
+ silent: false,
1591
+ debug: false,
1592
+ verbose: false,
1593
+ performance: true,
1594
+
1595
+ context: false,
1596
+
1597
+ type: 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
1598
+ firstDayOfWeek: 0, // day for first day column (0 = Sunday)
1599
+ constantHeight: true, // add rows to shorter months to keep day calendar height consistent (6 rows)
1600
+ today: false, // show a 'today/now' button at the bottom of the calendar
1601
+ closable: true, // close the popup after selecting a date/time
1602
+ monthFirst: true, // month before day when parsing date from text
1603
+ touchReadonly: true, // set input to readonly on touch devices
1604
+ inline: false, // create the calendar inline instead of inside a popup
1605
+ on: null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
1606
+ initialDate: null, // date to display initially when no date is selected (null = now)
1607
+ startMode: false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
1608
+ minDate: null, // minimum date/time that can be selected, dates/times before are disabled
1609
+ maxDate: null, // maximum date/time that can be selected, dates/times after are disabled
1610
+ disableYear: false, // disable year selection mode
1611
+ disableMonth: false, // disable month selection mode
1612
+ disableMinute: false, // disable minute selection mode
1613
+ formatInput: true, // format the input text upon input blur and module creation
1614
+ startCalendar: null, // jquery object or selector for another calendar that represents the start date of a date range
1615
+ endCalendar: null, // jquery object or selector for another calendar that represents the end date of a date range
1616
+ multiMonth: 1, // show multiple months when in 'day' mode
1617
+ monthOffset: 0, // position current month by offset when multimonth > 1
1618
+ minTimeGap: 5,
1619
+ showWeekNumbers: false, // show Number of Week at the very first column of a dayView
1620
+ disabledHours: [], // specific hour(s) which won't be selectable and contain additional information.
1621
+ disabledDates: [], // specific day(s) which won't be selectable and contain additional information.
1622
+ disabledDaysOfWeek: [], // day(s) which won't be selectable(s) (0 = Sunday)
1623
+ enabledDates: [], // specific day(s) which will be selectable, all other days will be disabled
1624
+ eventDates: [], // specific day(s) which will be shown in a different color and using tooltips
1625
+ centuryBreak: 60, // starting short year until 99 where it will be assumed to belong to the last century
1626
+ currentCentury: 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1)
1627
+ selectAdjacentDays: false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable.
1628
+ // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1629
+ popupOptions: {
1630
+ position: 'bottom left',
1631
+ lastResort: 'bottom left',
1632
+ prefer: 'opposite',
1633
+ observeChanges: false,
1634
+ hideOnScroll: false,
102
1635
  },
103
1636
 
104
- destroy: function () {
105
- module.verbose('Destroying previous calendar for', element);
106
- $module.removeData(moduleNamespace);
107
- module.unbind.events();
1637
+ text: {
1638
+ days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1639
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
1640
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
1641
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1642
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1643
+ today: 'Today',
1644
+ now: 'Now',
1645
+ am: 'AM',
1646
+ pm: 'PM',
1647
+ weekNo: 'Week',
108
1648
  },
109
1649
 
110
- setup: {
111
- config: function () {
112
- if (module.get.minDate() !== null) {
113
- module.set.minDate($module.data(metadata.minDate));
114
- }
115
- if (module.get.maxDate() !== null) {
116
- module.set.maxDate($module.data(metadata.maxDate));
117
- }
118
- module.setting('type', module.get.type());
119
- },
120
- popup: function () {
121
- if (settings.inline) {
122
- return;
123
- }
124
- if (!$activator.length) {
125
- $activator = $module.children().first();
126
- if (!$activator.length) {
127
- return;
128
- }
129
- }
130
- if ($.fn.popup === undefined) {
131
- module.error(error.popup);
132
- return;
133
- }
134
- if (!$container.length) {
135
- //prepend the popup element to the activator's parent so that it has less chance of messing with
136
- //the styling (eg input action button needs to be the last child to have correct border radius)
137
- var $activatorParent = $activator.parent(),
138
- domPositionFunction = $activatorParent.closest(selector.append).length !== 0 ? 'appendTo' : 'prependTo';
139
- $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent);
140
- }
141
- $container.addClass(className.calendar);
142
- var onVisible = settings.onVisible;
143
- var onHidden = settings.onHidden;
144
- if (!$input.length) {
145
- //no input, $container has to handle focus/blur
146
- $container.attr('tabindex', '0');
147
- onVisible = function () {
148
- module.focus();
149
- return settings.onVisible.apply($container, arguments);
150
- };
151
- onHidden = function () {
152
- module.blur();
153
- return settings.onHidden.apply($container, arguments);
154
- };
155
- }
156
- var onShow = function () {
157
- //reset the focus date onShow
158
- module.set.focusDate(module.get.date());
159
- module.set.mode(settings.startMode);
160
- return settings.onShow.apply($container, arguments);
161
- };
162
- var on = settings.on || ($input.length ? 'focus' : 'click');
163
- var options = $.extend({}, settings.popupOptions, {
164
- popup: $container,
165
- on: on,
166
- hoverable: on === 'hover',
167
- onShow: onShow,
168
- onVisible: onVisible,
169
- onHide: settings.onHide,
170
- onHidden: onHidden
171
- });
172
- module.popup(options);
173
- },
174
- inline: function () {
175
- if ($activator.length && !settings.inline) {
176
- return;
177
- }
178
- $container = $('<div/>').addClass(className.calendar).appendTo($module);
179
- if (!$input.length) {
180
- $container.attr('tabindex', '0');
181
- }
182
- },
183
- input: function () {
184
- if (settings.touchReadonly && $input.length && isTouch) {
185
- $input.prop('readonly', true);
186
- }
187
- },
188
- date: function () {
189
- var date;
190
- if (settings.initialDate) {
191
- date = parser.date(settings.initialDate, settings);
192
- } else if ($module.data(metadata.date) !== undefined) {
193
- date = parser.date($module.data(metadata.date), settings);
194
- } else if ($input.length) {
195
- date = parser.date($input.val(), settings);
196
- }
197
- module.set.date(date, settings.formatInput, false);
198
- }
1650
+ formatter: {
1651
+ yearHeader: function (date, settings) {
1652
+ var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1653
+
1654
+ return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1655
+ },
1656
+ monthHeader: 'YYYY',
1657
+ dayHeader: 'MMMM YYYY',
1658
+ hourHeader: 'MMMM D, YYYY',
1659
+ minuteHeader: 'MMMM D, YYYY',
1660
+ dayColumnHeader: function (day, settings) {
1661
+ return settings.text.days[day];
1662
+ },
1663
+ datetime: 'MMMM D, YYYY h:mm A',
1664
+ date: 'MMMM D, YYYY',
1665
+ time: 'h:mm A',
1666
+ cellTime: 'h:mm A',
1667
+ month: 'MMMM YYYY',
1668
+ year: 'YYYY',
1669
+ today: function (settings) {
1670
+ return settings.type === 'date' ? settings.text.today : settings.text.now;
1671
+ },
1672
+ cell: function (cell, date, cellOptions) {},
199
1673
  },
200
1674
 
201
- create: {
202
- calendar: function () {
203
- var i, r, c, p, row, cell, pageGrid;
1675
+ parser: {
1676
+ date: function (text, settings) {
1677
+ if (text instanceof Date) {
1678
+ return text;
1679
+ }
1680
+ if (!text) {
1681
+ return null;
1682
+ }
1683
+ text = String(text).trim().replace(/([./:-])\s+/g, '$1').replace(/\s+([./:-])/g, '$1')
1684
+ .replace(/\s+/g, ' ');
1685
+ if (text.length === 0) {
1686
+ return null;
1687
+ }
1688
+ if (/^\d{4}(?:[./-]\d{1,2}){2}$/.test(text)) {
1689
+ text = text.replace(/[./-]/g, '/') + ' 00:00:00';
1690
+ }
1691
+ // Reverse date and month in some cases
1692
+ text = settings.monthFirst || !/^\d{1,2}[./-]/.test(text) ? text : text.replace(/[./-]/g, '/').replace(/(\d+)\/(\d+)/, '$2/$1');
1693
+ var textDate = new Date(text);
1694
+ var numberOnly = text.match(/^\d+$/) !== null;
1695
+ if (!numberOnly && !isNaN(textDate.getDate())) {
1696
+ return textDate;
1697
+ }
1698
+ text = text.toLowerCase();
204
1699
 
205
- var mode = module.get.mode();
206
- var today = new Date();
207
- var date = module.get.date();
208
- var focusDate = module.get.focusDate();
209
- var display = focusDate || date || settings.initialDate || today;
210
- display = module.helper.dateInRange(display);
1700
+ var
1701
+ i,
1702
+ j,
1703
+ k
1704
+ ;
1705
+ var
1706
+ minute = -1,
1707
+ hour = -1,
1708
+ day = -1,
1709
+ month = -1,
1710
+ year = -1
1711
+ ;
1712
+ var isAm;
211
1713
 
212
- if (!focusDate) {
213
- focusDate = display;
214
- module.set.focusDate(focusDate, false, false);
215
- }
1714
+ var isTimeOnly = settings.type === 'time';
1715
+ var isDateOnly = settings.type.indexOf('time') < 0;
216
1716
 
217
- var isYear = mode === 'year';
218
- var isMonth = mode === 'month';
219
- var isDay = mode === 'day';
220
- var isHour = mode === 'hour';
221
- var isMinute = mode === 'minute';
222
- var isTimeOnly = settings.type === 'time';
223
-
224
- var multiMonth = Math.max(settings.multiMonth, 1);
225
- var monthOffset = !isDay ? 0 : module.get.monthOffset();
226
-
227
- var minute = display.getMinutes();
228
- var hour = display.getHours();
229
- var day = display.getDate();
230
- var startMonth = display.getMonth() + monthOffset;
231
- var year = display.getFullYear();
232
-
233
- var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : timeGap['column'];
234
- var rows = isDay || isHour ? 6 : timeGap['row'];
235
- var pages = isDay ? multiMonth : 1;
236
-
237
- var container = $container;
238
- var tooltipPosition = container.hasClass("left") ? "right center" : "left center";
239
- container.empty();
240
- if (pages > 1) {
241
- pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
242
- }
1717
+ var
1718
+ words = text.split(settings.regExp.dateWords),
1719
+ word
1720
+ ;
1721
+ var
1722
+ numbers = text.split(settings.regExp.dateNumbers),
1723
+ number
1724
+ ;
243
1725
 
244
- for (p = 0; p < pages; p++) {
245
- if (pages > 1) {
246
- var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
247
- container = pageColumn;
248
- }
249
-
250
- var month = startMonth + p;
251
- var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
252
- if (!settings.constantHeight && isDay) {
253
- var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
254
- rows = Math.ceil(requiredCells / 7);
255
- }
256
-
257
- var yearChange = isYear ? 10 : isMonth ? 1 : 0;
258
- var monthChange = isDay ? 1 : 0;
259
- var dayChange = isHour || isMinute ? 1 : 0;
260
- var prevNextDay = isHour || isMinute ? day : 1;
261
- var prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour);
262
- var nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour);
263
-
264
- var prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
265
- isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1);
266
- var nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
267
- isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1);
268
-
269
- var tempMode = mode;
270
- if (isDay && settings.showWeekNumbers){
271
- tempMode += ' andweek';
272
- }
273
- var table = $('<table/>').addClass(className.table).addClass(tempMode).appendTo(container);
274
- var textColumns = columns;
275
- //no header for time-only mode
276
- if (!isTimeOnly) {
277
- var thead = $('<thead/>').appendTo(table);
278
-
279
- row = $('<tr/>').appendTo(thead);
280
- cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
281
-
282
- var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
283
- isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
284
- var headerText = $('<span/>').addClass(className.link).appendTo(cell);
285
- headerText.text(formatter.header(headerDate, mode, settings));
286
- var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
287
- isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
288
- headerText.data(metadata.mode, newMode);
289
-
290
- if (p === 0) {
291
- var prev = $('<span/>').addClass(className.prev).appendTo(cell);
292
- prev.data(metadata.focusDate, prevDate);
293
- prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
294
- $('<i/>').addClass(className.prevIcon).appendTo(prev);
1726
+ var parts;
1727
+ var monthString;
1728
+
1729
+ if (!isDateOnly) {
1730
+ // am/pm
1731
+ isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0
1732
+ ? true
1733
+ : ($.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined);
1734
+
1735
+ // time with ':'
1736
+ for (i = 0; i < numbers.length; i++) {
1737
+ number = numbers[i];
1738
+ if (number.indexOf(':') >= 0) {
1739
+ if (hour < 0 || minute < 0) {
1740
+ parts = number.split(':');
1741
+ for (k = 0; k < Math.min(2, parts.length); k++) {
1742
+ j = parseInt(parts[k], 10);
1743
+ if (isNaN(j)) {
1744
+ j = 0;
1745
+ }
1746
+ if (k === 0) {
1747
+ hour = j % 24;
1748
+ } else {
1749
+ minute = j % 60;
1750
+ }
1751
+ }
1752
+ }
1753
+ numbers.splice(i, 1);
1754
+ }
1755
+ }
295
1756
  }
296
1757
 
297
- if (p === pages - 1) {
298
- var next = $('<span/>').addClass(className.next).appendTo(cell);
299
- next.data(metadata.focusDate, nextDate);
300
- next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
301
- $('<i/>').addClass(className.nextIcon).appendTo(next);
302
- }
303
- if (isDay) {
304
- row = $('<tr/>').appendTo(thead);
305
- if(settings.showWeekNumbers) {
306
- cell = $('<th/>').appendTo(row);
307
- cell.text(settings.text.weekNo);
308
- cell.addClass(className.weekCell);
309
- textColumns--;
310
- }
311
- for (i = 0; i < textColumns; i++) {
312
- cell = $('<th/>').appendTo(row);
313
- cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
314
- }
315
- }
316
- }
317
-
318
- var tbody = $('<tbody/>').appendTo(table);
319
- i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
320
- for (r = 0; r < rows; r++) {
321
- row = $('<tr/>').appendTo(tbody);
322
- if(isDay && settings.showWeekNumbers){
323
- cell = $('<th/>').appendTo(row);
324
- cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek));
325
- cell.addClass(className.weekCell);
326
- }
327
- for (c = 0; c < textColumns; c++, i++) {
328
- var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
329
- isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
330
- isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * settings.minTimeGap);
331
- var cellText = isYear ? i :
332
- isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
333
- formatter.time(cellDate, settings, true);
334
- cell = $('<td/>').addClass(className.cell).appendTo(row);
335
- cell.text(cellText);
336
- cell.data(metadata.date, cellDate);
337
- var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
338
- var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode);
339
- if (disabled) {
340
- var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates);
341
- if (disabledDate !== null && disabledDate[metadata.message]) {
342
- cell.attr("data-tooltip", disabledDate[metadata.message]);
343
- cell.attr("data-position", tooltipPosition);
1758
+ if (!isTimeOnly) {
1759
+ // textual month
1760
+ for (i = 0; i < words.length; i++) {
1761
+ word = words[i];
1762
+ if (word.length <= 0) {
1763
+ continue;
1764
+ }
1765
+ for (j = 0; j < settings.text.months.length; j++) {
1766
+ monthString = settings.text.months[j];
1767
+ monthString = monthString.slice(0, word.length).toLowerCase();
1768
+ if (monthString === word) {
1769
+ month = j + 1;
1770
+
1771
+ break;
1772
+ }
1773
+ }
1774
+ if (month >= 0) {
1775
+ break;
1776
+ }
344
1777
  }
345
- } else {
346
- var eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates);
347
- if (eventDate !== null) {
348
- cell.addClass(eventDate[metadata.class] || settings.eventClass);
349
- if (eventDate[metadata.message]) {
350
- cell.attr("data-tooltip", eventDate[metadata.message]);
351
- cell.attr("data-position", tooltipPosition);
352
- }
353
- }
354
- }
355
- var active = module.helper.dateEqual(cellDate, date, mode);
356
- var isToday = module.helper.dateEqual(cellDate, today, mode);
357
- cell.toggleClass(className.adjacentCell, adjacent);
358
- cell.toggleClass(className.disabledCell, disabled);
359
- cell.toggleClass(className.activeCell, active && !adjacent);
360
- if (!isHour && !isMinute) {
361
- cell.toggleClass(className.todayCell, !adjacent && isToday);
362
- }
363
-
364
- // Allow for external modifications of each cell
365
- var cellOptions = {
366
- mode: mode,
367
- adjacent: adjacent,
368
- disabled: disabled,
369
- active: active,
370
- today: isToday
371
- };
372
- formatter.cell(cell, cellDate, cellOptions);
373
-
374
- if (module.helper.dateEqual(cellDate, focusDate, mode)) {
375
- //ensure that the focus date is exactly equal to the cell date
376
- //so that, if selected, the correct value is set
377
- module.set.focusDate(cellDate, false, false);
378
- }
379
- }
380
- }
381
1778
 
382
- if (settings.today) {
383
- var todayRow = $('<tr/>').appendTo(tbody);
384
- var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
385
- todayButton.text(formatter.today(settings));
386
- todayButton.data(metadata.date, today);
387
- }
1779
+ // year > settings.centuryBreak
1780
+ for (i = 0; i < numbers.length; i++) {
1781
+ j = parseInt(numbers[i], 10);
1782
+ if (isNaN(j)) {
1783
+ continue;
1784
+ }
1785
+ if (j >= settings.centuryBreak && i === numbers.length - 1) {
1786
+ if (j <= 99) {
1787
+ j += settings.currentCentury - 100;
1788
+ }
1789
+ year = j;
1790
+ numbers.splice(i, 1);
1791
+
1792
+ break;
1793
+ }
1794
+ }
388
1795
 
389
- module.update.focus(false, table);
390
- }
391
- }
392
- },
1796
+ // numeric month
1797
+ if (month < 0) {
1798
+ for (i = 0; i < numbers.length; i++) {
1799
+ k = i > 1 || settings.monthFirst
1800
+ ? i
1801
+ : (i === 1 ? 0 : 1);
1802
+ j = parseInt(numbers[k], 10);
1803
+ if (isNaN(j)) {
1804
+ continue;
1805
+ }
1806
+ if (j >= 1 && j <= 12) {
1807
+ month = j;
1808
+ numbers.splice(k, 1);
1809
+
1810
+ break;
1811
+ }
1812
+ }
1813
+ }
393
1814
 
394
- update: {
395
- focus: function (updateRange, container) {
396
- container = container || $container;
397
- var mode = module.get.mode();
398
- var date = module.get.date();
399
- var focusDate = module.get.focusDate();
400
- var startDate = module.get.startDate();
401
- var endDate = module.get.endDate();
402
- var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
403
-
404
- container.find('td').each(function () {
405
- var cell = $(this);
406
- var cellDate = cell.data(metadata.date);
407
- if (!cellDate) {
408
- return;
409
- }
410
- var disabled = cell.hasClass(className.disabledCell);
411
- var active = cell.hasClass(className.activeCell);
412
- var adjacent = cell.hasClass(className.adjacentCell);
413
- var focused = module.helper.dateEqual(cellDate, focusDate, mode);
414
- var inRange = !rangeDate ? false :
415
- ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
416
- (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
417
- cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled);
418
-
419
- if (module.helper.isTodayButton(cell)) {
420
- return;
421
- }
422
- cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
423
- });
424
- }
425
- },
1815
+ // day
1816
+ for (i = 0; i < numbers.length; i++) {
1817
+ j = parseInt(numbers[i], 10);
1818
+ if (isNaN(j)) {
1819
+ continue;
1820
+ }
1821
+ if (j >= 1 && j <= 31) {
1822
+ day = j;
1823
+ numbers.splice(i, 1);
1824
+
1825
+ break;
1826
+ }
1827
+ }
426
1828
 
427
- refresh: function () {
428
- module.create.calendar();
429
- },
1829
+ // year <= settings.centuryBreak
1830
+ if (year < 0) {
1831
+ for (i = numbers.length - 1; i >= 0; i--) {
1832
+ j = parseInt(numbers[i], 10);
1833
+ if (isNaN(j)) {
1834
+ continue;
1835
+ }
1836
+ if (j <= 99) {
1837
+ j += settings.currentCentury;
1838
+ }
1839
+ year = j;
1840
+ numbers.splice(i, 1);
1841
+
1842
+ break;
1843
+ }
1844
+ }
1845
+ }
430
1846
 
431
- bind: {
432
- events: function () {
433
- module.debug('Binding events');
434
- $container.on('mousedown' + eventNamespace, module.event.mousedown);
435
- $container.on('touchstart' + eventNamespace, module.event.mousedown);
436
- $container.on('mouseup' + eventNamespace, module.event.mouseup);
437
- $container.on('touchend' + eventNamespace, module.event.mouseup);
438
- $container.on('mouseover' + eventNamespace, module.event.mouseover);
439
- if ($input.length) {
440
- $input.on('input' + eventNamespace, module.event.inputChange);
441
- $input.on('focus' + eventNamespace, module.event.inputFocus);
442
- $input.on('blur' + eventNamespace, module.event.inputBlur);
443
- $input.on('click' + eventNamespace, module.event.inputClick);
444
- $input.on('keydown' + eventNamespace, module.event.keydown);
445
- } else {
446
- $container.on('keydown' + eventNamespace, module.event.keydown);
447
- }
448
- }
449
- },
1847
+ if (!isDateOnly) {
1848
+ // hour
1849
+ if (hour < 0) {
1850
+ for (i = 0; i < numbers.length; i++) {
1851
+ j = parseInt(numbers[i], 10);
1852
+ if (isNaN(j)) {
1853
+ continue;
1854
+ }
1855
+ if (j >= 0 && j <= 23) {
1856
+ hour = j;
1857
+ numbers.splice(i, 1);
1858
+
1859
+ break;
1860
+ }
1861
+ }
1862
+ }
450
1863
 
451
- unbind: {
452
- events: function () {
453
- module.debug('Unbinding events');
454
- $container.off(eventNamespace);
455
- if ($input.length) {
456
- $input.off(eventNamespace);
457
- }
458
- }
459
- },
1864
+ // minute
1865
+ if (minute < 0) {
1866
+ for (i = 0; i < numbers.length; i++) {
1867
+ j = parseInt(numbers[i], 10);
1868
+ if (isNaN(j)) {
1869
+ continue;
1870
+ }
1871
+ if (j >= 0 && j <= 59) {
1872
+ minute = j;
1873
+ numbers.splice(i, 1);
1874
+
1875
+ break;
1876
+ }
1877
+ }
1878
+ }
1879
+ }
460
1880
 
461
- event: {
462
- mouseover: function (event) {
463
- var target = $(event.target);
464
- var date = target.data(metadata.date);
465
- var mousedown = event.buttons === 1;
466
- if (date) {
467
- module.set.focusDate(date, false, true, mousedown);
468
- }
469
- },
470
- mousedown: function (event) {
471
- if ($input.length) {
472
- //prevent the mousedown on the calendar causing the input to lose focus
473
- event.preventDefault();
474
- }
475
- isTouchDown = event.type.indexOf('touch') >= 0;
476
- var target = $(event.target);
477
- var date = target.data(metadata.date);
478
- if (date) {
479
- module.set.focusDate(date, false, true, true);
480
- }
481
- },
482
- mouseup: function (event) {
483
- //ensure input has focus so that it receives keydown events for calendar navigation
484
- module.focus();
485
- event.preventDefault();
486
- event.stopPropagation();
487
- isTouchDown = false;
488
- var target = $(event.target);
489
- if (target.hasClass("disabled")) {
490
- return;
491
- }
492
- var parent = target.parent();
493
- if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
494
- //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
495
- target = parent;
496
- }
497
- var date = target.data(metadata.date);
498
- var focusDate = target.data(metadata.focusDate);
499
- var mode = target.data(metadata.mode);
500
- if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) {
501
- var forceSet = target.hasClass(className.today);
502
- module.selectDate(date, forceSet);
503
- }
504
- else if (focusDate) {
505
- module.set.focusDate(focusDate);
506
- }
507
- else if (mode) {
508
- module.set.mode(mode);
509
- }
510
- },
511
- keydown: function (event) {
512
- var keyCode = event.which;
513
- if (keyCode === 27 || keyCode === 9) {
514
- //esc || tab
515
- module.popup('hide');
516
- }
1881
+ if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1882
+ return null;
1883
+ }
517
1884
 
518
- if (module.popup('is visible')) {
519
- if (keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) {
520
- //arrow keys
521
- var mode = module.get.mode();
522
- var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : mode === 'minute' ? timeGap['column'] : 3;
523
- var increment = keyCode === 37 ? -1 : keyCode === 38 ? -bigIncrement : keyCode == 39 ? 1 : bigIncrement;
524
- increment *= mode === 'minute' ? settings.minTimeGap : 1;
525
- var focusDate = module.get.focusDate() || module.get.date() || new Date();
526
- var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
527
- var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
528
- var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
529
- var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
530
- var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
531
- var newFocusDate = new Date(year, month, day, hour, minute);
532
- if (settings.type === 'time') {
533
- newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
1885
+ if (minute < 0) {
1886
+ minute = 0;
534
1887
  }
535
- if (module.helper.isDateInRange(newFocusDate, mode)) {
536
- module.set.focusDate(newFocusDate);
1888
+ if (hour < 0) {
1889
+ hour = 0;
537
1890
  }
538
- } else if (keyCode === 13) {
539
- //enter
540
- var mode = module.get.mode();
541
- var date = module.get.focusDate();
542
- if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) {
543
- module.selectDate(date);
1891
+ if (day < 0) {
1892
+ day = 1;
1893
+ }
1894
+ if (month < 0) {
1895
+ month = 1;
1896
+ }
1897
+ if (year < 0) {
1898
+ year = new Date().getFullYear();
544
1899
  }
545
- //disable form submission:
546
- event.preventDefault();
547
- event.stopPropagation();
548
- }
549
- }
550
-
551
- if (keyCode === 38 || keyCode === 40) {
552
- //arrow-up || arrow-down
553
- event.preventDefault(); //don't scroll
554
- module.popup('show');
555
- }
556
- },
557
- inputChange: function () {
558
- var val = $input.val();
559
- var date = parser.date(val, settings);
560
- module.set.date(date, false);
561
- },
562
- inputFocus: function () {
563
- $container.addClass(className.active);
564
- },
565
- inputBlur: function () {
566
- $container.removeClass(className.active);
567
- if (settings.formatInput) {
568
- var date = module.get.date();
569
- var text = formatter.datetime(date, settings);
570
- $input.val(text);
571
- }
572
- },
573
- inputClick: function () {
574
- module.popup('show');
575
- }
576
- },
577
1900
 
578
- get: {
579
- weekOfYear: function(weekYear,weekMonth,weekDay) {
580
- // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
581
- var ms1d = 864e5, // milliseconds in a day
582
- ms7d = 7 * ms1d; // milliseconds in a week
583
-
584
- return function() { // return a closure so constants get calculated only once
585
- var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number
586
- AWN = Math.floor(DC3 / 7), // an Absolute Week Number
587
- Wyr = new Date(AWN * ms7d).getUTCFullYear();
588
-
589
- return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
590
- }();
591
- },
592
- date: function () {
593
- return module.helper.sanitiseDate($module.data(metadata.date)) || null;
594
- },
595
- inputDate: function() {
596
- return $input.val();
597
- },
598
- focusDate: function () {
599
- return $module.data(metadata.focusDate) || null;
600
- },
601
- startDate: function () {
602
- var startModule = module.get.calendarModule(settings.startCalendar);
603
- return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
604
- },
605
- endDate: function () {
606
- var endModule = module.get.calendarModule(settings.endCalendar);
607
- return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
608
- },
609
- minDate: function() {
610
- return $module.data(metadata.minDate) || null;
611
- },
612
- maxDate: function() {
613
- return $module.data(metadata.maxDate) || null;
614
- },
615
- monthOffset: function () {
616
- return $module.data(metadata.monthOffset) || 0;
617
- },
618
- mode: function () {
619
- //only returns valid modes for the current settings
620
- var mode = $module.data(metadata.mode) || settings.startMode;
621
- var validModes = module.get.validModes();
622
- if ($.inArray(mode, validModes) >= 0) {
623
- return mode;
624
- }
625
- return settings.type === 'time' ? 'hour' :
626
- settings.type === 'month' ? 'month' :
627
- settings.type === 'year' ? 'year' : 'day';
628
- },
629
- type: function() {
630
- return $module.data(metadata.type) || settings.type;
631
- },
632
- validModes: function () {
633
- var validModes = [];
634
- if (settings.type !== 'time') {
635
- if (!settings.disableYear || settings.type === 'year') {
636
- validModes.push('year');
637
- }
638
- if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
639
- validModes.push('month');
640
- }
641
- if (settings.type.indexOf('date') >= 0) {
642
- validModes.push('day');
643
- }
644
- }
645
- if (settings.type.indexOf('time') >= 0) {
646
- validModes.push('hour');
647
- if (!settings.disableMinute) {
648
- validModes.push('minute');
649
- }
650
- }
651
- return validModes;
652
- },
653
- isTouch: function () {
654
- try {
655
- document.createEvent('TouchEvent');
656
- return true;
657
- }
658
- catch (e) {
659
- return false;
660
- }
661
- },
662
- calendarModule: function (selector) {
663
- if (!selector) {
664
- return null;
665
- }
666
- if (!(selector instanceof $)) {
667
- selector = $(selector).first();
668
- }
669
- //assume range related calendars are using the same namespace
670
- return selector.data(moduleNamespace);
671
- }
672
- },
1901
+ if (isAm !== undefined) {
1902
+ if (isAm) {
1903
+ if (hour === 12) {
1904
+ hour = 0;
1905
+ }
1906
+ } else if (hour < 12) {
1907
+ hour += 12;
1908
+ }
1909
+ }
673
1910
 
674
- set: {
675
- date: function (date, updateInput, fireChange) {
676
- updateInput = updateInput !== false;
677
- fireChange = fireChange !== false;
678
- date = module.helper.sanitiseDate(date);
679
- date = module.helper.dateInRange(date);
1911
+ var date = new Date(year, month - 1, day, hour, minute);
1912
+ if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1913
+ // month or year don't match up, switch to last day of the month
1914
+ date = new Date(year, month, 0, hour, minute);
1915
+ }
680
1916
 
681
- var mode = module.get.mode();
682
- var text = formatter.datetime(date, settings);
1917
+ return isNaN(date.getTime()) ? null : date;
1918
+ },
1919
+ },
683
1920
 
684
- if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) {
685
- return false;
686
- }
1921
+ // callback before date is changed, return false to cancel the change
1922
+ onBeforeChange: function (date, text, mode) {
1923
+ return true;
1924
+ },
687
1925
 
688
- module.set.focusDate(date);
1926
+ // callback when date changes
1927
+ onChange: function (date, text, mode) {},
689
1928
 
690
- if (settings.isDisabled(date, mode)) {
691
- return false;
692
- }
1929
+ // callback before show animation, return false to prevent show
1930
+ onShow: function () {},
693
1931
 
694
- var endDate = module.get.endDate();
695
- if (!!endDate && !!date && date > endDate) {
696
- //selected date is greater than end date in range, so clear end date
697
- module.set.endDate(undefined);
698
- }
699
- module.set.dataKeyValue(metadata.date, date);
1932
+ // callback after show animation
1933
+ onVisible: function () {},
700
1934
 
701
- if (updateInput && $input.length) {
702
- $input.val(text);
703
- }
1935
+ // callback before hide animation, return false to prevent hide
1936
+ onHide: function () {},
704
1937
 
705
- if (fireChange) {
706
- settings.onChange.call(element, date, text, mode);
707
- }
708
- },
709
- startDate: function (date, refreshCalendar) {
710
- date = module.helper.sanitiseDate(date);
711
- var startModule = module.get.calendarModule(settings.startCalendar);
712
- if (startModule) {
713
- startModule.set.date(date);
714
- }
715
- module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
716
- },
717
- endDate: function (date, refreshCalendar) {
718
- date = module.helper.sanitiseDate(date);
719
- var endModule = module.get.calendarModule(settings.endCalendar);
720
- if (endModule) {
721
- endModule.set.date(date);
722
- }
723
- module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
724
- },
725
- focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
726
- date = module.helper.sanitiseDate(date);
727
- date = module.helper.dateInRange(date);
728
- var isDay = module.get.mode() === 'day';
729
- var oldFocusDate = module.get.focusDate();
730
- if (isDay && date && oldFocusDate) {
731
- var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
732
- var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
733
- if (monthDelta) {
734
- var monthOffset = module.get.monthOffset() - monthDelta;
735
- module.set.monthOffset(monthOffset, false);
736
- }
737
- }
738
- var changed = module.set.dataKeyValue(metadata.focusDate, date, refreshCalendar);
739
- updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
740
- focusDateUsedForRange = updateRange;
741
- if (updateFocus) {
742
- module.update.focus(updateRange);
743
- }
744
- },
745
- minDate: function (date) {
746
- date = module.helper.sanitiseDate(date);
747
- if (settings.maxDate !== null && settings.maxDate <= date) {
748
- module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
749
- } else {
750
- module.setting('minDate', date);
751
- module.set.dataKeyValue(metadata.minDate, date);
752
- }
753
- },
754
- maxDate: function (date) {
755
- date = module.helper.sanitiseDate(date);
756
- if (settings.minDate !== null && settings.minDate >= date) {
757
- module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
758
- } else {
759
- module.setting('maxDate', date);
760
- module.set.dataKeyValue(metadata.maxDate, date);
761
- }
762
- },
763
- monthOffset: function (monthOffset, refreshCalendar) {
764
- var multiMonth = Math.max(settings.multiMonth, 1);
765
- monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
766
- module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
767
- },
768
- mode: function (mode, refreshCalendar) {
769
- module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
770
- },
771
- dataKeyValue: function (key, value, refreshCalendar) {
772
- var oldValue = $module.data(key);
773
- var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
774
- if (value) {
775
- $module.data(key, value);
776
- } else {
777
- $module.removeData(key);
778
- }
779
- refreshCalendar = refreshCalendar !== false && !equal;
780
- if (refreshCalendar) {
781
- module.refresh();
782
- }
783
- return !equal;
784
- }
785
- },
1938
+ // callback after hide animation
1939
+ onHidden: function () {},
786
1940
 
787
- selectDate: function (date, forceSet) {
788
- module.verbose('New date selection', date);
789
- var mode = module.get.mode();
790
- var complete = forceSet || mode === 'minute' ||
791
- (settings.disableMinute && mode === 'hour') ||
792
- (settings.type === 'date' && mode === 'day') ||
793
- (settings.type === 'month' && mode === 'month') ||
794
- (settings.type === 'year' && mode === 'year');
795
- if (complete) {
796
- var canceled = module.set.date(date) === false;
797
- if (!canceled && settings.closable) {
798
- module.popup('hide');
799
- //if this is a range calendar, show the end date calendar popup and focus the input
800
- var endModule = module.get.calendarModule(settings.endCalendar);
801
- if (endModule) {
802
- endModule.popup('show');
803
- endModule.focus();
804
- }
805
- }
806
- } else {
807
- var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
808
- mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
809
- module.set.mode(newMode);
810
- if (mode === 'hour' || (mode === 'day' && module.get.date())) {
811
- //the user has chosen enough to consider a valid date/time has been chosen
812
- module.set.date(date);
813
- } else {
814
- module.set.focusDate(date);
815
- }
816
- }
817
- },
1941
+ // callback before item is selected, return false to prevent selection
1942
+ onSelect: function (date, mode) {},
818
1943
 
819
- changeDate: function (date) {
820
- module.set.date(date);
1944
+ // is the given date disabled?
1945
+ isDisabled: function (date, mode) {
1946
+ return false;
821
1947
  },
822
1948
 
823
- clear: function () {
824
- module.set.date(undefined);
1949
+ selector: {
1950
+ popup: '.ui.popup',
1951
+ input: 'input',
1952
+ activator: 'input',
1953
+ append: '.inline.field,.inline.fields',
825
1954
  },
826
1955
 
827
- popup: function () {
828
- return $activator.popup.apply($activator, arguments);
1956
+ regExp: {
1957
+ dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1958
+ dateNumbers: /[^\d:]+/g,
1959
+ token: /d{1,4}|D{1,2}|M{1,4}|YY(?:YY)?|([Hhmsw])\1?|[ASYa]|"[^"]*"|'[^']*'/g,
829
1960
  },
830
1961
 
831
- focus: function () {
832
- if ($input.length) {
833
- $input.focus();
834
- } else {
835
- $container.focus();
836
- }
837
- },
838
- blur: function () {
839
- if ($input.length) {
840
- $input.blur();
841
- } else {
842
- $container.blur();
843
- }
1962
+ error: {
1963
+ popup: 'UI Popup, a required component is not included in this page',
1964
+ method: 'The method you called is not defined.',
844
1965
  },
845
1966
 
846
- helper: {
847
- isDisabled: function(date, mode) {
848
- return (mode === 'day' || mode === 'month' || mode === 'year') && ((settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){
849
- if(typeof d === 'string') {
850
- d = module.helper.sanitiseDate(d);
851
- }
852
- if (d instanceof Date) {
853
- return module.helper.dateEqual(date, d, mode);
854
- }
855
- if (d !== null && typeof d === 'object') {
856
- if (d[metadata.year]) {
857
- if (typeof d[metadata.year] === 'number') {
858
- return date.getFullYear() == d[metadata.year];
859
- } else if (Array.isArray(d[metadata.year])) {
860
- return d[metadata.year].indexOf(date.getFullYear()) > -1;
861
- }
862
- } else if (d[metadata.month]) {
863
- if (typeof d[metadata.month] === 'number') {
864
- return date.getMonth() == d[metadata.month];
865
- } else if (Array.isArray(d[metadata.month])) {
866
- return d[metadata.month].indexOf(date.getMonth()) > -1;
867
- } else if (d[metadata.month] instanceof Date) {
868
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
869
- return (date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())
870
- }
871
- } else if (d[metadata.date] && mode === 'day') {
872
- if (d[metadata.date] instanceof Date) {
873
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
874
- } else if (Array.isArray(d[metadata.date])) {
875
- return d[metadata.date].some(function(idate) {
876
- return module.helper.dateEqual(date, idate, mode);
877
- });
878
- }
879
- }
880
- }
881
- }));
882
- },
883
- isEnabled: function(date, mode) {
884
- if (mode === 'day') {
885
- return settings.enabledDates.length === 0 || settings.enabledDates.some(function(d){
886
- if(typeof d === 'string') {
887
- d = module.helper.sanitiseDate(d);
888
- }
889
- if (d instanceof Date) {
890
- return module.helper.dateEqual(date, d, mode);
891
- }
892
- if (d !== null && typeof d === 'object' && d[metadata.date]) {
893
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
894
- }
895
- });
896
- } else {
897
- return true;
898
- }
899
- },
900
- findDayAsObject: function(date, mode, dates) {
901
- if (mode === 'day' || mode === 'month' || mode === 'year') {
902
- var d;
903
- for (var i = 0; i < dates.length; i++) {
904
- d = dates[i];
905
- if(typeof d === 'string') {
906
- d = module.helper.sanitiseDate(d);
907
- }
908
- if (d instanceof Date && module.helper.dateEqual(date, d, mode)) {
909
- var dateObject = {};
910
- dateObject[metadata.date] = d;
911
- return dateObject;
912
- }
913
- else if (d !== null && typeof d === 'object') {
914
- if (d[metadata.year]) {
915
- if (typeof d[metadata.year] === 'number' && date.getFullYear() == d[metadata.year]) {
916
- return d;
917
- } else if (Array.isArray(d[metadata.year])) {
918
- if (d[metadata.year].indexOf(date.getFullYear()) > -1) {
919
- return d;
920
- }
921
- }
922
- } else if (d[metadata.month]) {
923
- if (typeof d[metadata.month] === 'number' && date.getMonth() == d[metadata.month]) {
924
- return d;
925
- } else if (Array.isArray(d[metadata.month])) {
926
- if (d[metadata.month].indexOf(date.getMonth()) > -1) {
927
- return d;
928
- }
929
- } else if (d[metadata.month] instanceof Date) {
930
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
931
- if ((date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())) {
932
- return d;
933
- }
934
- }
935
- } else if (d[metadata.date] && mode === 'day') {
936
- if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) {
937
- return d;
938
- } else if (Array.isArray(d[metadata.date])) {
939
- if(d[metadata.date].some(function(idate) { return module.helper.dateEqual(date, idate, mode); })) {
940
- return d;
941
- }
942
- }
943
- }
944
- }
945
- }
946
- }
947
- return null;
948
- },
949
- sanitiseDate: function (date) {
950
- if (!date) {
951
- return undefined;
952
- }
953
- if (!(date instanceof Date)) {
954
- date = parser.date('' + date, settings);
955
- }
956
- if (!date || date === null || isNaN(date.getTime())) {
957
- return undefined;
958
- }
959
- return date;
960
- },
961
- dateDiff: function (date1, date2, mode) {
962
- mode = mode || 'day';
963
- var isTimeOnly = settings.type === 'time';
964
- var isYear = mode === 'year';
965
- var isYearOrMonth = isYear || mode === 'month';
966
- var isMinute = mode === 'minute';
967
- var isHourOrMinute = isMinute || mode === 'hour';
968
- //only care about a minute accuracy of settings.minTimeGap
969
- date1 = new Date(
970
- isTimeOnly ? 2000 : date1.getFullYear(),
971
- isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
972
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
973
- !isHourOrMinute ? 0 : date1.getHours(),
974
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap));
975
- date2 = new Date(
976
- isTimeOnly ? 2000 : date2.getFullYear(),
977
- isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
978
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
979
- !isHourOrMinute ? 0 : date2.getHours(),
980
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap));
981
- return date2.getTime() - date1.getTime();
982
- },
983
- dateEqual: function (date1, date2, mode) {
984
- return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
985
- },
986
- isDateInRange: function (date, mode, minDate, maxDate) {
987
- if (!minDate && !maxDate) {
988
- var startDate = module.get.startDate();
989
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
990
- maxDate = settings.maxDate;
991
- }
992
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
993
- return !(!date ||
994
- (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
995
- (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
996
- },
997
- dateInRange: function (date, minDate, maxDate) {
998
- if (!minDate && !maxDate) {
999
- var startDate = module.get.startDate();
1000
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
1001
- maxDate = settings.maxDate;
1002
- }
1003
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
1004
- var isTimeOnly = settings.type === 'time';
1005
- return !date ? date :
1006
- (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
1007
- (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
1008
- (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
1009
- (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
1010
- date;
1011
- },
1012
- mergeDateTime: function (date, time) {
1013
- return (!date || !time) ? time :
1014
- new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
1015
- },
1016
- isTodayButton: function(element) {
1017
- return element.text() === settings.text.today;
1018
- }
1967
+ className: {
1968
+ calendar: 'calendar',
1969
+ active: 'active',
1970
+ popup: 'ui popup',
1971
+ grid: 'ui equal width grid',
1972
+ column: 'column',
1973
+ table: 'ui celled center aligned unstackable table',
1974
+ inverted: 'inverted',
1975
+ prev: 'prev link',
1976
+ next: 'next link',
1977
+ prevIcon: 'chevron left icon',
1978
+ nextIcon: 'chevron right icon',
1979
+ link: 'link',
1980
+ cell: 'link',
1981
+ disabledCell: 'disabled',
1982
+ weekCell: 'disabled',
1983
+ adjacentCell: 'adjacent',
1984
+ activeCell: 'active',
1985
+ rangeCell: 'range',
1986
+ focusCell: 'focus',
1987
+ todayCell: 'today',
1988
+ today: 'today link',
1989
+ disabled: 'disabled',
1019
1990
  },
1020
1991
 
1021
- setting: function (name, value) {
1022
- module.debug('Changing setting', name, value);
1023
- if ($.isPlainObject(name)) {
1024
- $.extend(true, settings, name);
1025
- }
1026
- else if (value !== undefined) {
1027
- if ($.isPlainObject(settings[name])) {
1028
- $.extend(true, settings[name], value);
1029
- }
1030
- else {
1031
- settings[name] = value;
1032
- }
1033
- }
1034
- else {
1035
- return settings[name];
1036
- }
1037
- },
1038
- internal: function (name, value) {
1039
- if( $.isPlainObject(name) ) {
1040
- $.extend(true, module, name);
1041
- }
1042
- else if(value !== undefined) {
1043
- module[name] = value;
1044
- }
1045
- else {
1046
- return module[name];
1047
- }
1048
- },
1049
- debug: function () {
1050
- if (!settings.silent && settings.debug) {
1051
- if (settings.performance) {
1052
- module.performance.log(arguments);
1053
- }
1054
- else {
1055
- module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1056
- module.debug.apply(console, arguments);
1057
- }
1058
- }
1992
+ metadata: {
1993
+ date: 'date',
1994
+ focusDate: 'focusDate',
1995
+ startDate: 'startDate',
1996
+ endDate: 'endDate',
1997
+ minDate: 'minDate',
1998
+ maxDate: 'maxDate',
1999
+ mode: 'mode',
2000
+ type: 'type',
2001
+ monthOffset: 'monthOffset',
2002
+ message: 'message',
2003
+ class: 'class',
2004
+ inverted: 'inverted',
2005
+ variation: 'variation',
2006
+ position: 'position',
2007
+ month: 'month',
2008
+ year: 'year',
2009
+ hours: 'hours',
2010
+ days: 'days',
1059
2011
  },
1060
- verbose: function () {
1061
- if (!settings.silent && settings.verbose && settings.debug) {
1062
- if (settings.performance) {
1063
- module.performance.log(arguments);
1064
- }
1065
- else {
1066
- module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1067
- module.verbose.apply(console, arguments);
1068
- }
1069
- }
1070
- },
1071
- error: function () {
1072
- if (!settings.silent) {
1073
- module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1074
- module.error.apply(console, arguments);
1075
- }
1076
- },
1077
- performance: {
1078
- log: function (message) {
1079
- var
1080
- currentTime,
1081
- executionTime,
1082
- previousTime
1083
- ;
1084
- if (settings.performance) {
1085
- currentTime = new Date().getTime();
1086
- previousTime = time || currentTime;
1087
- executionTime = currentTime - previousTime;
1088
- time = currentTime;
1089
- performance.push({
1090
- 'Name': message[0],
1091
- 'Arguments': [].slice.call(message, 1) || '',
1092
- 'Element': element,
1093
- 'Execution Time': executionTime
1094
- });
1095
- }
1096
- clearTimeout(module.performance.timer);
1097
- module.performance.timer = setTimeout(module.performance.display, 500);
1098
- },
1099
- display: function () {
1100
- var
1101
- title = settings.name + ':',
1102
- totalTime = 0
1103
- ;
1104
- time = false;
1105
- clearTimeout(module.performance.timer);
1106
- $.each(performance, function (index, data) {
1107
- totalTime += data['Execution Time'];
1108
- });
1109
- title += ' ' + totalTime + 'ms';
1110
- if (moduleSelector) {
1111
- title += ' \'' + moduleSelector + '\'';
1112
- }
1113
- if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1114
- console.groupCollapsed(title);
1115
- if (console.table) {
1116
- console.table(performance);
1117
- }
1118
- else {
1119
- $.each(performance, function (index, data) {
1120
- console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
1121
- });
1122
- }
1123
- console.groupEnd();
1124
- }
1125
- performance = [];
1126
- }
1127
- },
1128
- invoke: function (query, passedArguments, context) {
1129
- var
1130
- object = instance,
1131
- maxDepth,
1132
- found,
1133
- response
1134
- ;
1135
- passedArguments = passedArguments || queryArguments;
1136
- context = element || context;
1137
- if (typeof query == 'string' && object !== undefined) {
1138
- query = query.split(/[\. ]/);
1139
- maxDepth = query.length - 1;
1140
- $.each(query, function (depth, value) {
1141
- var camelCaseValue = (depth != maxDepth)
1142
- ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1143
- : query
1144
- ;
1145
- if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
1146
- object = object[camelCaseValue];
1147
- }
1148
- else if (object[camelCaseValue] !== undefined) {
1149
- found = object[camelCaseValue];
1150
- return false;
1151
- }
1152
- else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
1153
- object = object[value];
1154
- }
1155
- else if (object[value] !== undefined) {
1156
- found = object[value];
1157
- return false;
1158
- }
1159
- else {
1160
- module.error(error.method, query);
1161
- return false;
1162
- }
1163
- });
1164
- }
1165
- if ($.isFunction(found)) {
1166
- response = found.apply(context, passedArguments);
1167
- }
1168
- else if (found !== undefined) {
1169
- response = found;
1170
- }
1171
- if (Array.isArray(returnedValue)) {
1172
- returnedValue.push(response);
1173
- }
1174
- else if (returnedValue !== undefined) {
1175
- returnedValue = [returnedValue, response];
1176
- }
1177
- else if (response !== undefined) {
1178
- returnedValue = response;
1179
- }
1180
- return found;
1181
- }
1182
- };
1183
-
1184
- if (methodInvoked) {
1185
- if (instance === undefined) {
1186
- module.initialize();
1187
- }
1188
- module.invoke(query);
1189
- }
1190
- else {
1191
- if (instance !== undefined) {
1192
- instance.invoke('destroy');
1193
- }
1194
- module.initialize();
1195
- }
1196
- })
1197
- ;
1198
- return (returnedValue !== undefined)
1199
- ? returnedValue
1200
- : this
1201
- ;
1202
- };
1203
-
1204
- $.fn.calendar.settings = {
1205
-
1206
- name : 'Calendar',
1207
- namespace : 'calendar',
1208
-
1209
- silent: false,
1210
- debug: false,
1211
- verbose: false,
1212
- performance: false,
1213
-
1214
- type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
1215
- firstDayOfWeek : 0, // day for first day column (0 = Sunday)
1216
- constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows)
1217
- today : false, // show a 'today/now' button at the bottom of the calendar
1218
- closable : true, // close the popup after selecting a date/time
1219
- monthFirst : true, // month before day when parsing/converting date from/to text
1220
- touchReadonly : true, // set input to readonly on touch devices
1221
- inline : false, // create the calendar inline instead of inside a popup
1222
- on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
1223
- initialDate : null, // date to display initially when no date is selected (null = now)
1224
- startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
1225
- minDate : null, // minimum date/time that can be selected, dates/times before are disabled
1226
- maxDate : null, // maximum date/time that can be selected, dates/times after are disabled
1227
- ampm : true, // show am/pm in time mode
1228
- disableYear : false, // disable year selection mode
1229
- disableMonth : false, // disable month selection mode
1230
- disableMinute : false, // disable minute selection mode
1231
- formatInput : true, // format the input text upon input blur and module creation
1232
- startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range
1233
- endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range
1234
- multiMonth : 1, // show multiple months when in 'day' mode
1235
- minTimeGap : 5,
1236
- showWeekNumbers : null, // show Number of Week at the very first column of a dayView
1237
- disabledDates : [], // specific day(s) which won't be selectable and contain additional information.
1238
- disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday)
1239
- enabledDates : [], // specific day(s) which will be selectable, all other days will be disabled
1240
- eventDates : [], // specific day(s) which will be shown in a different color and using tooltips
1241
- centuryBreak : 60, // starting short year until 99 where it will be assumed to belong to the last century
1242
- currentCentury : 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1)
1243
- selectAdjacentDays : false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable.
1244
- // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1245
- popupOptions: {
1246
- position: 'bottom left',
1247
- lastResort: 'bottom left',
1248
- prefer: 'opposite',
1249
- hideOnScroll: false
1250
- },
1251
-
1252
- text: {
1253
- days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1254
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1255
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1256
- today: 'Today',
1257
- now: 'Now',
1258
- am: 'AM',
1259
- pm: 'PM',
1260
- weekNo: 'Week'
1261
- },
1262
-
1263
- formatter: {
1264
- header: function (date, mode, settings) {
1265
- return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
1266
- mode === 'month' ? settings.formatter.monthHeader(date, settings) :
1267
- mode === 'day' ? settings.formatter.dayHeader(date, settings) :
1268
- mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
1269
- settings.formatter.minuteHeader(date, settings);
1270
- },
1271
- yearHeader: function (date, settings) {
1272
- var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1273
- return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1274
- },
1275
- monthHeader: function (date, settings) {
1276
- return date.getFullYear();
1277
- },
1278
- dayHeader: function (date, settings) {
1279
- var month = settings.text.months[date.getMonth()];
1280
- var year = date.getFullYear();
1281
- return month + ' ' + year;
1282
- },
1283
- hourHeader: function (date, settings) {
1284
- return settings.formatter.date(date, settings);
1285
- },
1286
- minuteHeader: function (date, settings) {
1287
- return settings.formatter.date(date, settings);
1288
- },
1289
- dayColumnHeader: function (day, settings) {
1290
- return settings.text.days[day];
1291
- },
1292
- datetime: function (date, settings) {
1293
- if (!date) {
1294
- return '';
1295
- }
1296
- var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
1297
- var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
1298
- var separator = settings.type === 'datetime' ? ' ' : '';
1299
- return day + separator + time;
1300
- },
1301
- date: function (date, settings) {
1302
- if (!date) {
1303
- return '';
1304
- }
1305
- var day = date.getDate();
1306
- var month = settings.text.months[date.getMonth()];
1307
- var year = date.getFullYear();
1308
- return settings.type === 'year' ? year :
1309
- settings.type === 'month' ? month + ' ' + year :
1310
- (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
1311
- },
1312
- time: function (date, settings, forCalendar) {
1313
- if (!date) {
1314
- return '';
1315
- }
1316
- var hour = date.getHours();
1317
- var minute = date.getMinutes();
1318
- var ampm = '';
1319
- if (settings.ampm) {
1320
- ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
1321
- hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
1322
- }
1323
- return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
1324
- },
1325
- today: function (settings) {
1326
- return settings.type === 'date' ? settings.text.today : settings.text.now;
1327
- },
1328
- cell: function (cell, date, cellOptions) {
1329
- }
1330
- },
1331
-
1332
- parser: {
1333
- date: function (text, settings) {
1334
- if (text instanceof Date) {
1335
- return text;
1336
- }
1337
- if (!text) {
1338
- return null;
1339
- }
1340
- text = ('' + text).trim().toLowerCase();
1341
- if (text.length === 0) {
1342
- return null;
1343
- }
1344
- // Reverse date and month in some cases
1345
- text = settings.monthFirst ? text : text.replace(/[\/\-\.]/g,'/').replace(/([0-9]+)\/([0-9]+)/,'$2/$1');
1346
- var textDate = new Date(text);
1347
- if(!isNaN(textDate.getDate())) {
1348
- return textDate;
1349
- }
1350
-
1351
- var i, j, k;
1352
- var minute = -1, hour = -1, day = -1, month = -1, year = -1;
1353
- var isAm = undefined;
1354
-
1355
- var isTimeOnly = settings.type === 'time';
1356
- var isDateOnly = settings.type.indexOf('time') < 0;
1357
-
1358
- var words = text.split(settings.regExp.dateWords), word;
1359
- var numbers = text.split(settings.regExp.dateNumbers), number;
1360
-
1361
- var parts;
1362
- var monthString;
1363
-
1364
- if (!isDateOnly) {
1365
- //am/pm
1366
- isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
1367
- $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
1368
-
1369
- //time with ':'
1370
- for (i = 0; i < numbers.length; i++) {
1371
- number = numbers[i];
1372
- if (number.indexOf(':') >= 0) {
1373
- if (hour < 0 || minute < 0) {
1374
- parts = number.split(':');
1375
- for (k = 0; k < Math.min(2, parts.length); k++) {
1376
- j = parseInt(parts[k]);
1377
- if (isNaN(j)) {
1378
- j = 0;
1379
- }
1380
- if (k === 0) {
1381
- hour = j % 24;
1382
- } else {
1383
- minute = j % 60;
1384
- }
1385
- }
1386
- }
1387
- numbers.splice(i, 1);
1388
- }
1389
- }
1390
- }
1391
-
1392
- if (!isTimeOnly) {
1393
- //textual month
1394
- for (i = 0; i < words.length; i++) {
1395
- word = words[i];
1396
- if (word.length <= 0) {
1397
- continue;
1398
- }
1399
- for (j = 0; j < settings.text.months.length; j++) {
1400
- monthString = settings.text.months[j];
1401
- monthString = monthString.substring(0, word.length).toLowerCase();
1402
- if (monthString === word) {
1403
- month = j + 1;
1404
- break;
1405
- }
1406
- }
1407
- if (month >= 0) {
1408
- break;
1409
- }
1410
- }
1411
-
1412
- //year > settings.centuryBreak
1413
- for (i = 0; i < numbers.length; i++) {
1414
- j = parseInt(numbers[i]);
1415
- if (isNaN(j)) {
1416
- continue;
1417
- }
1418
- if (j >= settings.centuryBreak && i === numbers.length-1) {
1419
- if (j <= 99) {
1420
- j += settings.currentCentury - 100;
1421
- }
1422
- year = j;
1423
- numbers.splice(i, 1);
1424
- break;
1425
- }
1426
- }
1427
-
1428
- //numeric month
1429
- if (month < 0) {
1430
- for (i = 0; i < numbers.length; i++) {
1431
- k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
1432
- j = parseInt(numbers[k]);
1433
- if (isNaN(j)) {
1434
- continue;
1435
- }
1436
- if (1 <= j && j <= 12) {
1437
- month = j;
1438
- numbers.splice(k, 1);
1439
- break;
1440
- }
1441
- }
1442
- }
1443
-
1444
- //day
1445
- for (i = 0; i < numbers.length; i++) {
1446
- j = parseInt(numbers[i]);
1447
- if (isNaN(j)) {
1448
- continue;
1449
- }
1450
- if (1 <= j && j <= 31) {
1451
- day = j;
1452
- numbers.splice(i, 1);
1453
- break;
1454
- }
1455
- }
1456
-
1457
- //year <= settings.centuryBreak
1458
- if (year < 0) {
1459
- for (i = numbers.length - 1; i >= 0; i--) {
1460
- j = parseInt(numbers[i]);
1461
- if (isNaN(j)) {
1462
- continue;
1463
- }
1464
- if (j <= 99) {
1465
- j += settings.currentCentury;
1466
- }
1467
- year = j;
1468
- numbers.splice(i, 1);
1469
- break;
1470
- }
1471
- }
1472
- }
1473
-
1474
- if (!isDateOnly) {
1475
- //hour
1476
- if (hour < 0) {
1477
- for (i = 0; i < numbers.length; i++) {
1478
- j = parseInt(numbers[i]);
1479
- if (isNaN(j)) {
1480
- continue;
1481
- }
1482
- if (0 <= j && j <= 23) {
1483
- hour = j;
1484
- numbers.splice(i, 1);
1485
- break;
1486
- }
1487
- }
1488
- }
1489
-
1490
- //minute
1491
- if (minute < 0) {
1492
- for (i = 0; i < numbers.length; i++) {
1493
- j = parseInt(numbers[i]);
1494
- if (isNaN(j)) {
1495
- continue;
1496
- }
1497
- if (0 <= j && j <= 59) {
1498
- minute = j;
1499
- numbers.splice(i, 1);
1500
- break;
1501
- }
1502
- }
1503
- }
1504
- }
1505
-
1506
- if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1507
- return null;
1508
- }
1509
-
1510
- if (minute < 0) {
1511
- minute = 0;
1512
- }
1513
- if (hour < 0) {
1514
- hour = 0;
1515
- }
1516
- if (day < 0) {
1517
- day = 1;
1518
- }
1519
- if (month < 0) {
1520
- month = 1;
1521
- }
1522
- if (year < 0) {
1523
- year = new Date().getFullYear();
1524
- }
1525
-
1526
- if (isAm !== undefined) {
1527
- if (isAm) {
1528
- if (hour === 12) {
1529
- hour = 0;
1530
- }
1531
- } else if (hour < 12) {
1532
- hour += 12;
1533
- }
1534
- }
1535
-
1536
- var date = new Date(year, month - 1, day, hour, minute);
1537
- if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1538
- //month or year don't match up, switch to last day of the month
1539
- date = new Date(year, month, 0, hour, minute);
1540
- }
1541
- return isNaN(date.getTime()) ? null : date;
1542
- }
1543
- },
1544
-
1545
- // callback before date is changed, return false to cancel the change
1546
- onBeforeChange: function (date, text, mode) {
1547
- return true;
1548
- },
1549
-
1550
- // callback when date changes
1551
- onChange: function (date, text, mode) {
1552
- },
1553
-
1554
- // callback before show animation, return false to prevent show
1555
- onShow: function () {
1556
- },
1557
-
1558
- // callback after show animation
1559
- onVisible: function () {
1560
- },
1561
-
1562
- // callback before hide animation, return false to prevent hide
1563
- onHide: function () {
1564
- },
1565
-
1566
- // callback after hide animation
1567
- onHidden: function () {
1568
- },
1569
-
1570
- // callback before item is selected, return false to prevent selection
1571
- onSelect: function (date, mode) {
1572
- },
1573
-
1574
- // is the given date disabled?
1575
- isDisabled: function (date, mode) {
1576
- return false;
1577
- },
1578
-
1579
- selector: {
1580
- popup: '.ui.popup',
1581
- input: 'input',
1582
- activator: 'input',
1583
- append: '.inline.field,.inline.fields'
1584
- },
1585
-
1586
- regExp: {
1587
- dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1588
- dateNumbers: /[^\d:]+/g
1589
- },
1590
-
1591
- error: {
1592
- popup: 'UI Popup, a required component is not included in this page',
1593
- method: 'The method you called is not defined.'
1594
- },
1595
-
1596
- className: {
1597
- calendar: 'calendar',
1598
- active: 'active',
1599
- popup: 'ui popup',
1600
- grid: 'ui equal width grid',
1601
- column: 'column',
1602
- table: 'ui celled center aligned unstackable table',
1603
- prev: 'prev link',
1604
- next: 'next link',
1605
- prevIcon: 'chevron left icon',
1606
- nextIcon: 'chevron right icon',
1607
- link: 'link',
1608
- cell: 'link',
1609
- disabledCell: 'disabled',
1610
- weekCell: 'disabled',
1611
- adjacentCell: 'adjacent',
1612
- activeCell: 'active',
1613
- rangeCell: 'range',
1614
- focusCell: 'focus',
1615
- todayCell: 'today',
1616
- today: 'today link'
1617
- },
1618
-
1619
- metadata: {
1620
- date: 'date',
1621
- focusDate: 'focusDate',
1622
- startDate: 'startDate',
1623
- endDate: 'endDate',
1624
- minDate: 'minDate',
1625
- maxDate: 'maxDate',
1626
- mode: 'mode',
1627
- type: 'type',
1628
- monthOffset: 'monthOffset',
1629
- message: 'message',
1630
- class: 'class',
1631
- month: 'month',
1632
- year: 'year'
1633
- },
1634
-
1635
- eventClass: 'blue'
1636
- };
1637
2012
 
2013
+ eventClass: 'blue',
2014
+ };
1638
2015
  })(jQuery, window, document);