tramway 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +12 -893
  4. data/Rakefile +8 -8
  5. data/app/components/tailwind_component.html.haml +0 -0
  6. data/app/components/tailwind_component.rb +6 -0
  7. data/app/components/tailwinds/navbar/button_component.html.haml +1 -0
  8. data/app/components/tailwinds/navbar/button_component.rb +14 -0
  9. data/config/routes.rb +0 -9
  10. data/lib/tasks/tramway_tasks.rake +5 -0
  11. data/lib/tramway/engine.rb +5 -10
  12. data/lib/tramway/version.rb +1 -1
  13. data/lib/tramway.rb +5 -140
  14. metadata +16 -545
  15. data/app/assets/config/tramway_core_manifest.js +0 -2
  16. data/app/assets/images/tramway/mona_lisa_from_prado.jpg +0 -0
  17. data/app/assets/images/tramway/mona_lisa_from_prado_square.jpg +0 -0
  18. data/app/assets/javascripts/bootstrap-datepicker-1.8.0.js +0 -2035
  19. data/app/assets/javascripts/bootstrap-datepicker-1.8.0.ru.min.js +0 -64
  20. data/app/assets/javascripts/ckeditor/config.js +0 -30
  21. data/app/assets/javascripts/ckeditor/plugins/image/dialogs/image.js +0 -1259
  22. data/app/assets/javascripts/ckeditor/plugins/image/icons/hidpi/image.png +0 -0
  23. data/app/assets/javascripts/ckeditor/plugins/image/icons/image.png +0 -0
  24. data/app/assets/javascripts/ckeditor/plugins/image/images/noimage.png +0 -0
  25. data/app/assets/javascripts/ckeditor/plugins/image/lang/en.js +0 -25
  26. data/app/assets/javascripts/ckeditor/plugins/image/lang/ru.js +0 -25
  27. data/app/assets/javascripts/ckeditor/plugins/image/plugin.js +0 -184
  28. data/app/assets/javascripts/ckeditor/plugins/youtube/images/icon-hdpi.png +0 -0
  29. data/app/assets/javascripts/ckeditor/plugins/youtube/images/icon.png +0 -0
  30. data/app/assets/javascripts/ckeditor/plugins/youtube/lang/en.js +0 -25
  31. data/app/assets/javascripts/ckeditor/plugins/youtube/lang/ru.js +0 -25
  32. data/app/assets/javascripts/ckeditor/plugins/youtube/plugin.js +0 -449
  33. data/app/assets/javascripts/tramway/application.js +0 -61
  34. data/app/assets/stylesheets/tramway/application.sass +0 -59
  35. data/app/controllers/tramway/application_controller.rb +0 -142
  36. data/app/controllers/tramway/concerns/auth_management.rb +0 -26
  37. data/app/controllers/tramway/concerns/filtering.rb +0 -43
  38. data/app/controllers/tramway/export/application_controller.rb +0 -5
  39. data/app/controllers/tramway/has_and_belongs_to_many_records_controller.rb +0 -26
  40. data/app/controllers/tramway/records_controller.rb +0 -86
  41. data/app/controllers/tramway/sessions_controller.rb +0 -49
  42. data/app/controllers/tramway/singletons_controller.rb +0 -48
  43. data/app/controllers/tramway/welcome_controller.rb +0 -17
  44. data/app/decorators/tramway/application_decorated_collection.rb +0 -15
  45. data/app/decorators/tramway/application_decorator.rb +0 -124
  46. data/app/decorators/tramway/associations/class_helper.rb +0 -45
  47. data/app/decorators/tramway/associations/object_helper.rb +0 -58
  48. data/app/decorators/tramway/attributes/view_helper.rb +0 -30
  49. data/app/decorators/tramway/concerns/attributes_decorator_helper.rb +0 -97
  50. data/app/decorators/tramway/concerns/table_builder.rb +0 -33
  51. data/app/decorators/tramway/default/values_helper.rb +0 -23
  52. data/app/decorators/tramway/delegating/class_helper.rb +0 -9
  53. data/app/decorators/tramway/user_decorator.rb +0 -49
  54. data/app/forms/admin/tramway/user_form.rb +0 -24
  55. data/app/forms/tramway/application_form.rb +0 -124
  56. data/app/forms/tramway/application_forms/association_class_helpers.rb +0 -7
  57. data/app/forms/tramway/application_forms/association_object_helpers.rb +0 -36
  58. data/app/forms/tramway/application_forms/constant_class_actions.rb +0 -7
  59. data/app/forms/tramway/application_forms/constant_object_actions.rb +0 -20
  60. data/app/forms/tramway/application_forms/frontend.rb +0 -12
  61. data/app/forms/tramway/application_forms/object_helpers.rb +0 -15
  62. data/app/forms/tramway/application_forms/properties_object_helper.rb +0 -16
  63. data/app/forms/tramway/application_forms/submit_helper.rb +0 -26
  64. data/app/forms/tramway/extendable_form.rb +0 -15
  65. data/app/forms/tramway/extendable_forms_helpers/class_builder.rb +0 -34
  66. data/app/forms/tramway/extendable_forms_helpers/ignored_properties_helper.rb +0 -11
  67. data/app/forms/tramway/extendable_forms_helpers/more_properties_helper.rb +0 -31
  68. data/app/forms/tramway/extendable_forms_helpers/properties_helper.rb +0 -16
  69. data/app/forms/tramway/extendable_forms_helpers/submit/class_helpers.rb +0 -18
  70. data/app/forms/tramway/extendable_forms_helpers/submit/object_helpers.rb +0 -21
  71. data/app/forms/tramway/extendable_forms_helpers/validators.rb +0 -40
  72. data/app/forms/tramway/extended_application_form.rb +0 -23
  73. data/app/forms/tramway/form_creator.rb +0 -7
  74. data/app/forms/tramway/session_form.rb +0 -26
  75. data/app/helpers/tramway/actions_helper.rb +0 -45
  76. data/app/helpers/tramway/additional_buttons_builder.rb +0 -12
  77. data/app/helpers/tramway/application_helper.rb +0 -27
  78. data/app/helpers/tramway/cases_helper.rb +0 -13
  79. data/app/helpers/tramway/copy_to_clipboard_helper.rb +0 -11
  80. data/app/helpers/tramway/focus_generator_helper.rb +0 -10
  81. data/app/helpers/tramway/frontend_helper.rb +0 -26
  82. data/app/helpers/tramway/inputs/associations_helper.rb +0 -30
  83. data/app/helpers/tramway/inputs/polymorphic_associations_helper.rb +0 -24
  84. data/app/helpers/tramway/inputs_helper.rb +0 -96
  85. data/app/helpers/tramway/model_helper.rb +0 -7
  86. data/app/helpers/tramway/navbar_helper.rb +0 -11
  87. data/app/helpers/tramway/records_helper.rb +0 -120
  88. data/app/helpers/tramway/russian_cases_helper.rb +0 -26
  89. data/app/helpers/tramway/singleton_helper.rb +0 -12
  90. data/app/helpers/tramway/state_machine_buttons_helper.rb +0 -61
  91. data/app/helpers/tramway/title_helper.rb +0 -25
  92. data/app/inputs/date_picker_input.rb +0 -4
  93. data/app/inputs/multiple_file_input.rb +0 -7
  94. data/app/models/tramway/application_record.rb +0 -62
  95. data/app/models/tramway/user.rb +0 -18
  96. data/app/uploaders/application_uploader.rb +0 -22
  97. data/app/uploaders/file_uploader.rb +0 -4
  98. data/app/uploaders/ico_uploader.rb +0 -7
  99. data/app/uploaders/image_defaults.rb +0 -14
  100. data/app/uploaders/photo_uploader.rb +0 -54
  101. data/app/views/layouts/tramway/application.html.haml +0 -32
  102. data/app/views/layouts/tramway/shared/_navbar.html.haml +0 -46
  103. data/app/views/tramway/404.haml +0 -1
  104. data/app/views/tramway/records/_form.html.haml +0 -22
  105. data/app/views/tramway/records/_list.html.haml +0 -38
  106. data/app/views/tramway/records/_search.html.haml +0 -34
  107. data/app/views/tramway/records/edit.html.haml +0 -1
  108. data/app/views/tramway/records/index.html.haml +0 -31
  109. data/app/views/tramway/records/new.html.haml +0 -1
  110. data/app/views/tramway/records/show.html.haml +0 -1
  111. data/app/views/tramway/sessions/new.html.haml +0 -9
  112. data/app/views/tramway/shared/_input.html.haml +0 -34
  113. data/app/views/tramway/shared/_input_extended.html.haml +0 -14
  114. data/app/views/tramway/shared/_messages.html.haml +0 -10
  115. data/app/views/tramway/shared/_show.html.haml +0 -35
  116. data/app/views/tramway/shared/errors/server_error.html.haml +0 -12
  117. data/app/views/tramway/shared/input_extended_types/_checkbox.html.haml +0 -1
  118. data/app/views/tramway/shared/input_extended_types/_select.html.haml +0 -16
  119. data/app/views/tramway/shared/input_extended_types/_simple.html.haml +0 -4
  120. data/app/views/tramway/shared/input_extended_types/_yes_no.html.haml +0 -4
  121. data/app/views/tramway/shared/show/_attribute_tr.html.haml +0 -9
  122. data/app/views/tramway/shared/show/associations/_habtm_row.html.haml +0 -14
  123. data/app/views/tramway/shared/show/associations/_list.html.haml +0 -21
  124. data/app/views/tramway/shared/show/associations/_row.html.haml +0 -19
  125. data/app/views/tramway/shared/show/associations/_table_row.html.haml +0 -21
  126. data/app/views/tramway/singletons/_form.html.haml +0 -15
  127. data/app/views/tramway/singletons/edit.html.haml +0 -1
  128. data/app/views/tramway/singletons/new.html.haml +0 -1
  129. data/app/views/tramway/singletons/show.html.haml +0 -1
  130. data/app/views/tramway/welcome/index.html.haml +0 -4
  131. data/config/initializers/assets.rb +0 -7
  132. data/config/initializers/ckeditor.rb +0 -9
  133. data/config/initializers/plurals.rb +0 -25
  134. data/config/locales/en/collections.yml +0 -4
  135. data/config/locales/en/date.yml +0 -16
  136. data/config/locales/en/dates.yml +0 -10
  137. data/config/locales/en/helpers.yml +0 -26
  138. data/config/locales/en/locale.yml +0 -11
  139. data/config/locales/en/messages.yml +0 -7
  140. data/config/locales/en/models.yml +0 -9
  141. data/config/locales/en/simple_form_extension.yml +0 -8
  142. data/config/locales/en/state_machines.yml +0 -8
  143. data/config/locales/ru/collections.yml +0 -4
  144. data/config/locales/ru/date.yml +0 -16
  145. data/config/locales/ru/dates.yml +0 -10
  146. data/config/locales/ru/helpers.yml +0 -30
  147. data/config/locales/ru/locale.yml +0 -6
  148. data/config/locales/ru/messages.yml +0 -7
  149. data/config/locales/ru/models.yml +0 -21
  150. data/config/locales/ru/simple_form_extension.yml +0 -8
  151. data/config/locales/ru/state_machines.yml +0 -8
  152. data/lib/string.rb +0 -18
  153. data/lib/tramway/application.rb +0 -10
  154. data/lib/tramway/class_name_helpers.rb +0 -15
  155. data/lib/tramway/collection.rb +0 -9
  156. data/lib/tramway/collections/helper.rb +0 -21
  157. data/lib/tramway/collections.rb +0 -4
  158. data/lib/tramway/error.rb +0 -32
  159. data/lib/tramway/forms.rb +0 -5
  160. data/lib/tramway/generators/install_generator.rb +0 -49
  161. data/lib/tramway/generators/model_generator.rb +0 -105
  162. data/lib/tramway/generators/templates/create_tramway_users.rb +0 -18
  163. data/lib/tramway/generators/templates/decorator.rb.erb +0 -56
  164. data/lib/tramway/generators/templates/form.rb.erb +0 -22
  165. data/lib/tramway/generators/templates/initializers/simple_form.rb +0 -23
  166. data/lib/tramway/generators/templates/initializers/simple_form_bootstrap.rb +0 -133
  167. data/lib/tramway/generators.rb +0 -6
  168. data/lib/tramway/navbar.rb +0 -44
  169. data/lib/tramway/notifications.rb +0 -12
  170. data/lib/tramway/record_routes_helper.rb +0 -23
  171. data/lib/tramway/records_models.rb +0 -60
  172. data/lib/tramway/singleton_models.rb +0 -32
  173. data/lib/tramway/spec/helpers/navbar_helper.rb +0 -7
  174. data/lib/tramway/spec/helpers/tramway_helpers.rb +0 -47
  175. data/lib/tramway/welcome_page_actions.rb +0 -5
  176. data/lib/tramway/yaml/errors.yml +0 -50
  177. data/lib/validators/presence_validator.rb +0 -9
