bitsnote-assets 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/daterangepicker/daterangepicker.js +1113 -0
  3. data/app/assets/stylesheets/daterangepicker/daterangepicker.css +284 -0
  4. data/lib/bitsnote-assets.rb +1 -24
  5. data/lib/bitsnote-assets/version.rb +1 -1
  6. metadata +4 -22
  7. data/app/assets/javascripts/pickadate/picker.date.js +0 -1349
  8. data/app/assets/javascripts/pickadate/picker.date.min.js +0 -5
  9. data/app/assets/javascripts/pickadate/picker.js +0 -1078
  10. data/app/assets/javascripts/pickadate/picker.min.js +0 -7
  11. data/app/assets/javascripts/pickadate/picker.time.js +0 -1014
  12. data/app/assets/javascripts/pickadate/picker.time.min.js +0 -5
  13. data/app/assets/stylesheets/pickadate/classic.css +0 -109
  14. data/app/assets/stylesheets/pickadate/classic.date.css +0 -301
  15. data/app/assets/stylesheets/pickadate/classic.date.min.css +0 -1
  16. data/app/assets/stylesheets/pickadate/classic.min.css +0 -4
  17. data/app/assets/stylesheets/pickadate/classic.time.css +0 -131
  18. data/app/assets/stylesheets/pickadate/classic.time.min.css +0 -1
  19. data/app/assets/stylesheets/pickadate/default.css +0 -175
  20. data/app/assets/stylesheets/pickadate/default.date.css +0 -301
  21. data/app/assets/stylesheets/pickadate/default.date.min.css +0 -1
  22. data/app/assets/stylesheets/pickadate/default.min.css +0 -4
  23. data/app/assets/stylesheets/pickadate/default.time.css +0 -125
  24. data/app/assets/stylesheets/pickadate/default.time.min.css +0 -1
  25. data/app/assets/stylesheets/pickadate/rtl.css +0 -29
  26. data/app/assets/stylesheets/pickadate/rtl.min.css +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a8e47c3f21a2dee68fa6f6c563851a79f832287
4
- data.tar.gz: da87e01b26d2ff9fe93afa509936bf2bf408cf72
3
+ metadata.gz: ac58000fbf2609485e6426f2edc280df9dff46e4
4
+ data.tar.gz: 1dd13764e81f86cb4c4415c4180ac94a348256c1
5
5
  SHA512:
