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