@@ -1,2035 +0,0 @@
1
- /*!
2
- * Datepicker for Bootstrap v1.8.0 (https://github.com/uxsolutions/bootstrap-datepicker)
3
- *
4
- * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
5
- */
6
-
7
- (function(factory){
8
- if (typeof define === 'function' && define.amd) {
9
- define(['jquery'], factory);
10
- } else if (typeof exports === 'object') {
11
- factory(require('jquery'));
12
- } else {
13
- factory(jQuery);
14
- }
15
- }(function($, undefined){
16
- function UTCDate(){
17
- return new Date(Date.UTC.apply(Date, arguments));
18
- }
19
- function UTCToday(){
20
- var today = new Date();
21
- return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
22
- }
23
- function isUTCEquals(date1, date2) {
24
- return (
25
- date1.getUTCFullYear() === date2.getUTCFullYear() &&
26
- date1.getUTCMonth() === date2.getUTCMonth() &&
27
- date1.getUTCDate() === date2.getUTCDate()
28
- );
29
- }
30
- function alias(method, deprecationMsg){
31
- return function(){
32
- if (deprecationMsg !== undefined) {
33
- $.fn.datepicker.deprecated(deprecationMsg);
34
- }
35
-
36
- return this[method].apply(this, arguments);
37
- };
38
- }
39
- function isValidDate(d) {
40
- return d && !isNaN(d.getTime());
41
- }
42
-
43
- var DateArray = (function(){
44
- var extras = {
45
- get: function(i){
46
- return this.slice(i)[0];
47
- },
48
- contains: function(d){
49
- // Array.indexOf is not cross-browser;
50
- // $.inArray doesn't work with Dates
51
- var val = d && d.valueOf();
52
- for (var i=0, l=this.length; i < l; i++)
53
- // Use date arithmetic to allow dates with different times to match
54
- if (0 <= this[i].valueOf() - val && this[i].valueOf() - val < 1000*60*60*24)
55
- return i;
56
- return -1;
57
- },
58
- remove: function(i){
59
- this.splice(i,1);
60
- },
61
- replace: function(new_array){
62
- if (!new_array)
63
- return;
64
- if (!$.isArray(new_array))
65
- new_array = [new_array];
66
- this.clear();
67
- this.push.apply(this, new_array);
68
- },
69
- clear: function(){
70
- this.length = 0;
71
- },
72
- copy: function(){
73
- var a = new DateArray();
74
- a.replace(this);
75
- return a;
76
- }
77
- };
78
-
79
- return function(){
80
- var a = [];
81
- a.push.apply(a, arguments);
82
- $.extend(a, extras);
83
- return a;
84
- };
85
- })();
86
-
87
-
88
- // Picker object
89
-
90
- var Datepicker = function(element, options){
91
- $.data(element, 'datepicker', this);
92
- this._process_options(options);
93
-
94
- this.dates = new DateArray();
95
- this.viewDate = this.o.defaultViewDate;
96
- this.focusDate = null;
97
-
98
- this.element = $(element);
99
- this.isInput = this.element.is('input');
100
- this.inputField = this.isInput ? this.element : this.element.find('input');
101
- this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
102
- if (this.component && this.component.length === 0)
103
- this.component = false;
104
- this.isInline = !this.component && this.element.is('div');
105
-
106
- this.picker = $(DPGlobal.template);
107
-
108
- // Checking templates and inserting
109
- if (this._check_template(this.o.templates.leftArrow)) {
110
- this.picker.find('.prev').html(this.o.templates.leftArrow);
111
- }
112
-
113
- if (this._check_template(this.o.templates.rightArrow)) {
114
- this.picker.find('.next').html(this.o.templates.rightArrow);
115
- }
116
-
117
- this._buildEvents();
118
- this._attachEvents();
119
-
120
- if (this.isInline){
121
- this.picker.addClass('datepicker-inline').appendTo(this.element);
122
- }
123
- else {
124
- this.picker.addClass('datepicker-dropdown dropdown-menu');
125
- }
126
-
127
- if (this.o.rtl){
128
- this.picker.addClass('datepicker-rtl');
129
- }
130
-
131
- if (this.o.calendarWeeks) {
132
- this.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear')
133
- .attr('colspan', function(i, val){
134
- return Number(val) + 1;
135
- });
136
- }
137
-
138
- this._process_options({
139
- startDate: this._o.startDate,
140
- endDate: this._o.endDate,
141
- daysOfWeekDisabled: this.o.daysOfWeekDisabled,
142
- daysOfWeekHighlighted: this.o.daysOfWeekHighlighted,
143
- datesDisabled: this.o.datesDisabled
144
- });
145
-
146
- this._allow_update = false;
147
- this.setViewMode(this.o.startView);
148
- this._allow_update = true;
149
-
150
- this.fillDow();
151
- this.fillMonths();
152
-
153
- this.update();
154
-
155
- if (this.isInline){
156
- this.show();
157
- }
158
- };
159
-
160
- Datepicker.prototype = {
161
- constructor: Datepicker,
162
-
163
- _resolveViewName: function(view){
164
- $.each(DPGlobal.viewModes, function(i, viewMode){
165
- if (view === i || $.inArray(view, viewMode.names) !== -1){
166
- view = i;
167
- return false;
168
- }
169
- });
170
-
171
- return view;
172
- },
173
-
174
- _resolveDaysOfWeek: function(daysOfWeek){
175
- if (!$.isArray(daysOfWeek))
176
- daysOfWeek = daysOfWeek.split(/[,\s]*/);
177
- return $.map(daysOfWeek, Number);
178
- },
179
-
180
- _check_template: function(tmp){
181
- try {
182
- // If empty
183
- if (tmp === undefined || tmp === "") {
184
- return false;
185
- }
186
- // If no html, everything ok
187
- if ((tmp.match(/[<>]/g) || []).length <= 0) {
188
- return true;
189
- }
190
- // Checking if html is fine
191
- var jDom = $(tmp);
192
- return jDom.length > 0;
193
- }
194
- catch (ex) {
195
- return false;
196
- }
197
- },
198
-
199
- _process_options: function(opts){
200
- // Store raw options for reference
201
- this._o = $.extend({}, this._o, opts);
202
- // Processed options
203
- var o = this.o = $.extend({}, this._o);
204
-
205
- // Check if "de-DE" style date is available, if not language should
206
- // fallback to 2 letter code eg "de"
207
- var lang = o.language;
208
- if (!dates[lang]){
209
- lang = lang.split('-')[0];
210
- if (!dates[lang])
211
- lang = defaults.language;
212
- }
213
- o.language = lang;
214
-
215
- // Retrieve view index from any aliases
216
- o.startView = this._resolveViewName(o.startView);
217
- o.minViewMode = this._resolveViewName(o.minViewMode);
218
- o.maxViewMode = this._resolveViewName(o.maxViewMode);
219
-
220
- // Check view is between min and max
221
- o.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView));
222
-
223
- // true, false, or Number > 0
224
- if (o.multidate !== true){
225
- o.multidate = Number(o.multidate) || false;
226
- if (o.multidate !== false)
227
- o.multidate = Math.max(0, o.multidate);
228
- }
229
- o.multidateSeparator = String(o.multidateSeparator);
230
-
231
- o.weekStart %= 7;
232
- o.weekEnd = (o.weekStart + 6) % 7;
233
-
234
- var format = DPGlobal.parseFormat(o.format);
235
- if (o.startDate !== -Infinity){
236
- if (!!o.startDate){
237
- if (o.startDate instanceof Date)
238
- o.startDate = this._local_to_utc(this._zero_time(o.startDate));
239
- else
240
- o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);
241
- }
242
- else {
243
- o.startDate = -Infinity;
244
- }
245
- }
246
- if (o.endDate !== Infinity){
247
- if (!!o.endDate){
248
- if (o.endDate instanceof Date)
249
- o.endDate = this._local_to_utc(this._zero_time(o.endDate));
250
- else
251
- o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);
252
- }
253
- else {
254
- o.endDate = Infinity;
255
- }
256
- }
257
-
258
- o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);
259
- o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
260
-
261
- o.datesDisabled = o.datesDisabled||[];
262
- if (!$.isArray(o.datesDisabled)) {
263
- o.datesDisabled = o.datesDisabled.split(',');
264
- }
265
- o.datesDisabled = $.map(o.datesDisabled, function(d){
266
- return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
267
- });
268
-
269
- var plc = String(o.orientation).toLowerCase().split(/\s+/g),
270
- _plc = o.orientation.toLowerCase();
271
- plc = $.grep(plc, function(word){
272
- return /^auto|left|right|top|bottom$/.test(word);
273
- });
274
- o.orientation = {x: 'auto', y: 'auto'};
275
- if (!_plc || _plc === 'auto')
276
- ; // no action
277
- else if (plc.length === 1){
278
- switch (plc[0]){
279
- case 'top':
280
- case 'bottom':
281
- o.orientation.y = plc[0];
282
- break;
283
- case 'left':
284
- case 'right':
285
- o.orientation.x = plc[0];
286
- break;
287
- }
288
- }
289
- else {
290
- _plc = $.grep(plc, function(word){
291
- return /^left|right$/.test(word);
292
- });
293
- o.orientation.x = _plc[0] || 'auto';
294
-
295
- _plc = $.grep(plc, function(word){
296
- return /^top|bottom$/.test(word);
297
- });
298
- o.orientation.y = _plc[0] || 'auto';
299
- }
300
- if (o.defaultViewDate instanceof Date || typeof o.defaultViewDate === 'string') {
301
- o.defaultViewDate = DPGlobal.parseDate(o.defaultViewDate, format, o.language, o.assumeNearbyYear);
302
- } else if (o.defaultViewDate) {
303
- var year = o.defaultViewDate.year || new Date().getFullYear();
304
- var month = o.defaultViewDate.month || 0;
305
- var day = o.defaultViewDate.day || 1;
306
- o.defaultViewDate = UTCDate(year, month, day);
307
- } else {
308
- o.defaultViewDate = UTCToday();
309
- }
310
- },
311
- _events: [],
312
- _secondaryEvents: [],
313
- _applyEvents: function(evs){
314
- for (var i=0, el, ch, ev; i < evs.length; i++){
315
- el = evs[i][0];
316
- if (evs[i].length === 2){
317
- ch = undefined;
318
- ev = evs[i][1];
319
- } else if (evs[i].length === 3){
320
- ch = evs[i][1];
321
- ev = evs[i][2];
322
- }
323
- el.on(ev, ch);
324
- }
325
- },
326
- _unapplyEvents: function(evs){
327
- for (var i=0, el, ev, ch; i < evs.length; i++){
328
- el = evs[i][0];
329
- if (evs[i].length === 2){
330
- ch = undefined;
331
- ev = evs[i][1];
332
- } else if (evs[i].length === 3){
333
- ch = evs[i][1];
334
- ev = evs[i][2];
335
- }
336
- el.off(ev, ch);
337
- }
338
- },
339
- _buildEvents: function(){
340
- var events = {
341
- keyup: $.proxy(function(e){
342
- if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
343
- this.update();
344
- }, this),
345
- keydown: $.proxy(this.keydown, this),
346
- paste: $.proxy(this.paste, this)
347
- };
348
-
349
- if (this.o.showOnFocus === true) {
350
- events.focus = $.proxy(this.show, this);
351
- }
352
-
353
- if (this.isInput) { // single input
354
- this._events = [
355
- [this.element, events]
356
- ];
357
- }
358
- // component: input + button
359
- else if (this.component && this.inputField.length) {
360
- this._events = [
361
- // For components that are not readonly, allow keyboard nav
362
- [this.inputField, events],
363
- [this.component, {
364
- click: $.proxy(this.show, this)
365
- }]
366
- ];
367
- }
368
- else {
369
- this._events = [
370
- [this.element, {
371
- click: $.proxy(this.show, this),
372
- keydown: $.proxy(this.keydown, this)
373
- }]
374
- ];
375
- }
376
- this._events.push(
377
- // Component: listen for blur on element descendants
378
- [this.element, '*', {
379
- blur: $.proxy(function(e){
380
- this._focused_from = e.target;
381
- }, this)
382
- }],
383
- // Input: listen for blur on element
384
- [this.element, {
385
- blur: $.proxy(function(e){
386
- this._focused_from = e.target;
387
- }, this)
388
- }]
389
- );
390
-
391
- if (this.o.immediateUpdates) {
392
- // Trigger input updates immediately on changed year/month
393
- this._events.push([this.element, {
394
- 'changeYear changeMonth': $.proxy(function(e){
395
- this.update(e.date);
396
- }, this)
397
- }]);
398
- }
399
-
400
- this._secondaryEvents = [
401
- [this.picker, {
402
- click: $.proxy(this.click, this)
403
- }],
404
- [this.picker, '.prev, .next', {
405
- click: $.proxy(this.navArrowsClick, this)
406
- }],
407
- [this.picker, '.day:not(.disabled)', {
408
- click: $.proxy(this.dayCellClick, this)
409
- }],
410
- [$(window), {
411
- resize: $.proxy(this.place, this)
412
- }],
413
- [$(document), {
414
- 'mousedown touchstart': $.proxy(function(e){
415
- // Clicked outside the datepicker, hide it
416
- if (!(
417
- this.element.is(e.target) ||
418
- this.element.find(e.target).length ||
419
- this.picker.is(e.target) ||
420
- this.picker.find(e.target).length ||
421
- this.isInline
422
- )){
423
- this.hide();
424
- }
425
- }, this)
426
- }]
427
- ];
428
- },
429
- _attachEvents: function(){
430
- this._detachEvents();
431
- this._applyEvents(this._events);
432
- },
433
- _detachEvents: function(){
434
- this._unapplyEvents(this._events);
435
- },
436
- _attachSecondaryEvents: function(){
437
- this._detachSecondaryEvents();
438
- this._applyEvents(this._secondaryEvents);
439
- },
440
- _detachSecondaryEvents: function(){
441
- this._unapplyEvents(this._secondaryEvents);
442
- },
443
- _trigger: function(event, altdate){
444
- var date = altdate || this.dates.get(-1),
445
- local_date = this._utc_to_local(date);
446
-
447
- this.element.trigger({
448
- type: event,
449
- date: local_date,
450
- viewMode: this.viewMode,
451
- dates: $.map(this.dates, this._utc_to_local),
452
- format: $.proxy(function(ix, format){
453
- if (arguments.length === 0){
454
- ix = this.dates.length - 1;
455
- format = this.o.format;
456
- } else if (typeof ix === 'string'){
457
- format = ix;
458
- ix = this.dates.length - 1;
459
- }
460
- format = format || this.o.format;
461
- var date = this.dates.get(ix);
462
- return DPGlobal.formatDate(date, format, this.o.language);
463
- }, this)
464
- });
465
- },
466
-
467
- show: function(){
468
- if (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))
469
- return;
470
- if (!this.isInline)
471
- this.picker.appendTo(this.o.container);
472
- this.place();
473
- this.picker.show();
474
- this._attachSecondaryEvents();
475
- this._trigger('show');
476
- if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
477
- $(this.element).blur();
478
- }
479
- return this;
480
- },
481
-
482
- hide: function(){
483
- if (this.isInline || !this.picker.is(':visible'))
484
- return this;
485
- this.focusDate = null;
486
- this.picker.hide().detach();
487
- this._detachSecondaryEvents();
488
- this.setViewMode(this.o.startView);
489
-
490
- if (this.o.forceParse && this.inputField.val())
491
- this.setValue();
492
- this._trigger('hide');
493
- return this;
494
- },
495
-
496
- destroy: function(){
497
- this.hide();
498
- this._detachEvents();
499
- this._detachSecondaryEvents();
500
- this.picker.remove();
501
- delete this.element.data().datepicker;
502
- if (!this.isInput){
503
- delete this.element.data().date;
504
- }
505
- return this;
506
- },
507
-
508
- paste: function(e){
509
- var dateString;
510
- if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types
511
- && $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) {
512
- dateString = e.originalEvent.clipboardData.getData('text/plain');
513
- } else if (window.clipboardData) {
514
- dateString = window.clipboardData.getData('Text');
515
- } else {
516
- return;
517
- }
518
- this.setDate(dateString);
519
- this.update();
520
- e.preventDefault();
521
- },
522
-
523
- _utc_to_local: function(utc){
524
- if (!utc) {
525
- return utc;
526
- }
527
-
528
- var local = new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000));
529
-
530
- if (local.getTimezoneOffset() !== utc.getTimezoneOffset()) {
531
- local = new Date(utc.getTime() + (local.getTimezoneOffset() * 60000));
532
- }
533
-
534
- return local;
535
- },
536
- _local_to_utc: function(local){
537
- return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
538
- },
539
- _zero_time: function(local){
540
- return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
541
- },
542
- _zero_utc_time: function(utc){
543
- return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
544
- },
545
-
546
- getDates: function(){
547
- return $.map(this.dates, this._utc_to_local);
548
- },
549
-
550
- getUTCDates: function(){
551
- return $.map(this.dates, function(d){
552
- return new Date(d);
553
- });
554
- },
555
-
556
- getDate: function(){
557
- return this._utc_to_local(this.getUTCDate());
558
- },
559
-
560
- getUTCDate: function(){
561
- var selected_date = this.dates.get(-1);
562
- if (selected_date !== undefined) {
563
- return new Date(selected_date);
564
- } else {
565
- return null;
566
- }
567
- },
568
-
569
- clearDates: function(){
570
- this.inputField.val('');
571
- this.update();
572
- this._trigger('changeDate');
573
-
574
- if (this.o.autoclose) {
575
- this.hide();
576
- }
577
- },
578
-
579
- setDates: function(){
580
- var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
581
- this.update.apply(this, args);
582
- this._trigger('changeDate');
583
- this.setValue();
584
- return this;
585
- },
586
-
587
- setUTCDates: function(){
588
- var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
589
- this.setDates.apply(this, $.map(args, this._utc_to_local));
590
- return this;
591
- },
592
-
593
- setDate: alias('setDates'),
594
- setUTCDate: alias('setUTCDates'),
595
- remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'),
596
-
597
- setValue: function(){
598
- var formatted = this.getFormattedDate();
599
- this.inputField.val(formatted);
600
- return this;
601
- },
602
-
603
- getFormattedDate: function(format){
604
- if (format === undefined)
605
- format = this.o.format;
606
-
607
- var lang = this.o.language;
608
- return $.map(this.dates, function(d){
609
- return DPGlobal.formatDate(d, format, lang);
610
- }).join(this.o.multidateSeparator);
611
- },
612
-
613
- getStartDate: function(){
614
- return this.o.startDate;
615
- },
616
-
617
- setStartDate: function(startDate){
618
- this._process_options({startDate: startDate});
619
- this.update();
620
- this.updateNavArrows();
621
- return this;
622
- },
623
-
624
- getEndDate: function(){
625
- return this.o.endDate;
626
- },
627
-
628
- setEndDate: function(endDate){
629
- this._process_options({endDate: endDate});
630
- this.update();
631
- this.updateNavArrows();
632
- return this;
633
- },
634
-
635
- setDaysOfWeekDisabled: function(daysOfWeekDisabled){
636
- this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
637
- this.update();
638
- return this;
639
- },
640
-
641
- setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
642
- this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
643
- this.update();
644
- return this;
645
- },
646
-
647
- setDatesDisabled: function(datesDisabled){
648
- this._process_options({datesDisabled: datesDisabled});
649
- this.update();
650
- return this;
651
- },
652
-
653
- place: function(){
654
- if (this.isInline)
655
- return this;
656
- var calendarWidth = this.picker.outerWidth(),
657
- calendarHeight = this.picker.outerHeight(),
658
- visualPadding = 10,
659
- container = $(this.o.container),
660
- windowWidth = container.width(),
661
- scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
662
- appendOffset = container.offset();
663
-
664
- var parentsZindex = [0];
665
- this.element.parents().each(function(){
666
- var itemZIndex = $(this).css('z-index');
667
- if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex));
668
- });
669
- var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
670
- var offset = this.component ? this.component.parent().offset() : this.element.offset();
671
- var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
672
- var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
673
- var left = offset.left - appendOffset.left;
674
- var top = offset.top - appendOffset.top;
675
-
676
- if (this.o.container !== 'body') {
677
- top += scrollTop;
678
- }
679
-
680
- this.picker.removeClass(
681
- 'datepicker-orient-top datepicker-orient-bottom '+
682
- 'datepicker-orient-right datepicker-orient-left'
683
- );
684
-
685
- if (this.o.orientation.x !== 'auto'){
686
- this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
687
- if (this.o.orientation.x === 'right')
688
- left -= calendarWidth - width;
689
- }
690
- // auto x orientation is best-placement: if it crosses a window
691
- // edge, fudge it sideways
692
- else {
693
- if (offset.left < 0) {
694
- // component is outside the window on the left side. Move it into visible range
695
- this.picker.addClass('datepicker-orient-left');
696
- left -= offset.left - visualPadding;
697
- } else if (left + calendarWidth > windowWidth) {
698
- // the calendar passes the widow right edge. Align it to component right side
699
- this.picker.addClass('datepicker-orient-right');
700
- left += width - calendarWidth;
701
- } else {
702
- if (this.o.rtl) {
703
- // Default to right
704
- this.picker.addClass('datepicker-orient-right');
705
- } else {
706
- // Default to left
707
- this.picker.addClass('datepicker-orient-left');
708
- }
709
- }
710
- }
711
-
712
- // auto y orientation is best-situation: top or bottom, no fudging,
713
- // decision based on which shows more of the calendar
714
- var yorient = this.o.orientation.y,
715
- top_overflow;
716
- if (yorient === 'auto'){
717
- top_overflow = -scrollTop + top - calendarHeight;
718
- yorient = top_overflow < 0 ? 'bottom' : 'top';
719
- }
720
-
721
- this.picker.addClass('datepicker-orient-' + yorient);
722
- if (yorient === 'top')
723
- top -= calendarHeight + parseInt(this.picker.css('padding-top'));
724
- else
725
- top += height;
726
-
727
- if (this.o.rtl) {
728
- var right = windowWidth - (left + width);
729
- this.picker.css({
730
- top: top,
731
- right: right,
732
- zIndex: zIndex
733
- });
734
- } else {
735
- this.picker.css({
736
- top: top,
737
- left: left,
738
- zIndex: zIndex
739
- });
740
- }
741
- return this;
742
- },
743
-
744
- _allow_update: true,
745
- update: function(){
746
- if (!this._allow_update)
747
- return this;
748
-
749
- var oldDates = this.dates.copy(),
750
- dates = [],
751
- fromArgs = false;
752
- if (arguments.length){
753
- $.each(arguments, $.proxy(function(i, date){
754
- if (date instanceof Date)
755
- date = this._local_to_utc(date);
756
- dates.push(date);
757
- }, this));
758
- fromArgs = true;
759
- } else {
760
- dates = this.isInput
761
- ? this.element.val()
762
- : this.element.data('date') || this.inputField.val();
763
- if (dates && this.o.multidate)
764
- dates = dates.split(this.o.multidateSeparator);
765
- else
766
- dates = [dates];
767
- delete this.element.data().date;
768
- }
769
-
770
- dates = $.map(dates, $.proxy(function(date){
771
- return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);
772
- }, this));
773
- dates = $.grep(dates, $.proxy(function(date){
774
- return (
775
- !this.dateWithinRange(date) ||
776
- !date
777
- );
778
- }, this), true);
779
- this.dates.replace(dates);
780
-
781
- if (this.o.updateViewDate) {
782
- if (this.dates.length)
783
- this.viewDate = new Date(this.dates.get(-1));
784
- else if (this.viewDate < this.o.startDate)
785
- this.viewDate = new Date(this.o.startDate);
786
- else if (this.viewDate > this.o.endDate)
787
- this.viewDate = new Date(this.o.endDate);
788
- else
789
- this.viewDate = this.o.defaultViewDate;
790
- }
791
-
792
- if (fromArgs){
793
- // setting date by clicking
794
- this.setValue();
795
- this.element.change();
796
- }
797
- else if (this.dates.length){
798
- // setting date by typing
799
- if (String(oldDates) !== String(this.dates) && fromArgs) {
800
- this._trigger('changeDate');
801
- this.element.change();
802
- }
803
- }
804
- if (!this.dates.length && oldDates.length) {
805
- this._trigger('clearDate');
806
- this.element.change();
807
- }
808
-
809
- this.fill();
810
- return this;
811
- },
812
-
813
- fillDow: function(){
814
- if (this.o.showWeekDays) {
815
- var dowCnt = this.o.weekStart,
816
- html = '<tr>';
817
- if (this.o.calendarWeeks){
818
- html += '<th class="cw">&#160;</th>';
819
- }
820
- while (dowCnt < this.o.weekStart + 7){
821
- html += '<th class="dow';
822
- if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1)
823
- html += ' disabled';
824
- html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
825
- }
826
- html += '</tr>';
827
- this.picker.find('.datepicker-days thead').append(html);
828
- }
829
- },
830
-
831
- fillMonths: function(){
832
- var localDate = this._utc_to_local(this.viewDate);
833
- var html = '';
834
- var focused;
835
- for (var i = 0; i < 12; i++){
836
- focused = localDate && localDate.getMonth() === i ? ' focused' : '';
837
- html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i] + '</span>';
838
- }
839
- this.picker.find('.datepicker-months td').html(html);
840
- },
841
-
842
- setRange: function(range){
843
- if (!range || !range.length)
844
- delete this.range;
845
- else
846
- this.range = $.map(range, function(d){
847
- return d.valueOf();
848
- });
849
- this.fill();
850
- },
851
-
852
- getClassNames: function(date){
853
- var cls = [],
854
- year = this.viewDate.getUTCFullYear(),
855
- month = this.viewDate.getUTCMonth(),
856
- today = UTCToday();
857
- if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
858
- cls.push('old');
859
- } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
860
- cls.push('new');
861
- }
862
- if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
863
- cls.push('focused');
864
- // Compare internal UTC date with UTC today, not local today
865
- if (this.o.todayHighlight && isUTCEquals(date, today)) {
866
- cls.push('today');
867
- }
868
- if (this.dates.contains(date) !== -1)
869
- cls.push('active');
870
- if (!this.dateWithinRange(date)){
871
- cls.push('disabled');
872
- }
873
- if (this.dateIsDisabled(date)){
874
- cls.push('disabled', 'disabled-date');
875
- }
876
- if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
877
- cls.push('highlighted');
878
- }
879
-
880
- if (this.range){
881
- if (date > this.range[0] && date < this.range[this.range.length-1]){
882
- cls.push('range');
883
- }
884
- if ($.inArray(date.valueOf(), this.range) !== -1){
885
- cls.push('selected');
886
- }
887
- if (date.valueOf() === this.range[0]){
888
- cls.push('range-start');
889
- }
890
- if (date.valueOf() === this.range[this.range.length-1]){
891
- cls.push('range-end');
892
- }
893
- }
894
- return cls;
895
- },
896
-
897
- _fill_yearsView: function(selector, cssClass, factor, year, startYear, endYear, beforeFn){
898
- var html = '';
899
- var step = factor / 10;
900
- var view = this.picker.find(selector);
901
- var startVal = Math.floor(year / factor) * factor;
902
- var endVal = startVal + step * 9;
903
- var focusedVal = Math.floor(this.viewDate.getFullYear() / step) * step;
904
- var selected = $.map(this.dates, function(d){
905
- return Math.floor(d.getUTCFullYear() / step) * step;
906
- });
907
-
908
- var classes, tooltip, before;
909
- for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) {
910
- classes = [cssClass];
911
- tooltip = null;
912
-
913
- if (currVal === startVal - step) {
914
- classes.push('old');
915
- } else if (currVal === endVal + step) {
916
- classes.push('new');
917
- }
918
- if ($.inArray(currVal, selected) !== -1) {
919
- classes.push('active');
920
- }
921
- if (currVal < startYear || currVal > endYear) {
922
- classes.push('disabled');
923
- }
924
- if (currVal === focusedVal) {
925
- classes.push('focused');
926
- }
927
-
928
- if (beforeFn !== $.noop) {
929
- before = beforeFn(new Date(currVal, 0, 1));
930
- if (before === undefined) {
931
- before = {};
932
- } else if (typeof before === 'boolean') {
933
- before = {enabled: before};
934
- } else if (typeof before === 'string') {
935
- before = {classes: before};
936
- }
937
- if (before.enabled === false) {
938
- classes.push('disabled');
939
- }
940
- if (before.classes) {
941
- classes = classes.concat(before.classes.split(/\s+/));
942
- }
943
- if (before.tooltip) {
944
- tooltip = before.tooltip;
945
- }
946
- }
947
-
948
- html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + currVal + '</span>';
949
- }
950
-
951
- view.find('.datepicker-switch').text(startVal + '-' + endVal);
952
- view.find('td').html(html);
953
- },
954
-
955
- fill: function(){
956
- var d = new Date(this.viewDate),
957
- year = d.getUTCFullYear(),
958
- month = d.getUTCMonth(),
959
- startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
960
- startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
961
- endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
962
- endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
963
- todaytxt = dates[this.o.language].today || dates['en'].today || '',
964
- cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
965
- titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
966
- tooltip,
967
- before;
968
- if (isNaN(year) || isNaN(month))
969
- return;
970
- this.picker.find('.datepicker-days .datepicker-switch')
971
- .text(DPGlobal.formatDate(d, titleFormat, this.o.language));
972
- this.picker.find('tfoot .today')
973
- .text(todaytxt)
974
- .css('display', this.o.todayBtn === true || this.o.todayBtn === 'linked' ? 'table-cell' : 'none');
975
- this.picker.find('tfoot .clear')
976
- .text(cleartxt)
977
- .css('display', this.o.clearBtn === true ? 'table-cell' : 'none');
978
- this.picker.find('thead .datepicker-title')
979
- .text(this.o.title)
980
- .css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none');
981
- this.updateNavArrows();
982
- this.fillMonths();
983
- var prevMonth = UTCDate(year, month, 0),
984
- day = prevMonth.getUTCDate();
985
- prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
986
- var nextMonth = new Date(prevMonth);
987
- if (prevMonth.getUTCFullYear() < 100){
988
- nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
989
- }
990
- nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
991
- nextMonth = nextMonth.valueOf();
992
- var html = [];
993
- var weekDay, clsName;
994
- while (prevMonth.valueOf() < nextMonth){
995
- weekDay = prevMonth.getUTCDay();
996
- if (weekDay === this.o.weekStart){
997
- html.push('<tr>');
998
- if (this.o.calendarWeeks){
999
- // ISO 8601: First week contains first thursday.
1000
- // ISO also states week starts on Monday, but we can be more abstract here.
1001
- var
1002
- // Start of current week: based on weekstart/current date
1003
- ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
1004
- // Thursday of this week
1005
- th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
1006
- // First Thursday of year, year from thursday
1007
- yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
1008
- // Calendar week: ms between thursdays, div ms per day, div 7 days
1009
- calWeek = (th - yth) / 864e5 / 7 + 1;
1010
- html.push('<td class="cw">'+ calWeek +'</td>');
1011
- }
1012
- }
1013
- clsName = this.getClassNames(prevMonth);
1014
- clsName.push('day');
1015
-
1016
- var content = prevMonth.getUTCDate();
1017
-
1018
- if (this.o.beforeShowDay !== $.noop){
1019
- before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
1020
- if (before === undefined)
1021
- before = {};
1022
- else if (typeof before === 'boolean')
1023
- before = {enabled: before};
1024
- else if (typeof before === 'string')
1025
- before = {classes: before};
1026
- if (before.enabled === false)
1027
- clsName.push('disabled');
1028
- if (before.classes)
1029
- clsName = clsName.concat(before.classes.split(/\s+/));
1030
- if (before.tooltip)
1031
- tooltip = before.tooltip;
1032
- if (before.content)
1033
- content = before.content;
1034
- }
1035
-
1036
- //Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
1037
- //Fallback to unique function for older jquery versions
1038
- if ($.isFunction($.uniqueSort)) {
1039
- clsName = $.uniqueSort(clsName);
1040
- } else {
1041
- clsName = $.unique(clsName);
1042
- }
1043
-
1044
- html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + ' data-date="' + prevMonth.getTime().toString() + '">' + content + '</td>');
1045
- tooltip = null;
1046
- if (weekDay === this.o.weekEnd){
1047
- html.push('</tr>');
1048
- }
1049
- prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
1050
- }
1051
- this.picker.find('.datepicker-days tbody').html(html.join(''));
1052
-
1053
- var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
1054
- var months = this.picker.find('.datepicker-months')
1055
- .find('.datepicker-switch')
1056
- .text(this.o.maxViewMode < 2 ? monthsTitle : year)
1057
- .end()
1058
- .find('tbody span').removeClass('active');
1059
-
1060
- $.each(this.dates, function(i, d){
1061
- if (d.getUTCFullYear() === year)
1062
- months.eq(d.getUTCMonth()).addClass('active');
1063
- });
1064
-
1065
- if (year < startYear || year > endYear){
1066
- months.addClass('disabled');
1067
- }
1068
- if (year === startYear){
1069
- months.slice(0, startMonth).addClass('disabled');
1070
- }
1071
- if (year === endYear){
1072
- months.slice(endMonth+1).addClass('disabled');
1073
- }
1074
-
1075
- if (this.o.beforeShowMonth !== $.noop){
1076
- var that = this;
1077
- $.each(months, function(i, month){
1078
- var moDate = new Date(year, i, 1);
1079
- var before = that.o.beforeShowMonth(moDate);
1080
- if (before === undefined)
1081
- before = {};
1082
- else if (typeof before === 'boolean')
1083
- before = {enabled: before};
1084
- else if (typeof before === 'string')
1085
- before = {classes: before};
1086
- if (before.enabled === false && !$(month).hasClass('disabled'))
1087
- $(month).addClass('disabled');
1088
- if (before.classes)
1089
- $(month).addClass(before.classes);
1090
- if (before.tooltip)
1091
- $(month).prop('title', before.tooltip);
1092
- });
1093
- }
1094
-
1095
- // Generating decade/years picker
1096
- this._fill_yearsView(
1097
- '.datepicker-years',
1098
- 'year',
1099
- 10,
1100
- year,
1101
- startYear,
1102
- endYear,
1103
- this.o.beforeShowYear
1104
- );
1105
-
1106
- // Generating century/decades picker
1107
- this._fill_yearsView(
1108
- '.datepicker-decades',
1109
- 'decade',
1110
- 100,
1111
- year,
1112
- startYear,
1113
- endYear,
1114
- this.o.beforeShowDecade
1115
- );
1116
-
1117
- // Generating millennium/centuries picker
1118
- this._fill_yearsView(
1119
- '.datepicker-centuries',
1120
- 'century',
1121
- 1000,
1122
- year,
1123
- startYear,
1124
- endYear,
1125
- this.o.beforeShowCentury
1126
- );
1127
- },
1128
-
1129
- updateNavArrows: function(){
1130
- if (!this._allow_update)
1131
- return;
1132
-
1133
- var d = new Date(this.viewDate),
1134
- year = d.getUTCFullYear(),
1135
- month = d.getUTCMonth(),
1136
- startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
1137
- startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
1138
- endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
1139
- endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
1140
- prevIsDisabled,
1141
- nextIsDisabled,
1142
- factor = 1;
1143
- switch (this.viewMode){
1144
- case 4:
1145
- factor *= 10;
1146
- /* falls through */
1147
- case 3:
1148
- factor *= 10;
1149
- /* falls through */
1150
- case 2:
1151
- factor *= 10;
1152
- /* falls through */
1153
- case 1:
1154
- prevIsDisabled = Math.floor(year / factor) * factor < startYear;
1155
- nextIsDisabled = Math.floor(year / factor) * factor + factor > endYear;
1156
- break;
1157
- case 0:
1158
- prevIsDisabled = year <= startYear && month < startMonth;
1159
- nextIsDisabled = year >= endYear && month > endMonth;
1160
- break;
1161
- }
1162
-
1163
- this.picker.find('.prev').toggleClass('disabled', prevIsDisabled);
1164
- this.picker.find('.next').toggleClass('disabled', nextIsDisabled);
1165
- },
1166
-
1167
- click: function(e){
1168
- e.preventDefault();
1169
- e.stopPropagation();
1170
-
1171
- var target, dir, day, year, month;
1172
- target = $(e.target);
1173
-
1174
- // Clicked on the switch
1175
- if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){
1176
- this.setViewMode(this.viewMode + 1);
1177
- }
1178
-
1179
- // Clicked on today button
1180
- if (target.hasClass('today') && !target.hasClass('day')){
1181
- this.setViewMode(0);
1182
- this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
1183
- }
1184
-
1185
- // Clicked on clear button
1186
- if (target.hasClass('clear')){
1187
- this.clearDates();
1188
- }
1189
-
1190
- if (!target.hasClass('disabled')){
1191
- // Clicked on a month, year, decade, century
1192
- if (target.hasClass('month')
1193
- || target.hasClass('year')
1194
- || target.hasClass('decade')
1195
- || target.hasClass('century')) {
1196
- this.viewDate.setUTCDate(1);
1197
-
1198
- day = 1;
1199
- if (this.viewMode === 1){
1200
- month = target.parent().find('span').index(target);
1201
- year = this.viewDate.getUTCFullYear();
1202
- this.viewDate.setUTCMonth(month);
1203
- } else {
1204
- month = 0;
1205
- year = Number(target.text());
1206
- this.viewDate.setUTCFullYear(year);
1207
- }
1208
-
1209
- this._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate);
1210
-
1211
- if (this.viewMode === this.o.minViewMode){
1212
- this._setDate(UTCDate(year, month, day));
1213
- } else {
1214
- this.setViewMode(this.viewMode - 1);
1215
- this.fill();
1216
- }
1217
- }
1218
- }
1219
-
1220
- if (this.picker.is(':visible') && this._focused_from){
1221
- this._focused_from.focus();
1222
- }
1223
- delete this._focused_from;
1224
- },
1225
-
1226
- dayCellClick: function(e){
1227
- var $target = $(e.currentTarget);
1228
- var timestamp = $target.data('date');
1229
- var date = new Date(timestamp);
1230
-
1231
- if (this.o.updateViewDate) {
1232
- if (date.getUTCFullYear() !== this.viewDate.getUTCFullYear()) {
1233
- this._trigger('changeYear', this.viewDate);
1234
- }
1235
-
1236
- if (date.getUTCMonth() !== this.viewDate.getUTCMonth()) {
1237
- this._trigger('changeMonth', this.viewDate);
1238
- }
1239
- }
1240
- this._setDate(date);
1241
- },
1242
-
1243
- // Clicked on prev or next
1244
- navArrowsClick: function(e){
1245
- var $target = $(e.currentTarget);
1246
- var dir = $target.hasClass('prev') ? -1 : 1;
1247
- if (this.viewMode !== 0){
1248
- dir *= DPGlobal.viewModes[this.viewMode].navStep * 12;
1249
- }
1250
- this.viewDate = this.moveMonth(this.viewDate, dir);
1251
- this._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate);
1252
- this.fill();
1253
- },
1254
-
1255
- _toggle_multidate: function(date){
1256
- var ix = this.dates.contains(date);
1257
- if (!date){
1258
- this.dates.clear();
1259
- }
1260
-
1261
- if (ix !== -1){
1262
- if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
1263
- this.dates.remove(ix);
1264
- }
1265
- } else if (this.o.multidate === false) {
1266
- this.dates.clear();
1267
- this.dates.push(date);
1268
- }
1269
- else {
1270
- this.dates.push(date);
1271
- }
1272
-
1273
- if (typeof this.o.multidate === 'number')
1274
- while (this.dates.length > this.o.multidate)
1275
- this.dates.remove(0);
1276
- },
1277
-
1278
- _setDate: function(date, which){
1279
- if (!which || which === 'date')
1280
- this._toggle_multidate(date && new Date(date));
1281
- if ((!which && this.o.updateViewDate) || which === 'view')
1282
- this.viewDate = date && new Date(date);
1283
-
1284
- this.fill();
1285
- this.setValue();
1286
- if (!which || which !== 'view') {
1287
- this._trigger('changeDate');
1288
- }
1289
- this.inputField.trigger('change');
1290
- if (this.o.autoclose && (!which || which === 'date')){
1291
- this.hide();
1292
- }
1293
- },
1294
-
1295
- moveDay: function(date, dir){
1296
- var newDate = new Date(date);
1297
- newDate.setUTCDate(date.getUTCDate() + dir);
1298
-
1299
- return newDate;
1300
- },
1301
-
1302
- moveWeek: function(date, dir){
1303
- return this.moveDay(date, dir * 7);
1304
- },
1305
-
1306
- moveMonth: function(date, dir){
1307
- if (!isValidDate(date))
1308
- return this.o.defaultViewDate;
1309
- if (!dir)
1310
- return date;
1311
- var new_date = new Date(date.valueOf()),
1312
- day = new_date.getUTCDate(),
1313
- month = new_date.getUTCMonth(),
1314
- mag = Math.abs(dir),
1315
- new_month, test;
1316
- dir = dir > 0 ? 1 : -1;
1317
- if (mag === 1){
1318
- test = dir === -1
1319
- // If going back one month, make sure month is not current month
1320
- // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
1321
- ? function(){
1322
- return new_date.getUTCMonth() === month;
1323
- }
1324
- // If going forward one month, make sure month is as expected
1325
- // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
1326
- : function(){
1327
- return new_date.getUTCMonth() !== new_month;
1328
- };
1329
- new_month = month + dir;
1330
- new_date.setUTCMonth(new_month);
1331
- // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1332
- new_month = (new_month + 12) % 12;
1333
- }
1334
- else {
1335
- // For magnitudes >1, move one month at a time...
1336
- for (var i=0; i < mag; i++)
1337
- // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
1338
- new_date = this.moveMonth(new_date, dir);
1339
- // ...then reset the day, keeping it in the new month
1340
- new_month = new_date.getUTCMonth();
1341
- new_date.setUTCDate(day);
1342
- test = function(){
1343
- return new_month !== new_date.getUTCMonth();
1344
- };
1345
- }
1346
- // Common date-resetting loop -- if date is beyond end of month, make it
1347
- // end of month
1348
- while (test()){
1349
- new_date.setUTCDate(--day);
1350
- new_date.setUTCMonth(new_month);
1351
- }
1352
- return new_date;
1353
- },
1354
-
1355
- moveYear: function(date, dir){
1356
- return this.moveMonth(date, dir*12);
1357
- },
1358
-
1359
- moveAvailableDate: function(date, dir, fn){
1360
- do {
1361
- date = this[fn](date, dir);
1362
-
1363
- if (!this.dateWithinRange(date))
1364
- return false;
1365
-
1366
- fn = 'moveDay';
1367
- }
1368
- while (this.dateIsDisabled(date));
1369
-
1370
- return date;
1371
- },
1372
-
1373
- weekOfDateIsDisabled: function(date){
1374
- return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
1375
- },
1376
-
1377
- dateIsDisabled: function(date){
1378
- return (
1379
- this.weekOfDateIsDisabled(date) ||
1380
- $.grep(this.o.datesDisabled, function(d){
1381
- return isUTCEquals(date, d);
1382
- }).length > 0
1383
- );
1384
- },
1385
-
1386
- dateWithinRange: function(date){
1387
- return date >= this.o.startDate && date <= this.o.endDate;
1388
- },
1389
-
1390
- keydown: function(e){
1391
- if (!this.picker.is(':visible')){
1392
- if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
1393
- this.show();
1394
- e.stopPropagation();
1395
- }
1396
- return;
1397
- }
1398
- var dateChanged = false,
1399
- dir, newViewDate,
1400
- focusDate = this.focusDate || this.viewDate;
1401
- switch (e.keyCode){
1402
- case 27: // escape
1403
- if (this.focusDate){
1404
- this.focusDate = null;
1405
- this.viewDate = this.dates.get(-1) || this.viewDate;
1406
- this.fill();
1407
- }
1408
- else
1409
- this.hide();
1410
- e.preventDefault();
1411
- e.stopPropagation();
1412
- break;
1413
- case 37: // left
1414
- case 38: // up
1415
- case 39: // right
1416
- case 40: // down
1417
- if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)
1418
- break;
1419
- dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
1420
- if (this.viewMode === 0) {
1421
- if (e.ctrlKey){
1422
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1423
-
1424
- if (newViewDate)
1425
- this._trigger('changeYear', this.viewDate);
1426
- } else if (e.shiftKey){
1427
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1428
-
1429
- if (newViewDate)
1430
- this._trigger('changeMonth', this.viewDate);
1431
- } else if (e.keyCode === 37 || e.keyCode === 39){
1432
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1433
- } else if (!this.weekOfDateIsDisabled(focusDate)){
1434
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1435
- }
1436
- } else if (this.viewMode === 1) {
1437
- if (e.keyCode === 38 || e.keyCode === 40) {
1438
- dir = dir * 4;
1439
- }
1440
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1441
- } else if (this.viewMode === 2) {
1442
- if (e.keyCode === 38 || e.keyCode === 40) {
1443
- dir = dir * 4;
1444
- }
1445
- newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1446
- }
1447
- if (newViewDate){
1448
- this.focusDate = this.viewDate = newViewDate;
1449
- this.setValue();
1450
- this.fill();
1451
- e.preventDefault();
1452
- }
1453
- break;
1454
- case 13: // enter
1455
- if (!this.o.forceParse)
1456
- break;
1457
- focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
1458
- if (this.o.keyboardNavigation) {
1459
- this._toggle_multidate(focusDate);
1460
- dateChanged = true;
1461
- }
1462
- this.focusDate = null;
1463
- this.viewDate = this.dates.get(-1) || this.viewDate;
1464
- this.setValue();
1465
- this.fill();
1466
- if (this.picker.is(':visible')){
1467
- e.preventDefault();
1468
- e.stopPropagation();
1469
- if (this.o.autoclose)
1470
- this.hide();
1471
- }
1472
- break;
1473
- case 9: // tab
1474
- this.focusDate = null;
1475
- this.viewDate = this.dates.get(-1) || this.viewDate;
1476
- this.fill();
1477
- this.hide();
1478
- break;
1479
- }
1480
- if (dateChanged){
1481
- if (this.dates.length)
1482
- this._trigger('changeDate');
1483
- else
1484
- this._trigger('clearDate');
1485
- this.inputField.trigger('change');
1486
- }
1487
- },
1488
-
1489
- setViewMode: function(viewMode){
1490
- this.viewMode = viewMode;
1491
- this.picker
1492
- .children('div')
1493
- .hide()
1494
- .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)
1495
- .show();
1496
- this.updateNavArrows();
1497
- this._trigger('changeViewMode', new Date(this.viewDate));
1498
- }
1499
- };
1500
-
1501
- var DateRangePicker = function(element, options){
1502
- $.data(element, 'datepicker', this);
1503
- this.element = $(element);
1504
- this.inputs = $.map(options.inputs, function(i){
1505
- return i.jquery ? i[0] : i;
1506
- });
1507
- delete options.inputs;
1508
-
1509
- this.keepEmptyValues = options.keepEmptyValues;
1510
- delete options.keepEmptyValues;
1511
-
1512
- datepickerPlugin.call($(this.inputs), options)
1513
- .on('changeDate', $.proxy(this.dateUpdated, this));
1514
-
1515
- this.pickers = $.map(this.inputs, function(i){
1516
- return $.data(i, 'datepicker');
1517
- });
1518
- this.updateDates();
1519
- };
1520
- DateRangePicker.prototype = {
1521
- updateDates: function(){
1522
- this.dates = $.map(this.pickers, function(i){
1523
- return i.getUTCDate();
1524
- });
1525
- this.updateRanges();
1526
- },
1527
- updateRanges: function(){
1528
- var range = $.map(this.dates, function(d){
1529
- return d.valueOf();
1530
- });
1531
- $.each(this.pickers, function(i, p){
1532
- p.setRange(range);
1533
- });
1534
- },
1535
- clearDates: function(){
1536
- $.each(this.pickers, function(i, p){
1537
- p.clearDates();
1538
- });
1539
- },
1540
- dateUpdated: function(e){
1541
- // `this.updating` is a workaround for preventing infinite recursion
1542
- // between `changeDate` triggering and `setUTCDate` calling. Until
1543
- // there is a better mechanism.
1544
- if (this.updating)
1545
- return;
1546
- this.updating = true;
1547
-
1548
- var dp = $.data(e.target, 'datepicker');
1549
-
1550
- if (dp === undefined) {
1551
- return;
1552
- }
1553
-
1554
- var new_date = dp.getUTCDate(),
1555
- keep_empty_values = this.keepEmptyValues,
1556
- i = $.inArray(e.target, this.inputs),
1557
- j = i - 1,
1558
- k = i + 1,
1559
- l = this.inputs.length;
1560
- if (i === -1)
1561
- return;
1562
-
1563
- $.each(this.pickers, function(i, p){
1564
- if (!p.getUTCDate() && (p === dp || !keep_empty_values))
1565
- p.setUTCDate(new_date);
1566
- });
1567
-
1568
- if (new_date < this.dates[j]){
1569
- // Date being moved earlier/left
1570
- while (j >= 0 && new_date < this.dates[j]){
1571
- this.pickers[j--].setUTCDate(new_date);
1572
- }
1573
- } else if (new_date > this.dates[k]){
1574
- // Date being moved later/right
1575
- while (k < l && new_date > this.dates[k]){
1576
- this.pickers[k++].setUTCDate(new_date);
1577
- }
1578
- }
1579
- this.updateDates();
1580
-
1581
- delete this.updating;
1582
- },
1583
- destroy: function(){
1584
- $.map(this.pickers, function(p){ p.destroy(); });
1585
- $(this.inputs).off('changeDate', this.dateUpdated);
1586
- delete this.element.data().datepicker;
1587
- },
1588
- remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead')
1589
- };
1590
-
1591
- function opts_from_el(el, prefix){
1592
- // Derive options from element data-attrs
1593
- var data = $(el).data(),
1594
- out = {}, inkey,
1595
- replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
1596
- prefix = new RegExp('^' + prefix.toLowerCase());
1597
- function re_lower(_,a){
1598
- return a.toLowerCase();
1599
- }
1600
- for (var key in data)
1601
- if (prefix.test(key)){
1602
- inkey = key.replace(replace, re_lower);
1603
- out[inkey] = data[key];
1604
- }
1605
- return out;
1606
- }
1607
-
1608
- function opts_from_locale(lang){
1609
- // Derive options from locale plugins
1610
- var out = {};
1611
- // Check if "de-DE" style date is available, if not language should
1612
- // fallback to 2 letter code eg "de"
1613
- if (!dates[lang]){
1614
- lang = lang.split('-')[0];
1615
- if (!dates[lang])
1616
- return;
1617
- }
1618
- var d = dates[lang];
1619
- $.each(locale_opts, function(i,k){
1620
- if (k in d)
1621
- out[k] = d[k];
1622
- });
1623
- return out;
1624
- }
1625
-
1626
- var old = $.fn.datepicker;
1627
- var datepickerPlugin = function(option){
1628
- var args = Array.apply(null, arguments);
1629
- args.shift();
1630
- var internal_return;
1631
- this.each(function(){
1632
- var $this = $(this),
1633
- data = $this.data('datepicker'),
1634
- options = typeof option === 'object' && option;
1635
- if (!data){
1636
- var elopts = opts_from_el(this, 'date'),
1637
- // Preliminary otions
1638
- xopts = $.extend({}, defaults, elopts, options),
1639
- locopts = opts_from_locale(xopts.language),
1640
- // Options priority: js args, data-attrs, locales, defaults
1641
- opts = $.extend({}, defaults, locopts, elopts, options);
1642
- if ($this.hasClass('input-daterange') || opts.inputs){
1643
- $.extend(opts, {
1644
- inputs: opts.inputs || $this.find('input').toArray()
1645
- });
1646
- data = new DateRangePicker(this, opts);
1647
- }
1648
- else {
1649
- data = new Datepicker(this, opts);
1650
- }
1651
- $this.data('datepicker', data);
1652
- }
1653
- if (typeof option === 'string' && typeof data[option] === 'function'){
1654
- internal_return = data[option].apply(data, args);
1655
- }
1656
- });
1657
-
1658
- if (
1659
- internal_return === undefined ||
1660
- internal_return instanceof Datepicker ||
1661
- internal_return instanceof DateRangePicker
1662
- )
1663
- return this;
1664
-
1665
- if (this.length > 1)
1666
- throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
1667
- else
1668
- return internal_return;
1669
- };
1670
- $.fn.datepicker = datepickerPlugin;
1671
-
1672
- var defaults = $.fn.datepicker.defaults = {
1673
- assumeNearbyYear: false,
1674
- autoclose: false,
1675
- beforeShowDay: $.noop,
1676
- beforeShowMonth: $.noop,
1677
- beforeShowYear: $.noop,
1678
- beforeShowDecade: $.noop,
1679
- beforeShowCentury: $.noop,
1680
- calendarWeeks: false,
1681
- clearBtn: false,
1682
- toggleActive: false,
1683
- daysOfWeekDisabled: [],
1684
- daysOfWeekHighlighted: [],
1685
- datesDisabled: [],
1686
- endDate: Infinity,
1687
- forceParse: true,
1688
- format: 'mm/dd/yyyy',
1689
- keepEmptyValues: false,
1690
- keyboardNavigation: true,
1691
- language: 'en',
1692
- minViewMode: 0,
1693
- maxViewMode: 4,
1694
- multidate: false,
1695
- multidateSeparator: ',',
1696
- orientation: "auto",
1697
- rtl: false,
1698
- startDate: -Infinity,
1699
- startView: 0,
1700
- todayBtn: false,
1701
- todayHighlight: false,
1702
- updateViewDate: true,
1703
- weekStart: 0,
1704
- disableTouchKeyboard: false,
1705
- enableOnReadonly: true,
1706
- showOnFocus: true,
1707
- zIndexOffset: 10,
1708
- container: 'body',
1709
- immediateUpdates: false,
1710
- title: '',
1711
- templates: {
1712
- leftArrow: '&#x00AB;',
1713
- rightArrow: '&#x00BB;'
1714
- },
1715
- showWeekDays: true
1716
- };
1717
- var locale_opts = $.fn.datepicker.locale_opts = [
1718
- 'format',
1719
- 'rtl',
1720
- 'weekStart'
1721
- ];
1722
- $.fn.datepicker.Constructor = Datepicker;
1723
- var dates = $.fn.datepicker.dates = {
1724
- en: {
1725
- days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
1726
- daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
1727
- daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
1728
- months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1729
- monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1730
- today: "Today",
1731
- clear: "Clear",
1732
- titleFormat: "MM yyyy"
1733
- }
1734
- };
1735
-
1736
- var DPGlobal = {
1737
- viewModes: [
1738
- {
1739
- names: ['days', 'month'],
1740
- clsName: 'days',
1741
- e: 'changeMonth'
1742
- },
1743
- {
1744
- names: ['months', 'year'],
1745
- clsName: 'months',
1746
- e: 'changeYear',
1747
- navStep: 1
1748
- },
1749
- {
1750
- names: ['years', 'decade'],
1751
- clsName: 'years',
1752
- e: 'changeDecade',
1753
- navStep: 10
1754
- },
1755
- {
1756
- names: ['decades', 'century'],
1757
- clsName: 'decades',
1758
- e: 'changeCentury',
1759
- navStep: 100
1760
- },
1761
- {
1762
- names: ['centuries', 'millennium'],
1763
- clsName: 'centuries',
1764
- e: 'changeMillennium',
1765
- navStep: 1000
1766
- }
1767
- ],
1768
- validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1769
- nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
1770
- parseFormat: function(format){
1771
- if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
1772
- return format;
1773
- // IE treats \0 as a string end in inputs (truncating the value),
1774
- // so it's a bad format delimiter, anyway
1775
- var separators = format.replace(this.validParts, '\0').split('\0'),
1776
- parts = format.match(this.validParts);
1777
- if (!separators || !separators.length || !parts || parts.length === 0){
1778
- throw new Error("Invalid date format.");
1779
- }
1780
- return {separators: separators, parts: parts};
1781
- },
1782
- parseDate: function(date, format, language, assumeNearby){
1783
- if (!date)
1784
- return undefined;
1785
- if (date instanceof Date)
1786
- return date;
1787
- if (typeof format === 'string')
1788
- format = DPGlobal.parseFormat(format);
1789
- if (format.toValue)
1790
- return format.toValue(date, format, language);
1791
- var fn_map = {
1792
- d: 'moveDay',
1793
- m: 'moveMonth',
1794
- w: 'moveWeek',
1795
- y: 'moveYear'
1796
- },
1797
- dateAliases = {
1798
- yesterday: '-1d',
1799
- today: '+0d',
1800
- tomorrow: '+1d'
1801
- },
1802
- parts, part, dir, i, fn;
1803
- if (date in dateAliases){
1804
- date = dateAliases[date];
1805
- }
1806
- if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/i.test(date)){
1807
- parts = date.match(/([\-+]\d+)([dmwy])/gi);
1808
- date = new Date();
1809
- for (i=0; i < parts.length; i++){
1810
- part = parts[i].match(/([\-+]\d+)([dmwy])/i);
1811
- dir = Number(part[1]);
1812
- fn = fn_map[part[2].toLowerCase()];
1813
- date = Datepicker.prototype[fn](date, dir);
1814
- }
1815
- return Datepicker.prototype._zero_utc_time(date);
1816
- }
1817
-
1818
- parts = date && date.match(this.nonpunctuation) || [];
1819
-
1820
- function applyNearbyYear(year, threshold){
1821
- if (threshold === true)
1822
- threshold = 10;
1823
-
1824
- // if year is 2 digits or less, than the user most likely is trying to get a recent century
1825
- if (year < 100){
1826
- year += 2000;
1827
- // if the new year is more than threshold years in advance, use last century
1828
- if (year > ((new Date()).getFullYear()+threshold)){
1829
- year -= 100;
1830
- }
1831
- }
1832
-
1833
- return year;
1834
- }
1835
-
1836
- var parsed = {},
1837
- setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1838
- setters_map = {
1839
- yyyy: function(d,v){
1840
- return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1841
- },
1842
- m: function(d,v){
1843
- if (isNaN(d))
1844
- return d;
1845
- v -= 1;
1846
- while (v < 0) v += 12;
1847
- v %= 12;
1848
- d.setUTCMonth(v);
1849
- while (d.getUTCMonth() !== v)
1850
- d.setUTCDate(d.getUTCDate()-1);
1851
- return d;
1852
- },
1853
- d: function(d,v){
1854
- return d.setUTCDate(v);
1855
- }
1856
- },
1857
- val, filtered;
1858
- setters_map['yy'] = setters_map['yyyy'];
1859
- setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1860
- setters_map['dd'] = setters_map['d'];
1861
- date = UTCToday();
1862
- var fparts = format.parts.slice();
1863
- // Remove noop parts
1864
- if (parts.length !== fparts.length){
1865
- fparts = $(fparts).filter(function(i,p){
1866
- return $.inArray(p, setters_order) !== -1;
1867
- }).toArray();
1868
- }
1869
- // Process remainder
1870
- function match_part(){
1871
- var m = this.slice(0, parts[i].length),
1872
- p = parts[i].slice(0, m.length);
1873
- return m.toLowerCase() === p.toLowerCase();
1874
- }
1875
- if (parts.length === fparts.length){
1876
- var cnt;
1877
- for (i=0, cnt = fparts.length; i < cnt; i++){
1878
- val = parseInt(parts[i], 10);
1879
- part = fparts[i];
1880
- if (isNaN(val)){
1881
- switch (part){
1882
- case 'MM':
1883
- filtered = $(dates[language].months).filter(match_part);
1884
- val = $.inArray(filtered[0], dates[language].months) + 1;
1885
- break;
1886
- case 'M':
1887
- filtered = $(dates[language].monthsShort).filter(match_part);
1888
- val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1889
- break;
1890
- }
1891
- }
1892
- parsed[part] = val;
1893
- }
1894
- var _date, s;
1895
- for (i=0; i < setters_order.length; i++){
1896
- s = setters_order[i];
1897
- if (s in parsed && !isNaN(parsed[s])){
1898
- _date = new Date(date);
1899
- setters_map[s](_date, parsed[s]);
1900
- if (!isNaN(_date))
1901
- date = _date;
1902
- }
1903
- }
1904
- }
1905
- return date;
1906
- },
1907
- formatDate: function(date, format, language){
1908
- if (!date)
1909
- return '';
1910
- if (typeof format === 'string')
1911
- format = DPGlobal.parseFormat(format);
1912
- if (format.toDisplay)
1913
- return format.toDisplay(date, format, language);
1914
- var val = {
1915
- d: date.getUTCDate(),
1916
- D: dates[language].daysShort[date.getUTCDay()],
1917
- DD: dates[language].days[date.getUTCDay()],
1918
- m: date.getUTCMonth() + 1,
1919
- M: dates[language].monthsShort[date.getUTCMonth()],
1920
- MM: dates[language].months[date.getUTCMonth()],
1921
- yy: date.getUTCFullYear().toString().substring(2),
1922
- yyyy: date.getUTCFullYear()
1923
- };
1924
- val.dd = (val.d < 10 ? '0' : '') + val.d;
1925
- val.mm = (val.m < 10 ? '0' : '') + val.m;
1926
- date = [];
1927
- var seps = $.extend([], format.separators);
1928
- for (var i=0, cnt = format.parts.length; i <= cnt; i++){
1929
- if (seps.length)
1930
- date.push(seps.shift());
1931
- date.push(val[format.parts[i]]);
1932
- }
1933
- return date.join('');
1934
- },
1935
- headTemplate: '<thead>'+
1936
- '<tr>'+
1937
- '<th colspan="7" class="datepicker-title"></th>'+
1938
- '</tr>'+
1939
- '<tr>'+
1940
- '<th class="prev">'+defaults.templates.leftArrow+'</th>'+
1941
- '<th colspan="5" class="datepicker-switch"></th>'+
1942
- '<th class="next">'+defaults.templates.rightArrow+'</th>'+
1943
- '</tr>'+
1944
- '</thead>',
1945
- contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1946
- footTemplate: '<tfoot>'+
1947
- '<tr>'+
1948
- '<th colspan="7" class="today"></th>'+
1949
- '</tr>'+
1950
- '<tr>'+
1951
- '<th colspan="7" class="clear"></th>'+
1952
- '</tr>'+
1953
- '</tfoot>'
1954
- };
1955
- DPGlobal.template = '<div class="datepicker">'+
1956
- '<div class="datepicker-days">'+
1957
- '<table class="table-condensed">'+
1958
- DPGlobal.headTemplate+
1959
- '<tbody></tbody>'+
1960
- DPGlobal.footTemplate+
1961
- '</table>'+
1962
- '</div>'+
1963
- '<div class="datepicker-months">'+
1964
- '<table class="table-condensed">'+
1965
- DPGlobal.headTemplate+
1966
- DPGlobal.contTemplate+
1967
- DPGlobal.footTemplate+
1968
- '</table>'+
1969
- '</div>'+
1970
- '<div class="datepicker-years">'+
1971
- '<table class="table-condensed">'+
1972
- DPGlobal.headTemplate+
1973
- DPGlobal.contTemplate+
1974
- DPGlobal.footTemplate+
1975
- '</table>'+
1976
- '</div>'+
1977
- '<div class="datepicker-decades">'+
1978
- '<table class="table-condensed">'+
1979
- DPGlobal.headTemplate+
1980
- DPGlobal.contTemplate+
1981
- DPGlobal.footTemplate+
1982
- '</table>'+
1983
- '</div>'+
1984
- '<div class="datepicker-centuries">'+
1985
- '<table class="table-condensed">'+
1986
- DPGlobal.headTemplate+
1987
- DPGlobal.contTemplate+
1988
- DPGlobal.footTemplate+
1989
- '</table>'+
1990
- '</div>'+
1991
- '</div>';
1992
-
1993
- $.fn.datepicker.DPGlobal = DPGlobal;
1994
-
1995
-
1996
- /* DATEPICKER NO CONFLICT
1997
- * =================== */
1998
-
1999
- $.fn.datepicker.noConflict = function(){
2000
- $.fn.datepicker = old;
2001
- return this;
2002
- };
2003
-
2004
- /* DATEPICKER VERSION
2005
- * =================== */
2006
- $.fn.datepicker.version = '1.8.0';
2007
-
2008
- $.fn.datepicker.deprecated = function(msg){
2009
- var console = window.console;
2010
- if (console && console.warn) {
2011
- console.warn('DEPRECATED: ' + msg);
2012
- }
2013
- };
2014
-
2015
-
2016
- /* DATEPICKER DATA-API
2017
- * ================== */
2018
-
2019
- $(document).on(
2020
- 'focus.datepicker.data-api click.datepicker.data-api',
2021
- '[data-provide="datepicker"]',
2022
- function(e){
2023
- var $this = $(this);
2024
- if ($this.data('datepicker'))
2025
- return;
2026
- e.preventDefault();
2027
- // component click requires us to explicitly show it
2028
- datepickerPlugin.call($this, 'show');
2029
- }
2030
- );
2031
- $(function(){
2032
- datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
2033
- });
2034
-
2035
- }));