6
- metadata.gz: fc6be01770abe01b4a329bf76ab7f99c82357a33963c135c5328f21b983f9c65b84bf305a66a96e5d68eb8e1ed87b5ab4ad302c308c8ba97e919c8c9a8788b82
7
- data.tar.gz: 663ebdea058b3586c592695ff02cc2b272b3054d9677da5694c7242acab6e47a7fdf267a854d9e6f5bd28c06b9ddf6877502fc146fbd830131a35bebbe681472
6
+ metadata.gz: c0908e55abb93cb62831600430cbc66ef9c19cb45c3d0606208571f08a4311f9c79428a083c0df0747775636dd9a642572b3f33eb640db6de4ef39bce4466755
7
+ data.tar.gz: cbf2eeb20fab8981ed8cdd1967f41cf3abc80d1cf0caa916794fd7f1b0ca15c7671810609278fa360f2ceb1031130b4d7a441d8c609f571ec6722763efdc14fe
@@ -0,0 +1,1113 @@
1
+ /**
2
+ * @version: 1.3.12
3
+ * @author: Dan Grossman http://www.dangrossman.info/
4
+ * @date: 2014-08-18
5
+ * @copyright: Copyright (c) 2012-2014 Dan Grossman. All rights reserved.
6
+ * @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0
7
+ * @website: http://www.improvely.com/
8
+ */
9
+
10
+ (function(root, factory) {
11
+
12
+ if (typeof define === 'function' && define.amd) {
13
+ define(['moment', 'jquery', 'exports'], function(momentjs, $, exports) {
14
+ root.daterangepicker = factory(root, exports, momentjs, $);
15
+ });
16
+
17
+ } else if (typeof exports !== 'undefined') {
18
+ var momentjs = require('moment');
19
+ var jQuery;
20
+ try {
21
+ jQuery = require('jquery');
22
+ } catch (err) {
23
+ jQuery = window.jQuery;
24
+ if (!jQuery) throw new Error('jQuery dependency not found');
25
+ }
26
+
27
+ factory(root, exports, momentjs, jQuery);
28
+
29
+ // Finally, as a browser global.
30
+ } else {
31
+ root.daterangepicker = factory(root, {}, root.moment, (root.jQuery || root.Zepto || root.ender || root.$));
32
+ }
33
+
34
+ }(this, function(root, daterangepicker, moment, $) {
35
+
36
+ var DateRangePicker = function (element, options, cb) {
37
+
38
+ // by default, the daterangepicker element is placed at the bottom of HTML body
39
+ this.parentEl = 'body';
40
+
41
+ //element that triggered the date range picker
42
+ this.element = $(element);
43
+
44
+ //tracks visible state
45
+ this.isShowing = false;
46
+
47
+ //create the picker HTML object
48
+ var DRPTemplate = '<div class="daterangepicker dropdown-menu">' +
49
+ '<div class="calendar left"></div>' +
50
+ '<div class="calendar right"></div>' +
51
+ '<div class="ranges">' +
52
+ '<div class="range_inputs">' +
53
+ '<div class="daterangepicker_start_input">' +
54
+ '<label for="daterangepicker_start"></label>' +
55
+ '<input class="input-mini" type="text" name="daterangepicker_start" value="" />' +
56
+ '</div>' +
57
+ '<div class="daterangepicker_end_input">' +
58
+ '<label for="daterangepicker_end"></label>' +
59
+ '<input class="input-mini" type="text" name="daterangepicker_end" value="" />' +
60
+ '</div>' +
61
+ '<button class="applyBtn" disabled="disabled"></button>&nbsp;' +
62
+ '<button class="cancelBtn"></button>' +
63
+ '</div>' +
64
+ '</div>' +
65
+ '</div>';
66
+
67
+ //custom options
68
+ if (typeof options !== 'object' || options === null)
69
+ options = {};
70
+
71
+ this.parentEl = (typeof options === 'object' && options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
72
+ this.container = $(DRPTemplate).appendTo(this.parentEl);
73
+
74
+ this.setOptions(options, cb);
75
+
76
+ //apply CSS classes and labels to buttons
77
+ var c = this.container;
78
+ $.each(this.buttonClasses, function (idx, val) {
79
+ c.find('button').addClass(val);
80
+ });
81
+ this.container.find('.daterangepicker_start_input label').html(this.locale.fromLabel);
82
+ this.container.find('.daterangepicker_end_input label').html(this.locale.toLabel);
83
+ if (this.applyClass.length)
84
+ this.container.find('.applyBtn').addClass(this.applyClass);
85
+ if (this.cancelClass.length)
86
+ this.container.find('.cancelBtn').addClass(this.cancelClass);
87
+ this.container.find('.applyBtn').html(this.locale.applyLabel);
88
+ this.container.find('.cancelBtn').html(this.locale.cancelLabel);
89
+
90
+ //event listeners
91
+
92
+ this.container.find('.calendar')
93
+ .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
94
+ .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
95
+ .on('click.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
96
+ .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))
97
+ .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this))
98
+ .on('change.daterangepicker', 'select.yearselect', $.proxy(this.updateMonthYear, this))
99
+ .on('change.daterangepicker', 'select.monthselect', $.proxy(this.updateMonthYear, this))
100
+ .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.ampmselect', $.proxy(this.updateTime, this));
101
+
102
+ this.container.find('.ranges')
103
+ .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
104
+ .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))
105
+ .on('click.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.showCalendars, this))
106
+ .on('change.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsChanged, this))
107
+ .on('keydown.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsKeydown, this))
108
+ .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))
109
+ .on('mouseenter.daterangepicker', 'li', $.proxy(this.enterRange, this))
110
+ .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this));
111
+
112
+ if (this.element.is('input')) {
113
+ this.element.on({
114
+ 'click.daterangepicker': $.proxy(this.show, this),
115
+ 'focus.daterangepicker': $.proxy(this.show, this),
116
+ 'keyup.daterangepicker': $.proxy(this.updateFromControl, this)
117
+ });
118
+ } else {
119
+ this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
120
+ }
121
+
122
+ };
123
+
124
+ DateRangePicker.prototype = {
125
+
126
+ constructor: DateRangePicker,
127
+
128
+ setOptions: function(options, callback) {
129
+
130
+ this.startDate = moment().startOf('day');
131
+ this.endDate = moment().endOf('day');
132
+ this.minDate = false;
133
+ this.maxDate = false;
134
+ this.dateLimit = false;
135
+
136
+ this.showDropdowns = false;
137
+ this.showWeekNumbers = false;
138
+ this.timePicker = false;
139
+ this.timePickerIncrement = 30;
140
+ this.timePicker12Hour = true;
141
+ this.singleDatePicker = false;
142
+ this.ranges = {};
143
+
144
+ this.opens = 'right';
145
+ if (this.element.hasClass('pull-right'))
146
+ this.opens = 'left';
147
+
148
+ this.buttonClasses = ['btn', 'btn-small btn-sm'];
149
+ this.applyClass = 'btn-success';
150
+ this.cancelClass = 'btn-default';
151
+
152
+ this.format = 'MM/DD/YYYY';
153
+ this.separator = ' - ';
154
+
155
+ this.locale = {
156
+ applyLabel: 'Apply',
157
+ cancelLabel: 'Cancel',
158
+ fromLabel: 'From',
159
+ toLabel: 'To',
160
+ weekLabel: 'W',
161
+ customRangeLabel: 'Custom Range',
162
+ daysOfWeek: moment.weekdaysMin(),
163
+ monthNames: moment.monthsShort(),
164
+ firstDay: moment.localeData()._week.dow
165
+ };
166
+
167
+ this.cb = function () { };
168
+
169
+ if (typeof options.format === 'string')
170
+ this.format = options.format;
171
+
172
+ if (typeof options.separator === 'string')
173
+ this.separator = options.separator;
174
+
175
+ if (typeof options.startDate === 'string')
176
+ this.startDate = moment(options.startDate, this.format);
177
+
178
+ if (typeof options.endDate === 'string')
179
+ this.endDate = moment(options.endDate, this.format);
180
+
181
+ if (typeof options.minDate === 'string')
182
+ this.minDate = moment(options.minDate, this.format);
183
+
184
+ if (typeof options.maxDate === 'string')
185
+ this.maxDate = moment(options.maxDate, this.format);
186
+
187
+ if (typeof options.startDate === 'object')
188
+ this.startDate = moment(options.startDate);
189
+
190
+ if (typeof options.endDate === 'object')
191
+ this.endDate = moment(options.endDate);
192
+
193
+ if (typeof options.minDate === 'object')
194
+ this.minDate = moment(options.minDate);
195
+
196
+ if (typeof options.maxDate === 'object')
197
+ this.maxDate = moment(options.maxDate);
198
+
199
+ if (typeof options.applyClass === 'string')
200
+ this.applyClass = options.applyClass;
201
+
202
+ if (typeof options.cancelClass === 'string')
203
+ this.cancelClass = options.cancelClass;
204
+
205
+ if (typeof options.dateLimit === 'object')
206
+ this.dateLimit = options.dateLimit;
207
+
208
+ if (typeof options.locale === 'object') {
209
+
210
+ if (typeof options.locale.daysOfWeek === 'object') {
211
+ // Create a copy of daysOfWeek to avoid modification of original
212
+ // options object for reusability in multiple daterangepicker instances
213
+ this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
214
+ }
215
+
216
+ if (typeof options.locale.monthNames === 'object') {
217
+ this.locale.monthNames = options.locale.monthNames.slice();
218
+ }
219
+
220
+ if (typeof options.locale.firstDay === 'number') {
221
+ this.locale.firstDay = options.locale.firstDay;
222
+ }
223
+
224
+ if (typeof options.locale.applyLabel === 'string') {
225
+ this.locale.applyLabel = options.locale.applyLabel;
226
+ }
227
+
228
+ if (typeof options.locale.cancelLabel === 'string') {
229
+ this.locale.cancelLabel = options.locale.cancelLabel;
230
+ }
231
+
232
+ if (typeof options.locale.fromLabel === 'string') {
233
+ this.locale.fromLabel = options.locale.fromLabel;
234
+ }
235
+
236
+ if (typeof options.locale.toLabel === 'string') {
237
+ this.locale.toLabel = options.locale.toLabel;
238
+ }
239
+
240
+ if (typeof options.locale.weekLabel === 'string') {
241
+ this.locale.weekLabel = options.locale.weekLabel;
242
+ }
243
+
244
+ if (typeof options.locale.customRangeLabel === 'string') {
245
+ this.locale.customRangeLabel = options.locale.customRangeLabel;
246
+ }
247
+ }
248
+
249
+ if (typeof options.opens === 'string')
250
+ this.opens = options.opens;
251
+
252
+ if (typeof options.showWeekNumbers === 'boolean') {
253
+ this.showWeekNumbers = options.showWeekNumbers;
254
+ }
255
+
256
+ if (typeof options.buttonClasses === 'string') {
257
+ this.buttonClasses = [options.buttonClasses];
258
+ }
259
+
260
+ if (typeof options.buttonClasses === 'object') {
261
+ this.buttonClasses = options.buttonClasses;
262
+ }
263
+
264
+ if (typeof options.showDropdowns === 'boolean') {
265
+ this.showDropdowns = options.showDropdowns;
266
+ }
267
+
268
+ if (typeof options.singleDatePicker === 'boolean') {
269
+ this.singleDatePicker = options.singleDatePicker;
270
+ }
271
+
272
+ if (typeof options.timePicker === 'boolean') {
273
+ this.timePicker = options.timePicker;
274
+ }
275
+
276
+ if (typeof options.timePickerIncrement === 'number') {
277
+ this.timePickerIncrement = options.timePickerIncrement;
278
+ }
279
+
280
+ if (typeof options.timePicker12Hour === 'boolean') {
281
+ this.timePicker12Hour = options.timePicker12Hour;
282
+ }
283
+
284
+ // update day names order to firstDay
285
+ if (this.locale.firstDay != 0) {
286
+ var iterator = this.locale.firstDay;
287
+ while (iterator > 0) {
288
+ this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
289
+ iterator--;
290
+ }
291
+ }
292
+
293
+ var start, end, range;
294
+
295
+ //if no start/end dates set, check if an input element contains initial values
296
+ if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
297
+ if ($(this.element).is('input[type=text]')) {
298
+ var val = $(this.element).val();
299
+ var split = val.split(this.separator);
300
+ start = end = null;
301
+ if (split.length == 2) {
302
+ start = moment(split[0], this.format);
303
+ end = moment(split[1], this.format);
304
+ } else if (this.singleDatePicker) {
305
+ start = moment(val, this.format);
306
+ end = moment(val, this.format);
307
+ }
308
+ if (start !== null && end !== null) {
309
+ this.startDate = start;
310
+ this.endDate = end;
311
+ }
312
+ }
313
+ }
314
+
315
+ if (typeof options.ranges === 'object') {
316
+ for (range in options.ranges) {
317
+
318
+ start = moment(options.ranges[range][0]);
319
+ end = moment(options.ranges[range][1]);
320
+
321
+ // If we have a min/max date set, bound this range
322
+ // to it, but only if it would otherwise fall
323
+ // outside of the min/max.
324
+ if (this.minDate && start.isBefore(this.minDate))
325
+ start = moment(this.minDate);
326
+
327
+ if (this.maxDate && end.isAfter(this.maxDate))
328
+ end = moment(this.maxDate);
329
+
330
+ // If the end of the range is before the minimum (if min is set) OR
331
+ // the start of the range is after the max (also if set) don't display this
332
+ // range option.
333
+ if ((this.minDate && end.isBefore(this.minDate)) || (this.maxDate && start.isAfter(this.maxDate))) {
334
+ continue;
335
+ }
336
+
337
+ this.ranges[range] = [start, end];
338
+ }
339
+
340
+ var list = '<ul>';
341
+ for (range in this.ranges) {
342
+ list += '<li>' + range + '</li>';
343
+ }
344
+ list += '<li>' + this.locale.customRangeLabel + '</li>';
345
+ list += '</ul>';
346
+ this.container.find('.ranges ul').remove();
347
+ this.container.find('.ranges').prepend(list);
348
+ }
349
+
350
+ if (typeof callback === 'function') {
351
+ this.cb = callback;
352
+ }
353
+
354
+ if (!this.timePicker) {
355
+ this.startDate = this.startDate.startOf('day');
356
+ this.endDate = this.endDate.endOf('day');
357
+ }
358
+
359
+ if (this.singleDatePicker) {
360
+ this.opens = 'right';
361
+ this.container.find('.calendar.right').show();
362
+ this.container.find('.calendar.left').hide();
363
+ this.container.find('.ranges').hide();
364
+ if (!this.container.find('.calendar.right').hasClass('single'))
365
+ this.container.find('.calendar.right').addClass('single');
366
+ } else {
367
+ this.container.find('.calendar.right').removeClass('single');
368
+ this.container.find('.ranges').show();
369
+ }
370
+
371
+ this.oldStartDate = this.startDate.clone();
372
+ this.oldEndDate = this.endDate.clone();
373
+ this.oldChosenLabel = this.chosenLabel;
374
+
375
+ this.leftCalendar = {
376
+ month: moment([this.startDate.year(), this.startDate.month(), 1, this.startDate.hour(), this.startDate.minute()]),
377
+ calendar: []
378
+ };
379
+
380
+ this.rightCalendar = {
381
+ month: moment([this.endDate.year(), this.endDate.month(), 1, this.endDate.hour(), this.endDate.minute()]),
382
+ calendar: []
383
+ };
384
+
385
+ if (this.opens == 'right') {
386
+ //swap calendar positions
387
+ var left = this.container.find('.calendar.left');
388
+ var right = this.container.find('.calendar.right');
389
+
390
+ if (right.hasClass('single')) {
391
+ right.removeClass('single');
392
+ left.addClass('single');
393
+ }
394
+
395
+ left.removeClass('left').addClass('right');
396
+ right.removeClass('right').addClass('left');
397
+
398
+ if (this.singleDatePicker) {
399
+ left.show();
400
+ right.hide();
401
+ }
402
+ }
403
+
404
+ if (typeof options.ranges === 'undefined' && !this.singleDatePicker) {
405
+ this.container.addClass('show-calendar');
406
+ }
407
+
408
+ this.container.addClass('opens' + this.opens);
409
+
410
+ this.updateView();
411
+ this.updateCalendars();
412
+
413
+ },
414
+
415
+ setStartDate: function(startDate) {
416
+ if (typeof startDate === 'string')
417
+ this.startDate = moment(startDate, this.format);
418
+
419
+ if (typeof startDate === 'object')
420
+ this.startDate = moment(startDate);
421
+
422
+ if (!this.timePicker)
423
+ this.startDate = this.startDate.startOf('day');
424
+
425
+ this.oldStartDate = this.startDate.clone();
426
+
427
+ this.updateView();
428
+ this.updateCalendars();
429
+ this.updateInputText();
430
+ },
431
+
432
+ setEndDate: function(endDate) {
433
+ if (typeof endDate === 'string')
434
+ this.endDate = moment(endDate, this.format);
435
+
436
+ if (typeof endDate === 'object')
437
+ this.endDate = moment(endDate);
438
+
439
+ if (!this.timePicker)
440
+ this.endDate = this.endDate.endOf('day');
441
+
442
+ this.oldEndDate = this.endDate.clone();
443
+
444
+ this.updateView();
445
+ this.updateCalendars();
446
+ this.updateInputText();
447
+ },
448
+
449
+ updateView: function () {
450
+ this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute());
451
+ this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute());
452
+ this.updateFormInputs();
453
+ },
454
+
455
+ updateFormInputs: function () {
456
+ this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format));
457
+ this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format));
458
+
459
+ if (this.startDate.isSame(this.endDate) || this.startDate.isBefore(this.endDate)) {
460
+ this.container.find('button.applyBtn').removeAttr('disabled');
461
+ } else {
462
+ this.container.find('button.applyBtn').attr('disabled', 'disabled');
463
+ }
464
+ },
465
+
466
+ updateFromControl: function () {
467
+ if (!this.element.is('input')) return;
468
+ if (!this.element.val().length) return;
469
+
470
+ var dateString = this.element.val().split(this.separator),
471
+ start = null,
472
+ end = null;
473
+
474
+ if(dateString.length === 2) {
475
+ start = moment(dateString[0], this.format);
476
+ end = moment(dateString[1], this.format);
477
+ }
478
+
479
+ if (this.singleDatePicker || start === null || end === null) {
480
+ start = moment(this.element.val(), this.format);
481
+ end = start;
482
+ }
483
+
484
+ if (end.isBefore(start)) return;
485
+
486
+ this.oldStartDate = this.startDate.clone();
487
+ this.oldEndDate = this.endDate.clone();
488
+
489
+ this.startDate = start;
490
+ this.endDate = end;
491
+
492
+ if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
493
+ this.notify();
494
+
495
+ this.updateCalendars();
496
+ },
497
+
498
+ notify: function () {
499
+ this.updateView();
500
+ this.cb(this.startDate, this.endDate, this.chosenLabel);
501
+ },
502
+
503
+ move: function () {
504
+ var parentOffset = { top: 0, left: 0 };
505
+ var parentRightEdge = $(window).width();
506
+ if (!this.parentEl.is('body')) {
507
+ parentOffset = {
508
+ top: this.parentEl.offset().top - this.parentEl.scrollTop(),
509
+ left: this.parentEl.offset().left - this.parentEl.scrollLeft()
510
+ };
511
+ parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
512
+ }
513
+
514
+ if (this.opens == 'left') {
515
+ this.container.css({
516
+ top: this.element.offset().top + this.element.outerHeight() - parentOffset.top,
517
+ right: parentRightEdge - this.element.offset().left - this.element.outerWidth(),
518
+ left: 'auto'
519
+ });
520
+ if (this.container.offset().left < 0) {
521
+ this.container.css({
522
+ right: 'auto',
523
+ left: 9
524
+ });
525
+ }
526
+ } else {
527
+ this.container.css({
528
+ top: this.element.offset().top + this.element.outerHeight() - parentOffset.top,
529
+ left: this.element.offset().left - parentOffset.left,
530
+ right: 'auto'
531
+ });
532
+ if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {
533
+ this.container.css({
534
+ left: 'auto',
535
+ right: 0
536
+ });
537
+ }
538
+ }
539
+ },
540
+
541
+ toggle: function (e) {
542
+ if (this.element.hasClass('active')) {
543
+ this.hide();
544
+ } else {
545
+ this.show();
546
+ }
547
+ },
548
+
549
+ show: function (e) {
550
+ if (this.isShowing) return;
551
+
552
+ this.element.addClass('active');
553
+ this.container.show();
554
+ this.move();
555
+
556
+ // Create a click proxy that is private to this instance of datepicker, for unbinding
557
+ this._outsideClickProxy = $.proxy(function (e) { this.outsideClick(e); }, this);
558
+ // Bind global datepicker mousedown for hiding and
559
+ $(document)
560
+ .on('mousedown.daterangepicker', this._outsideClickProxy)
561
+ // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
562
+ .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
563
+ // and also close when focus changes to outside the picker (eg. tabbing between controls)
564
+ .on('focusin.daterangepicker', this._outsideClickProxy);
565
+
566
+ this.isShowing = true;
567
+ this.element.trigger('show.daterangepicker', this);
568
+ },
569
+
570
+ outsideClick: function (e) {
571
+ var target = $(e.target);
572
+ // if the page is clicked anywhere except within the daterangerpicker/button
573
+ // itself then call this.hide()
574
+ if (
575
+ target.closest(this.element).length ||
576
+ target.closest(this.container).length ||
577
+ target.closest('.calendar-date').length
578
+ ) return;
579
+ this.hide();
580
+ },
581
+
582
+ hide: function (e) {
583
+ if (!this.isShowing) return;
584
+
585
+ $(document)
586
+ .off('mousedown.daterangepicker')
587
+ .off('click.daterangepicker', '[data-toggle=dropdown]')
588
+ .off('focusin.daterangepicker');
589
+
590
+ this.element.removeClass('active');
591
+ this.container.hide();
592
+
593
+ if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
594
+ this.notify();
595
+
596
+ this.oldStartDate = this.startDate.clone();
597
+ this.oldEndDate = this.endDate.clone();
598
+
599
+ this.isShowing = false;
600
+ this.element.trigger('hide.daterangepicker', this);
601
+ },
602
+
603
+ enterRange: function (e) {
604
+ // mouse pointer has entered a range label
605
+ var label = e.target.innerHTML;
606
+ if (label == this.locale.customRangeLabel) {
607
+ this.updateView();
608
+ } else {
609
+ var dates = this.ranges[label];
610
+ this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format));
611
+ this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format));
612
+ }
613
+ },
614
+
615
+ showCalendars: function() {
616
+ this.container.addClass('show-calendar');
617
+ this.move();
618
+ this.element.trigger('showCalendar.daterangepicker', this);
619
+ },
620
+
621
+ hideCalendars: function() {
622
+ this.container.removeClass('show-calendar');
623
+ this.element.trigger('hideCalendar.daterangepicker', this);
624
+ },
625
+
626
+ // when a date is typed into the start to end date textboxes
627
+ inputsChanged: function (e) {
628
+ var el = $(e.target);
629
+ var date = moment(el.val());
630
+ if (!date.isValid()) return;
631
+
632
+ var startDate, endDate;
633
+ if (el.attr('name') === 'daterangepicker_start') {
634
+ startDate = date;
635
+ endDate = this.endDate;
636
+ } else {
637
+ startDate = this.startDate;
638
+ endDate = date;
639
+ }
640
+ this.setCustomDates(startDate, endDate);
641
+ },
642
+
643
+ inputsKeydown: function(e) {
644
+ if (e.keyCode === 13) {
645
+ this.inputsChanged(e);
646
+ this.notify();
647
+ }
648
+ },
649
+
650
+ updateInputText: function() {
651
+ if (this.element.is('input') && !this.singleDatePicker) {
652
+ this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format));
653
+ } else if (this.element.is('input')) {
654
+ this.element.val(this.startDate.format(this.format));
655
+ }
656
+ },
657
+
658
+ clickRange: function (e) {
659
+ var label = e.target.innerHTML;
660
+ this.chosenLabel = label;
661
+ if (label == this.locale.customRangeLabel) {
662
+ this.showCalendars();
663
+ } else {
664
+ var dates = this.ranges[label];
665
+
666
+ this.startDate = dates[0];
667
+ this.endDate = dates[1];
668
+
669
+ if (!this.timePicker) {
670
+ this.startDate.startOf('day');
671
+ this.endDate.endOf('day');
672
+ }
673
+
674
+ this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute());
675
+ this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute());
676
+ this.updateCalendars();
677
+
678
+ this.updateInputText();
679
+
680
+ this.hideCalendars();
681
+ this.hide();
682
+ this.element.trigger('apply.daterangepicker', this);
683
+ }
684
+ },
685
+
686
+ clickPrev: function (e) {
687
+ var cal = $(e.target).parents('.calendar');
688
+ if (cal.hasClass('left')) {
689
+ this.leftCalendar.month.subtract(1, 'month');
690
+ } else {
691
+ this.rightCalendar.month.subtract(1, 'month');
692
+ }
693
+ this.updateCalendars();
694
+ },
695
+
696
+ clickNext: function (e) {
697
+ var cal = $(e.target).parents('.calendar');
698
+ if (cal.hasClass('left')) {
699
+ this.leftCalendar.month.add(1, 'month');
700
+ } else {
701
+ this.rightCalendar.month.add(1, 'month');
702
+ }
703
+ this.updateCalendars();
704
+ },
705
+
706
+ hoverDate: function (e) {
707
+ var title = $(e.target).attr('data-title');
708
+ var row = title.substr(1, 1);
709
+ var col = title.substr(3, 1);
710
+ var cal = $(e.target).parents('.calendar');
711
+
712
+ if (cal.hasClass('left')) {
713
+ this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format));
714
+ } else {
715
+ this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format));
716
+ }
717
+ },
718
+
719
+ setCustomDates: function(startDate, endDate) {
720
+ this.chosenLabel = this.locale.customRangeLabel;
721
+ if (startDate.isAfter(endDate)) {
722
+ var difference = this.endDate.diff(this.startDate);
723
+ endDate = moment(startDate).add(difference, 'ms');
724
+ }
725
+ this.startDate = startDate;
726
+ this.endDate = endDate;
727
+
728
+ this.updateView();
729
+ this.updateCalendars();
730
+ },
731
+
732
+ clickDate: function (e) {
733
+ var title = $(e.target).attr('data-title');
734
+ var row = title.substr(1, 1);
735
+ var col = title.substr(3, 1);
736
+ var cal = $(e.target).parents('.calendar');
737
+
738
+ var startDate, endDate;
739
+ if (cal.hasClass('left')) {
740
+ startDate = this.leftCalendar.calendar[row][col];
741
+ endDate = this.endDate;
742
+ if (typeof this.dateLimit === 'object') {
743
+ var maxDate = moment(startDate).add(this.dateLimit).startOf('day');
744
+ if (endDate.isAfter(maxDate)) {
745
+ endDate = maxDate;
746
+ }
747
+ }
748
+ } else {
749
+ startDate = this.startDate;
750
+ endDate = this.rightCalendar.calendar[row][col];
751
+ if (typeof this.dateLimit === 'object') {
752
+ var minDate = moment(endDate).subtract(this.dateLimit).startOf('day');
753
+ if (startDate.isBefore(minDate)) {
754
+ startDate = minDate;
755
+ }
756
+ }
757
+ }
758
+
759
+ if (this.singleDatePicker && cal.hasClass('left')) {
760
+ endDate = startDate.clone();
761
+ } else if (this.singleDatePicker && cal.hasClass('right')) {
762
+ startDate = endDate.clone();
763
+ }
764
+
765
+ cal.find('td').removeClass('active');
766
+
767
+ $(e.target).addClass('active');
768
+
769
+ this.setCustomDates(startDate, endDate);
770
+
771
+ if (!this.timePicker)
772
+ endDate.endOf('day');
773
+
774
+ if (this.singleDatePicker)
775
+ this.clickApply();
776
+ },
777
+
778
+ clickApply: function (e) {
779
+ this.updateInputText();
780
+ this.hide();
781
+ this.element.trigger('apply.daterangepicker', this);
782
+ },
783
+
784
+ clickCancel: function (e) {
785
+ this.startDate = this.oldStartDate;
786
+ this.endDate = this.oldEndDate;
787
+ this.chosenLabel = this.oldChosenLabel;
788
+ this.updateView();
789
+ this.updateCalendars();
790
+ this.hide();
791
+ this.element.trigger('cancel.daterangepicker', this);
792
+ },
793
+
794
+ updateMonthYear: function (e) {
795
+ var isLeft = $(e.target).closest('.calendar').hasClass('left'),
796
+ leftOrRight = isLeft ? 'left' : 'right',
797
+ cal = this.container.find('.calendar.'+leftOrRight);
798
+
799
+ // Month must be Number for new moment versions
800
+ var month = parseInt(cal.find('.monthselect').val(), 10);
801
+ var year = cal.find('.yearselect').val();
802
+
803
+ this[leftOrRight+'Calendar'].month.month(month).year(year);
804
+ this.updateCalendars();
805
+ },
806
+
807
+ updateTime: function(e) {
808
+
809
+ var cal = $(e.target).closest('.calendar'),
810
+ isLeft = cal.hasClass('left');
811
+
812
+ var hour = parseInt(cal.find('.hourselect').val(), 10);
813
+ var minute = parseInt(cal.find('.minuteselect').val(), 10);
814
+
815
+ if (this.timePicker12Hour) {
816
+ var ampm = cal.find('.ampmselect').val();
817
+ if (ampm === 'PM' && hour < 12)
818
+ hour += 12;
819
+ if (ampm === 'AM' && hour === 12)
820
+ hour = 0;
821
+ }
822
+
823
+ if (isLeft) {
824
+ var start = this.startDate.clone();
825
+ start.hour(hour);
826
+ start.minute(minute);
827
+ this.startDate = start;
828
+ this.leftCalendar.month.hour(hour).minute(minute);
829
+ } else {
830
+ var end = this.endDate.clone();
831
+ end.hour(hour);
832
+ end.minute(minute);
833
+ this.endDate = end;
834
+ this.rightCalendar.month.hour(hour).minute(minute);
835
+ }
836
+
837
+ this.updateCalendars();
838
+ },
839
+
840
+ updateCalendars: function () {
841
+ this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.month(), this.leftCalendar.month.year(), this.leftCalendar.month.hour(), this.leftCalendar.month.minute(), 'left');
842
+ this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.month(), this.rightCalendar.month.year(), this.rightCalendar.month.hour(), this.rightCalendar.month.minute(), 'right');
843
+ this.container.find('.calendar.left').empty().html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate));
844
+
845
+ var minDate = this.minDate;
846
+ if (!this.singleDatePicker)
847
+ minDate = this.startDate;
848
+ this.container.find('.calendar.right').empty().html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, minDate, this.maxDate));
849
+
850
+ this.container.find('.ranges li').removeClass('active');
851
+ var customRange = true;
852
+ var i = 0;
853
+ for (var range in this.ranges) {
854
+ if (this.timePicker) {
855
+ if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) {
856
+ customRange = false;
857
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')
858
+ .addClass('active').html();
859
+ }
860
+ } else {
861
+ //ignore times when comparing dates if time picker is not enabled
862
+ if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {
863
+ customRange = false;
864
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')
865
+ .addClass('active').html();
866
+ }
867
+ }
868
+ i++;
869
+ }
870
+ if (customRange) {
871
+ this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html();
872
+ this.showCalendars();
873
+ }
874
+ },
875
+
876
+ buildCalendar: function (month, year, hour, minute, side) {
877
+ var daysInMonth = moment([year, month]).daysInMonth();
878
+ var firstDay = moment([year, month, 1]);
879
+ var lastDay = moment([year, month, daysInMonth]);
880
+ var lastMonth = moment(firstDay).subtract(1, 'month').month();
881
+ var lastYear = moment(firstDay).subtract(1, 'month').year();
882
+
883
+ var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
884
+
885
+ var dayOfWeek = firstDay.day();
886
+
887
+ var i;
888
+
889
+ //initialize a 6 rows x 7 columns array for the calendar
890
+ var calendar = [];
891
+ calendar.firstDay = firstDay;
892
+ calendar.lastDay = lastDay;
893
+
894
+ for (i = 0; i < 6; i++) {
895
+ calendar[i] = [];
896
+ }
897
+
898
+ //populate the calendar with date objects
899
+ var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
900
+ if (startDay > daysInLastMonth)
901
+ startDay -= 7;
902
+
903
+ if (dayOfWeek == this.locale.firstDay)
904
+ startDay = daysInLastMonth - 6;
905
+
906
+ var curDate = moment([lastYear, lastMonth, startDay, 12, minute]);
907
+ var col, row;
908
+ for (i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
909
+ if (i > 0 && col % 7 === 0) {
910
+ col = 0;
911
+ row++;
912
+ }
913
+ calendar[row][col] = curDate.clone().hour(hour);
914
+ curDate.hour(12);
915
+ }
916
+
917
+ return calendar;
918
+ },
919
+
920
+ renderDropdowns: function (selected, minDate, maxDate) {
921
+ var currentMonth = selected.month();
922
+ var monthHtml = '<select class="monthselect">';
923
+ var inMinYear = false;
924
+ var inMaxYear = false;
925
+
926
+ for (var m = 0; m < 12; m++) {
927
+ if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {
928
+ monthHtml += "<option value='" + m + "'" +
929
+ (m === currentMonth ? " selected='selected'" : "") +
930
+ ">" + this.locale.monthNames[m] + "</option>";
931
+ }
932
+ }
933
+ monthHtml += "</select>";
934
+
935
+ var currentYear = selected.year();
936
+ var maxYear = (maxDate && maxDate.year()) || (currentYear + 5);
937
+ var minYear = (minDate && minDate.year()) || (currentYear - 50);
938
+ var yearHtml = '<select class="yearselect">';
939
+
940
+ for (var y = minYear; y <= maxYear; y++) {
941
+ yearHtml += '<option value="' + y + '"' +
942
+ (y === currentYear ? ' selected="selected"' : '') +
943
+ '>' + y + '</option>';
944
+ }
945
+
946
+ yearHtml += '</select>';
947
+
948
+ return monthHtml + yearHtml;
949
+ },
950
+
951
+ renderCalendar: function (calendar, selected, minDate, maxDate) {
952
+
953
+ var html = '<div class="calendar-date">';
954
+ html += '<table class="table-condensed">';
955
+ html += '<thead>';
956
+ html += '<tr>';
957
+
958
+ // add empty cell for week number
959
+ if (this.showWeekNumbers)
960
+ html += '<th></th>';
961
+
962
+ if (!minDate || minDate.isBefore(calendar.firstDay)) {
963
+ html += '<th class="prev available"><i class="fa fa-arrow-left icon-arrow-left glyphicon glyphicon-arrow-left"></i></th>';
964
+ } else {
965
+ html += '<th></th>';
966
+ }
967
+
968
+ var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
969
+
970
+ if (this.showDropdowns) {
971
+ dateHtml = this.renderDropdowns(calendar[1][1], minDate, maxDate);
972
+ }
973
+
974
+ html += '<th colspan="5" class="month">' + dateHtml + '</th>';
975
+ if (!maxDate || maxDate.isAfter(calendar.lastDay)) {
976
+ html += '<th class="next available"><i class="fa fa-arrow-right icon-arrow-right glyphicon glyphicon-arrow-right"></i></th>';
977
+ } else {
978
+ html += '<th></th>';
979
+ }
980
+
981
+ html += '</tr>';
982
+ html += '<tr>';
983
+
984
+ // add week number label
985
+ if (this.showWeekNumbers)
986
+ html += '<th class="week">' + this.locale.weekLabel + '</th>';
987
+
988
+ $.each(this.locale.daysOfWeek, function (index, dayOfWeek) {
989
+ html += '<th>' + dayOfWeek + '</th>';
990
+ });
991
+
992
+ html += '</tr>';
993
+ html += '</thead>';
994
+ html += '<tbody>';
995
+
996
+ for (var row = 0; row < 6; row++) {
997
+ html += '<tr>';
998
+
999
+ // add week number
1000
+ if (this.showWeekNumbers)
1001
+ html += '<td class="week">' + calendar[row][0].week() + '</td>';
1002
+
1003
+ for (var col = 0; col < 7; col++) {
1004
+ var cname = 'available ';
1005
+ cname += (calendar[row][col].month() == calendar[1][1].month()) ? '' : 'off';
1006
+
1007
+ if ((minDate && calendar[row][col].isBefore(minDate, 'day')) || (maxDate && calendar[row][col].isAfter(maxDate, 'day'))) {
1008
+ cname = ' off disabled ';
1009
+ } else if (calendar[row][col].format('YYYY-MM-DD') == selected.format('YYYY-MM-DD')) {
1010
+ cname += ' active ';
1011
+ if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) {
1012
+ cname += ' start-date ';
1013
+ }
1014
+ if (calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) {
1015
+ cname += ' end-date ';
1016
+ }
1017
+ } else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) {
1018
+ cname += ' in-range ';
1019
+ if (calendar[row][col].isSame(this.startDate)) { cname += ' start-date '; }
1020
+ if (calendar[row][col].isSame(this.endDate)) { cname += ' end-date '; }
1021
+ }
1022
+
1023
+ var title = 'r' + row + 'c' + col;
1024
+ html += '<td class="' + cname.replace(/\s+/g, ' ').replace(/^\s?(.*?)\s?$/, '$1') + '" data-title="' + title + '">' + calendar[row][col].date() + '</td>';
1025
+ }
1026
+ html += '</tr>';
1027
+ }
1028
+
1029
+ html += '</tbody>';
1030
+ html += '</table>';
1031
+ html += '</div>';
1032
+
1033
+ var i;
1034
+ if (this.timePicker) {
1035
+
1036
+ html += '<div class="calendar-time">';
1037
+ html += '<select class="hourselect">';
1038
+ var start = 0;
1039
+ var end = 23;
1040
+ var selected_hour = selected.hour();
1041
+ if (this.timePicker12Hour) {
1042
+ start = 1;
1043
+ end = 12;
1044
+ if (selected_hour >= 12)
1045
+ selected_hour -= 12;
1046
+ if (selected_hour === 0)
1047
+ selected_hour = 12;
1048
+ }
1049
+
1050
+ for (i = start; i <= end; i++) {
1051
+ if (i == selected_hour) {
1052
+ html += '<option value="' + i + '" selected="selected">' + i + '</option>';
1053
+ } else {
1054
+ html += '<option value="' + i + '">' + i + '</option>';
1055
+ }
1056
+ }
1057
+
1058
+ html += '</select> : ';
1059
+
1060
+ html += '<select class="minuteselect">';
1061
+
1062
+ for (i = 0; i < 60; i += this.timePickerIncrement) {
1063
+ var num = i;
1064
+ if (num < 10)
1065
+ num = '0' + num;
1066
+ if (i == selected.minute()) {
1067
+ html += '<option value="' + i + '" selected="selected">' + num + '</option>';
1068
+ } else {
1069
+ html += '<option value="' + i + '">' + num + '</option>';
1070
+ }
1071
+ }
1072
+
1073
+ html += '</select> ';
1074
+
1075
+ if (this.timePicker12Hour) {
1076
+ html += '<select class="ampmselect">';
1077
+ if (selected.hour() >= 12) {
1078
+ html += '<option value="AM">AM</option><option value="PM" selected="selected">PM</option>';
1079
+ } else {
1080
+ html += '<option value="AM" selected="selected">AM</option><option value="PM">PM</option>';
1081
+ }
1082
+ html += '</select>';
1083
+ }
1084
+
1085
+ html += '</div>';
1086
+
1087
+ }
1088
+
1089
+ return html;
1090
+
1091
+ },
1092
+
1093
+ remove: function() {
1094
+
1095
+ this.container.remove();
1096
+ this.element.off('.daterangepicker');
1097
+ this.element.removeData('daterangepicker');
1098
+
1099
+ }
1100
+
1101
+ };
1102
+
1103
+ $.fn.daterangepicker = function (options, cb) {
1104
+ this.each(function () {
1105
+ var el = $(this);
1106
+ if (el.data('daterangepicker'))
1107
+ el.data('daterangepicker').remove();
1108
+ el.data('daterangepicker', new DateRangePicker(el, options, cb));
1109
+ });
1110
+ return this;
1111
+ };
1112
+
1113
+ }));