daterangepicker-rails 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODFmNDFiMmRmMjcyNWU0MmQ0YThmOTM1Y2M1OTQ2ZWEzY2YxM2NhYQ==
5
+ data.tar.gz: !binary |-
6
+ Y2NjYzQ3MWY3MjEwZDdkZDVjMGVlNDk4ODVkNTM3ZWNlM2YzNzg0YQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NTBmODNkNDhhZWQ2MzQ5ODA3ZTk4ZjExZTJiNDQ1M2Q2OGVkZTRhZjIzMzk0
10
+ MjFkY2YwNmRjMDQ5NWViNjFjYWVmZGQ3MzQ2M2QzNGEwNzRjNTQ1NTU5ZTdm
11
+ YTEzZjdkOTlhMTFhMWM0Mzk5MDA2OWRiZTk5MjdjMWE0OTNkMDc=
12
+ data.tar.gz: !binary |-
13
+ ZGExOGQ3NjQ3OTcxNTRkM2NlMGRkMzZhOGVmNzNhMDRmMmVhZjA4ZDAzY2Zh
14
+ YmYwZWVmOWRhNDEwYTQ3Mzk0MzA4OGUwN2YyNjA1YTM4ZDk1NmYxZDJhYzE4
15
+ MTViYzIwNDVkNjZhZmQzMmZhMTYzOTBiMzc0Y2M2MjE3MjFkM2Y=
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in daterangepicker-rails.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Venkata Reddy Bhavanam
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Daterangepicker::Rails
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'daterangepicker-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install daterangepicker-rails
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/daterangepicker-rails/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'daterangepicker/rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "daterangepicker-rails"
8
+ spec.version = Daterangepicker::Rails::VERSION
9
+ spec.authors = ["Venkata Reddy Bhavanam"]
10
+ spec.email = ["venkatareddy.cs@gmail.com"]
11
+ spec.summary = %q{bootstrap css, moment js, datarangepicker js.}
12
+ spec.description = %q{Include Dan Grossman's Bootstrap DateRangePicker Easily in your rails app}
13
+ spec.homepage = "https://github.com/rubystar/daterangepicker-rails"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,8 @@
1
+ require "daterangepicker/rails/version"
2
+
3
+ module Daterangepicker
4
+ module Rails
5
+ class Engine < Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Daterangepicker
2
+ module Rails
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,1017 @@
1
+ /**
2
+ * @version: 1.3.6
3
+ * @author: Dan Grossman http://www.dangrossman.info/
4
+ * @date: 2014-04-29
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
+ !function ($, moment) {
10
+
11
+ var DateRangePicker = function (element, options, cb) {
12
+
13
+ // by default, the daterangepicker element is placed at the bottom of HTML body
14
+ this.parentEl = 'body';
15
+
16
+ //element that triggered the date range picker
17
+ this.element = $(element);
18
+
19
+ //create the picker HTML object
20
+ var DRPTemplate = '<div class="daterangepicker dropdown-menu">' +
21
+ '<div class="calendar left"></div>' +
22
+ '<div class="calendar right"></div>' +
23
+ '<div class="ranges">' +
24
+ '<div class="range_inputs">' +
25
+ '<div class="daterangepicker_start_input">' +
26
+ '<label for="daterangepicker_start"></label>' +
27
+ '<input class="input-mini" type="text" name="daterangepicker_start" value="" disabled="disabled" />' +
28
+ '</div>' +
29
+ '<div class="daterangepicker_end_input">' +
30
+ '<label for="daterangepicker_end"></label>' +
31
+ '<input class="input-mini" type="text" name="daterangepicker_end" value="" disabled="disabled" />' +
32
+ '</div>' +
33
+ '<button class="applyBtn" disabled="disabled"></button>&nbsp;' +
34
+ '<button class="cancelBtn"></button>' +
35
+ '</div>' +
36
+ '</div>' +
37
+ '</div>';
38
+
39
+ //custom options
40
+ if (typeof options !== 'object' || options === null)
41
+ options = {};
42
+
43
+ this.parentEl = (typeof options === 'object' && options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
44
+ this.container = $(DRPTemplate).appendTo(this.parentEl);
45
+
46
+ this.setOptions(options, cb);
47
+
48
+ //apply CSS classes and labels to buttons
49
+ var c = this.container;
50
+ $.each(this.buttonClasses, function (idx, val) {
51
+ c.find('button').addClass(val);
52
+ });
53
+ this.container.find('.daterangepicker_start_input label').html(this.locale.fromLabel);
54
+ this.container.find('.daterangepicker_end_input label').html(this.locale.toLabel);
55
+ if (this.applyClass.length)
56
+ this.container.find('.applyBtn').addClass(this.applyClass);
57
+ if (this.cancelClass.length)
58
+ this.container.find('.cancelBtn').addClass(this.cancelClass);
59
+ this.container.find('.applyBtn').html(this.locale.applyLabel);
60
+ this.container.find('.cancelBtn').html(this.locale.cancelLabel);
61
+
62
+ //event listeners
63
+
64
+ this.container.find('.calendar')
65
+ .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
66
+ .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
67
+ .on('click.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
68
+ .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.enterDate, this))
69
+ .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this))
70
+ .on('change.daterangepicker', 'select.yearselect', $.proxy(this.updateMonthYear, this))
71
+ .on('change.daterangepicker', 'select.monthselect', $.proxy(this.updateMonthYear, this))
72
+ .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.ampmselect', $.proxy(this.updateTime, this));
73
+
74
+ this.container.find('.ranges')
75
+ .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
76
+ .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))
77
+ .on('click.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.showCalendars, this))
78
+ .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))
79
+ .on('mouseenter.daterangepicker', 'li', $.proxy(this.enterRange, this))
80
+ .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this));
81
+
82
+ if (this.element.is('input')) {
83
+ this.element.on({
84
+ 'click.daterangepicker': $.proxy(this.show, this),
85
+ 'focus.daterangepicker': $.proxy(this.show, this),
86
+ 'keyup.daterangepicker': $.proxy(this.updateFromControl, this)
87
+ });
88
+ } else {
89
+ this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
90
+ }
91
+
92
+ };
93
+
94
+ DateRangePicker.prototype = {
95
+
96
+ constructor: DateRangePicker,
97
+
98
+ setOptions: function(options, callback) {
99
+
100
+ this.startDate = moment().startOf('day');
101
+ this.endDate = moment().endOf('day');
102
+ this.minDate = false;
103
+ this.maxDate = false;
104
+ this.dateLimit = false;
105
+
106
+ this.showDropdowns = false;
107
+ this.showWeekNumbers = false;
108
+ this.timePicker = false;
109
+ this.timePickerIncrement = 30;
110
+ this.timePicker12Hour = true;
111
+ this.singleDatePicker = false;
112
+ this.ranges = {};
113
+
114
+ this.opens = 'right';
115
+ if (this.element.hasClass('pull-right'))
116
+ this.opens = 'left';
117
+
118
+ this.buttonClasses = ['btn', 'btn-small'];
119
+ this.applyClass = 'btn-success';
120
+ this.cancelClass = 'btn-default';
121
+
122
+ this.format = 'MM/DD/YYYY';
123
+ this.separator = ' - ';
124
+
125
+ this.locale = {
126
+ applyLabel: 'Apply',
127
+ cancelLabel: 'Cancel',
128
+ fromLabel: 'From',
129
+ toLabel: 'To',
130
+ weekLabel: 'W',
131
+ customRangeLabel: 'Custom Range',
132
+ daysOfWeek: moment()._lang._weekdaysMin.slice(),
133
+ monthNames: moment()._lang._monthsShort.slice(),
134
+ firstDay: 0
135
+ };
136
+
137
+ this.cb = function () { };
138
+
139
+ if (typeof options.format === 'string')
140
+ this.format = options.format;
141
+
142
+ if (typeof options.separator === 'string')
143
+ this.separator = options.separator;
144
+
145
+ if (typeof options.startDate === 'string')
146
+ this.startDate = moment(options.startDate, this.format);
147
+
148
+ if (typeof options.endDate === 'string')
149
+ this.endDate = moment(options.endDate, this.format);
150
+
151
+ if (typeof options.minDate === 'string')
152
+ this.minDate = moment(options.minDate, this.format);
153
+
154
+ if (typeof options.maxDate === 'string')
155
+ this.maxDate = moment(options.maxDate, this.format);
156
+
157
+ if (typeof options.startDate === 'object')
158
+ this.startDate = moment(options.startDate);
159
+
160
+ if (typeof options.endDate === 'object')
161
+ this.endDate = moment(options.endDate);
162
+
163
+ if (typeof options.minDate === 'object')
164
+ this.minDate = moment(options.minDate);
165
+
166
+ if (typeof options.maxDate === 'object')
167
+ this.maxDate = moment(options.maxDate);
168
+
169
+ if (typeof options.applyClass === 'string')
170
+ this.applyClass = options.applyClass;
171
+
172
+ if (typeof options.cancelClass === 'string')
173
+ this.cancelClass = options.cancelClass;
174
+
175
+ if (typeof options.dateLimit === 'object')
176
+ this.dateLimit = options.dateLimit;
177
+
178
+ // update day names order to firstDay
179
+ if (typeof options.locale === 'object') {
180
+
181
+ if (typeof options.locale.daysOfWeek === 'object') {
182
+ // Create a copy of daysOfWeek to avoid modification of original
183
+ // options object for reusability in multiple daterangepicker instances
184
+ this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
185
+ }
186
+
187
+ if (typeof options.locale.monthNames === 'object') {
188
+ this.locale.monthNames = options.locale.monthNames.slice();
189
+ }
190
+
191
+ if (typeof options.locale.firstDay === 'number') {
192
+ this.locale.firstDay = options.locale.firstDay;
193
+ var iterator = options.locale.firstDay;
194
+ while (iterator > 0) {
195
+ this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
196
+ iterator--;
197
+ }
198
+ }
199
+
200
+ if (typeof options.locale.applyLabel === 'string') {
201
+ this.locale.applyLabel = options.locale.applyLabel;
202
+ }
203
+
204
+ if (typeof options.locale.cancelLabel === 'string') {
205
+ this.locale.cancelLabel = options.locale.cancelLabel;
206
+ }
207
+
208
+ if (typeof options.locale.fromLabel === 'string') {
209
+ this.locale.fromLabel = options.locale.fromLabel;
210
+ }
211
+
212
+ if (typeof options.locale.toLabel === 'string') {
213
+ this.locale.toLabel = options.locale.toLabel;
214
+ }
215
+
216
+ if (typeof options.locale.weekLabel === 'string') {
217
+ this.locale.weekLabel = options.locale.weekLabel;
218
+ }
219
+
220
+ if (typeof options.locale.customRangeLabel === 'string') {
221
+ this.locale.customRangeLabel = options.locale.customRangeLabel;
222
+ }
223
+ }
224
+
225
+ if (typeof options.opens === 'string')
226
+ this.opens = options.opens;
227
+
228
+ if (typeof options.showWeekNumbers === 'boolean') {
229
+ this.showWeekNumbers = options.showWeekNumbers;
230
+ }
231
+
232
+ if (typeof options.buttonClasses === 'string') {
233
+ this.buttonClasses = [options.buttonClasses];
234
+ }
235
+
236
+ if (typeof options.buttonClasses === 'object') {
237
+ this.buttonClasses = options.buttonClasses;
238
+ }
239
+
240
+ if (typeof options.showDropdowns === 'boolean') {
241
+ this.showDropdowns = options.showDropdowns;
242
+ }
243
+
244
+ if (typeof options.singleDatePicker === 'boolean') {
245
+ this.singleDatePicker = options.singleDatePicker;
246
+ }
247
+
248
+ if (typeof options.timePicker === 'boolean') {
249
+ this.timePicker = options.timePicker;
250
+ }
251
+
252
+ if (typeof options.timePickerIncrement === 'number') {
253
+ this.timePickerIncrement = options.timePickerIncrement;
254
+ }
255
+
256
+ if (typeof options.timePicker12Hour === 'boolean') {
257
+ this.timePicker12Hour = options.timePicker12Hour;
258
+ }
259
+
260
+ var start, end, range;
261
+
262
+ //if no start/end dates set, check if an input element contains initial values
263
+ if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
264
+ if ($(this.element).is('input[type=text]')) {
265
+ var val = $(this.element).val();
266
+ var split = val.split(this.separator);
267
+ start = end = null;
268
+ if (split.length == 2) {
269
+ start = moment(split[0], this.format);
270
+ end = moment(split[1], this.format);
271
+ } else if (this.singleDatePicker) {
272
+ start = moment(val, this.format);
273
+ end = moment(val, this.format);
274
+ }
275
+ if (start !== null && end !== null) {
276
+ this.startDate = start;
277
+ this.endDate = end;
278
+ }
279
+ }
280
+ }
281
+
282
+ if (typeof options.ranges === 'object') {
283
+ for (range in options.ranges) {
284
+
285
+ start = moment(options.ranges[range][0]);
286
+ end = moment(options.ranges[range][1]);
287
+
288
+ // If we have a min/max date set, bound this range
289
+ // to it, but only if it would otherwise fall
290
+ // outside of the min/max.
291
+ if (this.minDate && start.isBefore(this.minDate))
292
+ start = moment(this.minDate);
293
+
294
+ if (this.maxDate && end.isAfter(this.maxDate))
295
+ end = moment(this.maxDate);
296
+
297
+ // If the end of the range is before the minimum (if min is set) OR
298
+ // the start of the range is after the max (also if set) don't display this
299
+ // range option.
300
+ if ((this.minDate && end.isBefore(this.minDate)) || (this.maxDate && start.isAfter(this.maxDate))) {
301
+ continue;
302
+ }
303
+
304
+ this.ranges[range] = [start, end];
305
+ }
306
+
307
+ var list = '<ul>';
308
+ for (range in this.ranges) {
309
+ list += '<li>' + range + '</li>';
310
+ }
311
+ list += '<li>' + this.locale.customRangeLabel + '</li>';
312
+ list += '</ul>';
313
+ this.container.find('.ranges ul').remove();
314
+ this.container.find('.ranges').prepend(list);
315
+ }
316
+
317
+ if (typeof callback === 'function') {
318
+ this.cb = callback;
319
+ }
320
+
321
+ if (!this.timePicker) {
322
+ this.startDate = this.startDate.startOf('day');
323
+ this.endDate = this.endDate.endOf('day');
324
+ }
325
+
326
+ if (this.singleDatePicker) {
327
+ this.opens = 'right';
328
+ this.container.find('.calendar.right').show();
329
+ this.container.find('.calendar.left').hide();
330
+ this.container.find('.ranges').hide();
331
+ if (!this.container.find('.calendar.right').hasClass('single'))
332
+ this.container.find('.calendar.right').addClass('single');
333
+ } else {
334
+ this.container.find('.calendar.right').removeClass('single');
335
+ this.container.find('.ranges').show();
336
+ }
337
+
338
+ this.oldStartDate = this.startDate.clone();
339
+ this.oldEndDate = this.endDate.clone();
340
+ this.oldChosenLabel = this.chosenLabel;
341
+
342
+ this.leftCalendar = {
343
+ month: moment([this.startDate.year(), this.startDate.month(), 1, this.startDate.hour(), this.startDate.minute()]),
344
+ calendar: []
345
+ };
346
+
347
+ this.rightCalendar = {
348
+ month: moment([this.endDate.year(), this.endDate.month(), 1, this.endDate.hour(), this.endDate.minute()]),
349
+ calendar: []
350
+ };
351
+
352
+ if (this.opens == 'right') {
353
+ //swap calendar positions
354
+ var left = this.container.find('.calendar.left');
355
+ var right = this.container.find('.calendar.right');
356
+ left.removeClass('left').addClass('right');
357
+ right.removeClass('right').addClass('left');
358
+ }
359
+
360
+ if (typeof options.ranges === 'undefined' && !this.singleDatePicker) {
361
+ this.container.addClass('show-calendar');
362
+ }
363
+
364
+ this.container.addClass('opens' + this.opens);
365
+
366
+ this.updateView();
367
+ this.updateCalendars();
368
+
369
+ },
370
+
371
+ setStartDate: function(startDate) {
372
+ if (typeof startDate === 'string')
373
+ this.startDate = moment(startDate, this.format);
374
+
375
+ if (typeof startDate === 'object')
376
+ this.startDate = moment(startDate);
377
+
378
+ if (!this.timePicker)
379
+ this.startDate = this.startDate.startOf('day');
380
+
381
+ this.oldStartDate = this.startDate.clone();
382
+
383
+ this.updateView();
384
+ this.updateCalendars();
385
+ },
386
+
387
+ setEndDate: function(endDate) {
388
+ if (typeof endDate === 'string')
389
+ this.endDate = moment(endDate, this.format);
390
+
391
+ if (typeof endDate === 'object')
392
+ this.endDate = moment(endDate);
393
+
394
+ if (!this.timePicker)
395
+ this.endDate = this.endDate.endOf('day');
396
+
397
+ this.oldEndDate = this.endDate.clone();
398
+
399
+ this.updateView();
400
+ this.updateCalendars();
401
+ },
402
+
403
+ updateView: function () {
404
+ this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year());
405
+ this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year());
406
+ this.updateFormInputs();
407
+ },
408
+
409
+ updateFormInputs: function () {
410
+ this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format));
411
+ this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format));
412
+
413
+ if (this.startDate.isSame(this.endDate) || this.startDate.isBefore(this.endDate)) {
414
+ this.container.find('button.applyBtn').removeAttr('disabled');
415
+ } else {
416
+ this.container.find('button.applyBtn').attr('disabled', 'disabled');
417
+ }
418
+ },
419
+
420
+ updateFromControl: function () {
421
+ if (!this.element.is('input')) return;
422
+ if (!this.element.val().length) return;
423
+
424
+ var dateString = this.element.val().split(this.separator),
425
+ start = null,
426
+ end = null;
427
+
428
+ if(dateString.length === 2) {
429
+ start = moment(dateString[0], this.format);
430
+ end = moment(dateString[1], this.format);
431
+ }
432
+
433
+ if (this.singleDatePicker || start === null || end === null) {
434
+ start = moment(this.element.val(), this.format);
435
+ end = start;
436
+ }
437
+
438
+ if (end.isBefore(start)) return;
439
+
440
+ this.oldStartDate = this.startDate.clone();
441
+ this.oldEndDate = this.endDate.clone();
442
+
443
+ this.startDate = start;
444
+ this.endDate = end;
445
+
446
+ if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
447
+ this.notify();
448
+
449
+ this.updateCalendars();
450
+ },
451
+
452
+ notify: function () {
453
+ this.updateView();
454
+ this.cb(this.startDate, this.endDate, this.chosenLabel);
455
+ },
456
+
457
+ move: function () {
458
+ var parentOffset = { top: 0, left: 0 };
459
+ if (!this.parentEl.is('body')) {
460
+ parentOffset = {
461
+ top: this.parentEl.offset().top - this.parentEl.scrollTop(),
462
+ left: this.parentEl.offset().left - this.parentEl.scrollLeft()
463
+ };
464
+ }
465
+
466
+ if (this.opens == 'left') {
467
+ this.container.css({
468
+ top: this.element.offset().top + this.element.outerHeight() - parentOffset.top,
469
+ right: $(window).width() - this.element.offset().left - this.element.outerWidth() - parentOffset.left,
470
+ left: 'auto'
471
+ });
472
+ if (this.container.offset().left < 0) {
473
+ this.container.css({
474
+ right: 'auto',
475
+ left: 9
476
+ });
477
+ }
478
+ } else {
479
+ this.container.css({
480
+ top: this.element.offset().top + this.element.outerHeight() - parentOffset.top,
481
+ left: this.element.offset().left - parentOffset.left,
482
+ right: 'auto'
483
+ });
484
+ if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {
485
+ this.container.css({
486
+ left: 'auto',
487
+ right: 0
488
+ });
489
+ }
490
+ }
491
+ },
492
+
493
+ toggle: function (e) {
494
+ if (this.element.hasClass('active')) {
495
+ this.hide();
496
+ } else {
497
+ this.show();
498
+ }
499
+ },
500
+
501
+ show: function (e) {
502
+ this.element.addClass('active');
503
+ this.container.show();
504
+ this.move();
505
+
506
+ $(document).on('click.daterangepicker', $.proxy(this.outsideClick, this));
507
+ // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
508
+ $(document).on('click.daterangepicker', '[data-toggle=dropdown]', $.proxy(this.outsideClick, this));
509
+
510
+ this.element.trigger('show.daterangepicker', this);
511
+ },
512
+
513
+ outsideClick: function (e) {
514
+ var target = $(e.target);
515
+ // if the page is clicked anywhere except within the daterangerpicker/button
516
+ // itself then call this.hide()
517
+ if (
518
+ target.closest(this.element).length ||
519
+ target.closest(this.container).length ||
520
+ target.closest('.calendar-date').length
521
+ ) return;
522
+ this.hide();
523
+ },
524
+
525
+ hide: function (e) {
526
+ $(document).off('click.daterangepicker', this.outsideClick);
527
+
528
+ this.element.removeClass('active');
529
+ this.container.hide();
530
+
531
+ if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
532
+ this.notify();
533
+
534
+ this.oldStartDate = this.startDate.clone();
535
+ this.oldEndDate = this.endDate.clone();
536
+
537
+ this.element.trigger('hide.daterangepicker', this);
538
+ },
539
+
540
+ enterRange: function (e) {
541
+ // mouse pointer has entered a range label
542
+ var label = e.target.innerHTML;
543
+ if (label == this.locale.customRangeLabel) {
544
+ this.updateView();
545
+ } else {
546
+ var dates = this.ranges[label];
547
+ this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format));
548
+ this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format));
549
+ }
550
+ },
551
+
552
+ showCalendars: function() {
553
+ this.container.addClass('show-calendar');
554
+ this.move();
555
+ },
556
+
557
+ hideCalendars: function() {
558
+ this.container.removeClass('show-calendar');
559
+ },
560
+
561
+ updateInputText: function() {
562
+ if (this.element.is('input') && !this.singleDatePicker) {
563
+ this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format));
564
+ } else if (this.element.is('input')) {
565
+ this.element.val(this.startDate.format(this.format));
566
+ }
567
+ },
568
+
569
+ clickRange: function (e) {
570
+ var label = e.target.innerHTML;
571
+ this.chosenLabel = label;
572
+ if (label == this.locale.customRangeLabel) {
573
+ this.showCalendars();
574
+ } else {
575
+ var dates = this.ranges[label];
576
+
577
+ this.startDate = dates[0];
578
+ this.endDate = dates[1];
579
+
580
+ if (!this.timePicker) {
581
+ this.startDate.startOf('day');
582
+ this.endDate.endOf('day');
583
+ }
584
+
585
+ this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute());
586
+ this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute());
587
+ this.updateCalendars();
588
+
589
+ this.updateInputText();
590
+
591
+ this.hideCalendars();
592
+ this.hide();
593
+ this.element.trigger('apply.daterangepicker', this);
594
+ }
595
+ },
596
+
597
+ clickPrev: function (e) {
598
+ var cal = $(e.target).parents('.calendar');
599
+ if (cal.hasClass('left')) {
600
+ this.leftCalendar.month.subtract('month', 1);
601
+ } else {
602
+ this.rightCalendar.month.subtract('month', 1);
603
+ }
604
+ this.updateCalendars();
605
+ },
606
+
607
+ clickNext: function (e) {
608
+ var cal = $(e.target).parents('.calendar');
609
+ if (cal.hasClass('left')) {
610
+ this.leftCalendar.month.add('month', 1);
611
+ } else {
612
+ this.rightCalendar.month.add('month', 1);
613
+ }
614
+ this.updateCalendars();
615
+ },
616
+
617
+ enterDate: function (e) {
618
+
619
+ var title = $(e.target).attr('data-title');
620
+ var row = title.substr(1, 1);
621
+ var col = title.substr(3, 1);
622
+ var cal = $(e.target).parents('.calendar');
623
+
624
+ if (cal.hasClass('left')) {
625
+ this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format));
626
+ } else {
627
+ this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format));
628
+ }
629
+
630
+ },
631
+
632
+ clickDate: function (e) {
633
+ var title = $(e.target).attr('data-title');
634
+ var row = title.substr(1, 1);
635
+ var col = title.substr(3, 1);
636
+ var cal = $(e.target).parents('.calendar');
637
+
638
+ var startDate, endDate;
639
+ if (cal.hasClass('left')) {
640
+ startDate = this.leftCalendar.calendar[row][col];
641
+ endDate = this.endDate;
642
+ if (typeof this.dateLimit === 'object') {
643
+ var maxDate = moment(startDate).add(this.dateLimit).startOf('day');
644
+ if (endDate.isAfter(maxDate)) {
645
+ endDate = maxDate;
646
+ }
647
+ }
648
+ } else {
649
+ startDate = this.startDate;
650
+ endDate = this.rightCalendar.calendar[row][col];
651
+ if (typeof this.dateLimit === 'object') {
652
+ var minDate = moment(endDate).subtract(this.dateLimit).startOf('day');
653
+ if (startDate.isBefore(minDate)) {
654
+ startDate = minDate;
655
+ }
656
+ }
657
+ }
658
+
659
+ if (this.singleDatePicker && cal.hasClass('left')) {
660
+ endDate = startDate.clone();
661
+ } else if (this.singleDatePicker && cal.hasClass('right')) {
662
+ startDate = endDate.clone();
663
+ }
664
+
665
+ cal.find('td').removeClass('active');
666
+
667
+ if (startDate.isSame(endDate) || startDate.isBefore(endDate)) {
668
+ $(e.target).addClass('active');
669
+ this.startDate = startDate;
670
+ this.endDate = endDate;
671
+ this.chosenLabel = this.locale.customRangeLabel;
672
+ } else if (startDate.isAfter(endDate)) {
673
+ $(e.target).addClass('active');
674
+ var difference = this.endDate.diff(this.startDate);
675
+ this.startDate = startDate;
676
+ this.endDate = moment(startDate).add('ms', difference);
677
+ this.chosenLabel = this.locale.customRangeLabel;
678
+ }
679
+
680
+ this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year());
681
+ this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year());
682
+ this.updateCalendars();
683
+
684
+ if (!this.timePicker)
685
+ endDate.endOf('day');
686
+
687
+ if (this.singleDatePicker)
688
+ this.clickApply();
689
+ },
690
+
691
+ clickApply: function (e) {
692
+ this.updateInputText();
693
+ this.hide();
694
+ this.element.trigger('apply.daterangepicker', this);
695
+ },
696
+
697
+ clickCancel: function (e) {
698
+ this.startDate = this.oldStartDate;
699
+ this.endDate = this.oldEndDate;
700
+ this.chosenLabel = this.oldChosenLabel;
701
+ this.updateView();
702
+ this.updateCalendars();
703
+ this.hide();
704
+ this.element.trigger('cancel.daterangepicker', this);
705
+ },
706
+
707
+ updateMonthYear: function (e) {
708
+ var isLeft = $(e.target).closest('.calendar').hasClass('left'),
709
+ leftOrRight = isLeft ? 'left' : 'right',
710
+ cal = this.container.find('.calendar.'+leftOrRight);
711
+
712
+ // Month must be Number for new moment versions
713
+ var month = parseInt(cal.find('.monthselect').val(), 10);
714
+ var year = cal.find('.yearselect').val();
715
+
716
+ this[leftOrRight+'Calendar'].month.month(month).year(year);
717
+ this.updateCalendars();
718
+ },
719
+
720
+ updateTime: function(e) {
721
+ var isLeft = $(e.target).closest('.calendar').hasClass('left'),
722
+ leftOrRight = isLeft ? 'left' : 'right',
723
+ cal = this.container.find('.calendar.'+leftOrRight);
724
+
725
+ var hour = parseInt(cal.find('.hourselect').val(), 10);
726
+ var minute = parseInt(cal.find('.minuteselect').val(), 10);
727
+
728
+ if (this.timePicker12Hour) {
729
+ var ampm = cal.find('.ampmselect').val();
730
+ if (ampm === 'PM' && hour < 12)
731
+ hour += 12;
732
+ if (ampm === 'AM' && hour === 12)
733
+ hour = 0;
734
+ }
735
+
736
+ if (isLeft) {
737
+ var start = this.startDate.clone();
738
+ start.hour(hour);
739
+ start.minute(minute);
740
+ this.startDate = start;
741
+ this.leftCalendar.month.hour(hour).minute(minute);
742
+ } else {
743
+ var end = this.endDate.clone();
744
+ end.hour(hour);
745
+ end.minute(minute);
746
+ this.endDate = end;
747
+ this.rightCalendar.month.hour(hour).minute(minute);
748
+ }
749
+
750
+ this.updateCalendars();
751
+ },
752
+
753
+ updateCalendars: function () {
754
+ this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.month(), this.leftCalendar.month.year(), this.leftCalendar.month.hour(), this.leftCalendar.month.minute(), 'left');
755
+ this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.month(), this.rightCalendar.month.year(), this.rightCalendar.month.hour(), this.rightCalendar.month.minute(), 'right');
756
+ this.container.find('.calendar.left').empty().html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate));
757
+ this.container.find('.calendar.right').empty().html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.startDate, this.maxDate));
758
+
759
+ this.container.find('.ranges li').removeClass('active');
760
+ var customRange = true;
761
+ var i = 0;
762
+ for (var range in this.ranges) {
763
+ if (this.timePicker) {
764
+ if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) {
765
+ customRange = false;
766
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')
767
+ .addClass('active').html();
768
+ }
769
+ } else {
770
+ //ignore times when comparing dates if time picker is not enabled
771
+ 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')) {
772
+ customRange = false;
773
+ this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')
774
+ .addClass('active').html();
775
+ }
776
+ }
777
+ i++;
778
+ }
779
+ if (customRange) {
780
+ this.chosenLabel = this.container.find('.ranges li:last')
781
+ .addClass('active').html();
782
+ }
783
+ },
784
+
785
+ buildCalendar: function (month, year, hour, minute, side) {
786
+ var firstDay = moment([year, month, 1]);
787
+ var lastMonth = moment(firstDay).subtract('month', 1).month();
788
+ var lastYear = moment(firstDay).subtract('month', 1).year();
789
+
790
+ var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
791
+
792
+ var dayOfWeek = firstDay.day();
793
+
794
+ var i;
795
+
796
+ //initialize a 6 rows x 7 columns array for the calendar
797
+ var calendar = [];
798
+ for (i = 0; i < 6; i++) {
799
+ calendar[i] = [];
800
+ }
801
+
802
+ //populate the calendar with date objects
803
+ var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
804
+ if (startDay > daysInLastMonth)
805
+ startDay -= 7;
806
+
807
+ if (dayOfWeek == this.locale.firstDay)
808
+ startDay = daysInLastMonth - 6;
809
+
810
+ var curDate = moment([lastYear, lastMonth, startDay, 12, minute]);
811
+ var col, row;
812
+ for (i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add('hour', 24)) {
813
+ if (i > 0 && col % 7 === 0) {
814
+ col = 0;
815
+ row++;
816
+ }
817
+ calendar[row][col] = curDate.clone().hour(hour);
818
+ curDate.hour(12);
819
+ }
820
+
821
+ return calendar;
822
+ },
823
+
824
+ renderDropdowns: function (selected, minDate, maxDate) {
825
+ var currentMonth = selected.month();
826
+ var monthHtml = '<select class="monthselect">';
827
+ var inMinYear = false;
828
+ var inMaxYear = false;
829
+
830
+ for (var m = 0; m < 12; m++) {
831
+ if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {
832
+ monthHtml += "<option value='" + m + "'" +
833
+ (m === currentMonth ? " selected='selected'" : "") +
834
+ ">" + this.locale.monthNames[m] + "</option>";
835
+ }
836
+ }
837
+ monthHtml += "</select>";
838
+
839
+ var currentYear = selected.year();
840
+ var maxYear = (maxDate && maxDate.year()) || (currentYear + 5);
841
+ var minYear = (minDate && minDate.year()) || (currentYear - 50);
842
+ var yearHtml = '<select class="yearselect">';
843
+
844
+ for (var y = minYear; y <= maxYear; y++) {
845
+ yearHtml += '<option value="' + y + '"' +
846
+ (y === currentYear ? ' selected="selected"' : '') +
847
+ '>' + y + '</option>';
848
+ }
849
+
850
+ yearHtml += '</select>';
851
+
852
+ return monthHtml + yearHtml;
853
+ },
854
+
855
+ renderCalendar: function (calendar, selected, minDate, maxDate) {
856
+
857
+ var html = '<div class="calendar-date">';
858
+ html += '<table class="table-condensed">';
859
+ html += '<thead>';
860
+ html += '<tr>';
861
+
862
+ // add empty cell for week number
863
+ if (this.showWeekNumbers)
864
+ html += '<th></th>';
865
+
866
+ if (!minDate || minDate.isBefore(calendar[1][1])) {
867
+ html += '<th class="prev available"><i class="fa fa-arrow-left icon-arrow-left glyphicon glyphicon-arrow-left"></i></th>';
868
+ } else {
869
+ html += '<th></th>';
870
+ }
871
+
872
+ var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
873
+
874
+ if (this.showDropdowns) {
875
+ dateHtml = this.renderDropdowns(calendar[1][1], minDate, maxDate);
876
+ }
877
+
878
+ html += '<th colspan="5" class="month">' + dateHtml + '</th>';
879
+ if (!maxDate || maxDate.isAfter(calendar[1][1])) {
880
+ html += '<th class="next available"><i class="fa fa-arrow-right icon-arrow-right glyphicon glyphicon-arrow-right"></i></th>';
881
+ } else {
882
+ html += '<th></th>';
883
+ }
884
+
885
+ html += '</tr>';
886
+ html += '<tr>';
887
+
888
+ // add week number label
889
+ if (this.showWeekNumbers)
890
+ html += '<th class="week">' + this.locale.weekLabel + '</th>';
891
+
892
+ $.each(this.locale.daysOfWeek, function (index, dayOfWeek) {
893
+ html += '<th>' + dayOfWeek + '</th>';
894
+ });
895
+
896
+ html += '</tr>';
897
+ html += '</thead>';
898
+ html += '<tbody>';
899
+
900
+ for (var row = 0; row < 6; row++) {
901
+ html += '<tr>';
902
+
903
+ // add week number
904
+ if (this.showWeekNumbers)
905
+ html += '<td class="week">' + calendar[row][0].week() + '</td>';
906
+
907
+ for (var col = 0; col < 7; col++) {
908
+ var cname = 'available ';
909
+ cname += (calendar[row][col].month() == calendar[1][1].month()) ? '' : 'off';
910
+
911
+ if ((minDate && calendar[row][col].isBefore(minDate)) || (maxDate && calendar[row][col].isAfter(maxDate))) {
912
+ cname = ' off disabled ';
913
+ } else if (calendar[row][col].format('YYYY-MM-DD') == selected.format('YYYY-MM-DD')) {
914
+ cname += ' active ';
915
+ if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) {
916
+ cname += ' start-date ';
917
+ }
918
+ if (calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) {
919
+ cname += ' end-date ';
920
+ }
921
+ } else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) {
922
+ cname += ' in-range ';
923
+ if (calendar[row][col].isSame(this.startDate)) { cname += ' start-date '; }
924
+ if (calendar[row][col].isSame(this.endDate)) { cname += ' end-date '; }
925
+ }
926
+
927
+ var title = 'r' + row + 'c' + col;
928
+ html += '<td class="' + cname.replace(/\s+/g, ' ').replace(/^\s?(.*?)\s?$/, '$1') + '" data-title="' + title + '">' + calendar[row][col].date() + '</td>';
929
+ }
930
+ html += '</tr>';
931
+ }
932
+
933
+ html += '</tbody>';
934
+ html += '</table>';
935
+ html += '</div>';
936
+
937
+ var i;
938
+ if (this.timePicker) {
939
+
940
+ html += '<div class="calendar-time">';
941
+ html += '<select class="hourselect">';
942
+ var start = 0;
943
+ var end = 23;
944
+ var selected_hour = selected.hour();
945
+ if (this.timePicker12Hour) {
946
+ start = 1;
947
+ end = 12;
948
+ if (selected_hour >= 12)
949
+ selected_hour -= 12;
950
+ if (selected_hour === 0)
951
+ selected_hour = 12;
952
+ }
953
+
954
+ for (i = start; i <= end; i++) {
955
+ if (i == selected_hour) {
956
+ html += '<option value="' + i + '" selected="selected">' + i + '</option>';
957
+ } else {
958
+ html += '<option value="' + i + '">' + i + '</option>';
959
+ }
960
+ }
961
+
962
+ html += '</select> : ';
963
+
964
+ html += '<select class="minuteselect">';
965
+
966
+ for (i = 0; i < 60; i += this.timePickerIncrement) {
967
+ var num = i;
968
+ if (num < 10)
969
+ num = '0' + num;
970
+ if (i == selected.minute()) {
971
+ html += '<option value="' + i + '" selected="selected">' + num + '</option>';
972
+ } else {
973
+ html += '<option value="' + i + '">' + num + '</option>';
974
+ }
975
+ }
976
+
977
+ html += '</select> ';
978
+
979
+ if (this.timePicker12Hour) {
980
+ html += '<select class="ampmselect">';
981
+ if (selected.hour() >= 12) {
982
+ html += '<option value="AM">AM</option><option value="PM" selected="selected">PM</option>';
983
+ } else {
984
+ html += '<option value="AM" selected="selected">AM</option><option value="PM">PM</option>';
985
+ }
986
+ html += '</select>';
987
+ }
988
+
989
+ html += '</div>';
990
+
991
+ }
992
+
993
+ return html;
994
+
995
+ },
996
+
997
+ remove: function() {
998
+
999
+ this.container.remove();
1000
+ this.element.off('.daterangepicker');
1001
+ this.element.removeData('daterangepicker');
1002
+
1003
+ }
1004
+
1005
+ };
1006
+
1007
+ $.fn.daterangepicker = function (options, cb) {
1008
+ this.each(function () {
1009
+ var el = $(this);
1010
+ if (el.data('daterangepicker'))
1011
+ el.data('daterangepicker').remove();
1012
+ el.data('daterangepicker', new DateRangePicker(el, options, cb));
1013
+ });
1014
+ return this;
1015
+ };
1016
+
1017
+ }(window.jQuery, window.moment);