1/** 2* @version: 3.1 3* @author: Dan Grossman http://www.dangrossman.info/ 4* @copyright: Copyright (c) 2012-2019 Dan Grossman. All rights reserved. 5* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6* @website: http://www.daterangepicker.com/ 7*/ 8// Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js 9(function (root, factory) { 10 if (typeof define === 'function' && define.amd) { 11 // AMD. Make globaly available as well 12 define(['moment', 'jquery'], function (moment, jquery) { 13 if (!jquery.fn) jquery.fn = {}; // webpack server rendering 14 if (typeof moment !== 'function' && moment.hasOwnProperty('default')) moment = moment['default'] 15 return factory(moment, jquery); 16 }); 17 } else if (typeof module === 'object' && module.exports) { 18 // Node / Browserify 19 //isomorphic issue 20 var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined; 21 if (!jQuery) { 22 jQuery = require('jquery'); 23 if (!jQuery.fn) jQuery.fn = {}; 24 } 25 var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment'); 26 module.exports = factory(moment, jQuery); 27 } else { 28 // Browser globals 29 root.daterangepicker = factory(root.moment, root.jQuery); 30 } 31}(typeof window !== 'undefined' ? window : this, function (moment, $) { 32 var DateRangePicker = function (element, options, cb) { 33 34 // var today = new Date(); 35 // var tomorrow = new Date(); 36 // var ddd = tomorrow.setDate(today.getDate()); 37 // this.ccc = today.getDate() + 1; 38 39 //default settings for options 40 this.parentEl = 'body'; 41 this.element = $(element); 42 this.minDate = moment().add(1, 'day'); 43 this.maxDate = moment().add(1, 'day').add(730, 'days'); 44 this.startDate = moment().add(1, 'day'); 45 46 // this.endDate = moment().add(1, 'day').add(90,'days'); 47 this.endDate = moment().add(1, 'day'); 48 49 dateLimit = { days: 90 }; 50 // this.startDate = moment().startOf('day').add(1, 'day'); 51 // this.startDate = moment().startOf('day'); 52 // this.endDate = moment().endOf('day'); 53 this.maxSpan = false; 54 this.autoApply = false; 55 56 this.showDropdowns = false; 57 this.minYear = moment().subtract(100, 'year').format('YYYY'); 58 this.maxYear = moment().add(100, 'year').format('YYYY'); 59 this.showWeekNumbers = false; 60 this.showISOWeekNumbers = false; 61 this.showCustomRangeLabel = true; 62 this.timePicker = false; 63 this.timePicker24Hour = false; 64 this.timePickerIncrement = 1; 65 this.timePickerSeconds = false; 66 this.linkedCalendars = true; 67 this.autoUpdateInput = true; 68 this.alwaysShowCalendars = false; 69 this.ranges = { 70 'Today': [moment(), moment()], 71 'Yesterday': [moment().subtract('days', 1), moment().subtract('days', 1)], 72 'Last 7 Days': [moment().subtract('days', 6), moment()], 73 'Last 30 Days': [moment().subtract('days', 29), moment()], 74 'This Month': [moment().startOf('month'), moment().endOf('month')], 75 'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')] 76 }; 77 78 this.opens = 'right'; 79 if (this.element.hasClass('pull-right')) 80 this.opens = 'left'; 81 82 this.drops = 'down'; 83 if (this.element.hasClass('dropup')) 84 this.drops = 'up'; 85 86 this.buttonClasses = 'btn btn-sm'; 87 this.applyButtonClasses = 'btn-primary'; 88 this.cancelButtonClasses = 'btn-default'; 89 90 this.locale = { 91 direction: 'ltr', 92 format: moment.localeData().longDateFormat('L'), 93 separator: ' - ', 94 applyLabel: 'DONE', 95 cancelLabel: 'Clear', 96 weekLabel: 'W', 97 customRangeLabel: 'Custom Range',
vendor: 48,451 bytes, lines 98-1188
98 daysOfWeek: moment.weekdaysMin(), 99 monthNames: moment.months(), 100 firstDay: moment.localeData().firstDayOfWeek() 101 }; 102 103 this.callback = function () { }; 104 105 //some state information 106 this.isShowing = false; 107 this.leftCalendar = {}; 108 this.rightCalendar = {}; 109 110 //custom options from user 111 if (typeof options !== 'object' || options === null) 112 options = {}; 113 114 //allow setting options with data attributes 115 //data-api options will be overwritten with custom javascript options 116 options = $.extend(this.element.data(), options); 117 118 //html template for the picker UI 119 if (typeof options.template !== 'string' && !(options.template instanceof $)) 120 options.template = 121 /* '<div class="daterangepicker">' + 122 // '<div class="drp-buttons drp-buttonstop">' + 123 // '<span class="drp-selected1"><i class="fa fa-angle-left back-button" aria-hidden="true"></i><span class="drp-selected1-text"> Back </span></span>' + 124 // '<span class="drp-selected"></span>' + 125 126 // '</div>' + 127 '<div class="drp-calendar left">' + 128 '<div class="calendar-table"></div>' + 129 '<div class="calendar-time"></div>' + 130 '</div>' + 131 '<div class="drp-calendar right">' + 132 '<div class="calendar-table"></div>' + 133 '<div class="calendar-time"></div>' + 134 '</div>' + 135 '<div class="drp-buttons drp-buttonsbottom">' + 136 '<button class="cancelBtn" type="button"></button>' + 137 '<button class="applyBtn" disabled="disabled" type="button"></button> ' + 138 '</div>' + 139 '</div>'; */ 140 141 '<div class="daterangepicker">' + 142 '<div class="drp-buttons for-mobile-date">' + 143 '<span class="btn-wrap-back"><button class="backBtn" type="button"><i class="fa fa-angle-left back-button" aria-hidden="true"></i> Back</button></span>' + 144 '<span class="drp-selected"></span>' + 145 146 '</div>' + 147 '<div class="drp-calendar left">' + 148 '<div class="calendar-table"></div>' + 149 '<div class="calendar-time"></div>' + 150 '</div>' + 151 '<div class="drp-calendar right">' + 152 '<div class="calendar-table"></div>' + 153 '<div class="calendar-time"></div>' + 154 '</div>' + 155 '<div class="drp-buttons drp-buttonsbottom">' + 156 '<button class="cancelBtn" type="button"></button>' + 157 '<button class="applyBtn" disabled="disabled" type="button"></button> ' + 158 '</div>' + 159 '</div>'; 160 161 162 this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl); 163 this.container = $(options.template).appendTo(this.parentEl); 164 165 // 166 // handle all the possible options overriding defaults 167 // 168 169 if (typeof options.locale === 'object') { 170 171 if (typeof options.locale.direction === 'string') 172 this.locale.direction = options.locale.direction; 173 174 if (typeof options.locale.format === 'string') 175 this.locale.format = options.locale.format; 176 177 if (typeof options.locale.separator === 'string') 178 this.locale.separator = options.locale.separator; 179 180 if (typeof options.locale.daysOfWeek === 'object') 181 this.locale.daysOfWeek = options.locale.daysOfWeek.slice(); 182 183 if (typeof options.locale.monthNames === 'object') 184 this.locale.monthNames = options.locale.monthNames.slice(); 185 186 if (typeof options.locale.firstDay === 'number') 187 this.locale.firstDay = options.locale.firstDay; 188 189 if (typeof options.locale.applyLabel === 'string') 190 this.locale.applyLabel = options.locale.applyLabel; 191 192 if (typeof options.locale.cancelLabel === 'string') 193 this.locale.cancelLabel = options.locale.cancelLabel; 194 195 if (typeof options.locale.weekLabel === 'string') 196 this.locale.weekLabel = options.locale.weekLabel; 197 198 if (typeof options.locale.customRangeLabel === 'string') { 199 //Support unicode chars in the custom range name. 200 var elem = document.createElement('textarea'); 201 elem.innerHTML = options.locale.customRangeLabel; 202 var rangeHtml = elem.value; 203 this.locale.customRangeLabel = rangeHtml; 204 } 205 } 206 this.container.addClass(this.locale.direction); 207 208 if (typeof options.startDate === 'string') 209 this.startDate = moment(options.startDate, this.locale.format); 210 211 if (typeof options.endDate === 'string') 212 this.endDate = moment(options.endDate, this.locale.format); 213 214 if (typeof options.minDate === 'string') 215 this.minDate = moment(options.minDate, this.locale.format); 216 217 if (typeof options.maxDate === 'string') 218 this.maxDate = moment(options.maxDate, this.locale.format); 219 220 if (typeof options.startDate === 'object') 221 this.startDate = moment(options.startDate); 222 223 if (typeof options.endDate === 'object') 224 this.endDate = moment(options.endDate); 225 226 if (typeof options.minDate === 'object') 227 this.minDate = moment(options.minDate); 228 229 if (typeof options.maxDate === 'object') 230 this.maxDate = moment(options.maxDate); 231 232 // sanity check for bad options 233 if (this.minDate && this.startDate.isBefore(this.minDate)) 234 this.startDate = this.minDate.clone(); 235 236 // sanity check for bad options 237 if (this.maxDate && this.endDate.isAfter(this.maxDate)) 238 this.endDate = this.maxDate.clone(); 239 240 if (typeof options.applyButtonClasses === 'string') 241 this.applyButtonClasses = options.applyButtonClasses; 242 243 if (typeof options.applyClass === 'string') //backwards compat 244 this.applyButtonClasses = options.applyClass; 245 246 if (typeof options.cancelButtonClasses === 'string') 247 this.cancelButtonClasses = options.cancelButtonClasses; 248 249 if (typeof options.cancelClass === 'string') //backwards compat 250 this.cancelButtonClasses = options.cancelClass; 251 252 if (typeof options.maxSpan === 'object') 253 this.maxSpan = options.maxSpan; 254 255 if (typeof options.dateLimit === 'object') //backwards compat 256 this.maxSpan = options.dateLimit; 257 258 if (typeof options.opens === 'string') 259 this.opens = options.opens; 260 261 if (typeof options.drops === 'string') 262 this.drops = options.drops; 263 264 if (typeof options.showWeekNumbers === 'boolean') 265 this.showWeekNumbers = options.showWeekNumbers; 266 267 if (typeof options.showISOWeekNumbers === 'boolean') 268 this.showISOWeekNumbers = options.showISOWeekNumbers; 269 270 if (typeof options.buttonClasses === 'string') 271 this.buttonClasses = options.buttonClasses; 272 273 if (typeof options.buttonClasses === 'object') 274 this.buttonClasses = options.buttonClasses.join(' '); 275 276 if (typeof options.showDropdowns === 'boolean') 277 this.showDropdowns = options.showDropdowns; 278 279 if (typeof options.minYear === 'number') 280 this.minYear = options.minYear; 281 282 if (typeof options.maxYear === 'number') 283 this.maxYear = options.maxYear; 284 285 if (typeof options.showCustomRangeLabel === 'boolean') 286 this.showCustomRangeLabel = options.showCustomRangeLabel; 287 288 if (typeof options.singleDatePicker === 'boolean') { 289 this.singleDatePicker = options.singleDatePicker; 290 if (this.singleDatePicker) 291 this.endDate = this.startDate.clone(); 292 } 293 294 if (typeof options.timePicker === 'boolean') 295 this.timePicker = options.timePicker; 296 297 if (typeof options.timePickerSeconds === 'boolean') 298 this.timePickerSeconds = options.timePickerSeconds; 299 300 if (typeof options.timePickerIncrement === 'number') 301 this.timePickerIncrement = options.timePickerIncrement; 302 303 if (typeof options.timePicker24Hour === 'boolean') 304 this.timePicker24Hour = options.timePicker24Hour; 305 306 if (typeof options.autoApply === 'boolean') 307 this.autoApply = options.autoApply; 308 309 if (typeof options.autoUpdateInput === 'boolean') 310 this.autoUpdateInput = options.autoUpdateInput; 311 312 if (typeof options.linkedCalendars === 'boolean') 313 this.linkedCalendars = options.linkedCalendars; 314 315 if (typeof options.isInvalidDate === 'function') 316 this.isInvalidDate = options.isInvalidDate; 317 318 if (typeof options.isCustomDate === 'function') 319 this.isCustomDate = options.isCustomDate; 320 321 if (typeof options.alwaysShowCalendars === 'boolean') 322 this.alwaysShowCalendars = options.alwaysShowCalendars; 323 324 // update day names order to firstDay 325 if (this.locale.firstDay != 0) { 326 var iterator = this.locale.firstDay; 327 while (iterator > 0) { 328 this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); 329 iterator--; 330 } 331 } 332 333 var start, end, range; 334 335 //if no start/end dates set, check if an input element contains initial values 336 if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') { 337 if ($(this.element).is(':text')) { 338 var val = $(this.element).val(), 339 split = val.split(this.locale.separator); 340 341 start = end = null; 342 343 if (split.length == 2) { 344 start = moment(split[0], this.locale.format); 345 end = moment(split[1], this.locale.format); 346 } else if (this.singleDatePicker && val !== "") { 347 start = moment(val, this.locale.format); 348 end = moment(val, this.locale.format); 349 } 350 if (start !== null && end !== null) { 351 this.setStartDate(start); 352 this.setEndDate(end); 353 } 354 } 355 } 356 357 if (typeof options.ranges === 'object') { 358 for (range in options.ranges) { 359 360 if (typeof options.ranges[range][0] === 'string') 361 start = moment(options.ranges[range][0], this.locale.format); 362 else 363 start = moment(options.ranges[range][0]); 364 365 if (typeof options.ranges[range][1] === 'string') 366 end = moment(options.ranges[range][1], this.locale.format); 367 else 368 end = moment(options.ranges[range][1]); 369 370 // If the start or end date exceed those allowed by the minDate or maxSpan 371 // options, shorten the range to the allowable period. 372 if (this.minDate && start.isBefore(this.minDate)) 373 start = this.minDate.clone(); 374 375 var maxDate = this.maxDate; 376 if (this.maxSpan && maxDate && start.clone().add(this.maxSpan).isAfter(maxDate)) 377 maxDate = start.clone().add(this.maxSpan); 378 if (maxDate && end.isAfter(maxDate)) 379 end = maxDate.clone(); 380 381 // If the end of the range is before the minimum or the start of the range is 382 // after the maximum, don't display this range option at all. 383 if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day')) 384 || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day'))) 385 continue; 386 387 //Support unicode chars in the range names. 388 var elem = document.createElement('textarea'); 389 elem.innerHTML = range; 390 var rangeHtml = elem.value; 391 392 this.ranges[rangeHtml] = [start, end]; 393 } 394 395 var list = '<ul>'; 396 for (range in this.ranges) { 397 list += '<li data-range-key="' + range + '">' + range + '</li>'; 398 } 399 if (this.showCustomRangeLabel) { 400 list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>'; 401 } 402 list += '</ul>'; 403 this.container.find('.ranges').prepend(list); 404 } 405 406 if (typeof cb === 'function') { 407 this.callback = cb; 408 } 409 410 if (!this.timePicker) { 411 this.startDate = this.startDate.startOf('day'); 412 this.endDate = this.endDate.endOf('day'); 413 this.container.find('.calendar-time').hide(); 414 } 415 416 //can't be used together for now 417 if (this.timePicker && this.autoApply) 418 this.autoApply = false; 419 420 if (this.autoApply) { 421 this.container.addClass('auto-apply'); 422 } 423 424 if (typeof options.ranges === 'object') 425 this.container.addClass('show-ranges'); 426 427 if (this.singleDatePicker) { 428 this.container.addClass('single'); 429 this.container.find('.drp-calendar.left').addClass('single'); 430 this.container.find('.drp-calendar.left').show(); 431 this.container.find('.drp-calendar.right').hide(); 432 if (!this.timePicker && this.autoApply) { 433 this.container.addClass('auto-apply'); 434 } 435 } 436 437 if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) { 438 this.container.addClass('show-calendar'); 439 } 440 441 this.container.addClass('opens' + this.opens); 442 443 //apply CSS classes and labels to buttons 444 this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses); 445 if (this.applyButtonClasses.length) 446 this.container.find('.applyBtn').addClass(this.applyButtonClasses); 447 if (this.cancelButtonClasses.length) 448 this.container.find('.cancelBtn').addClass(this.cancelButtonClasses); 449 this.container.find('.applyBtn').html(this.locale.applyLabel); 450 this.container.find('.cancelBtn').html(this.locale.cancelLabel); 451 452 // 453 // event listeners 454 // 455 456 this.container.find('.drp-calendar') 457 .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this)) 458 .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this)) 459 .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this)) 460 .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)) 461 .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this)) 462 .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this)) 463 .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)); 464 465 this.container.find('.ranges') 466 .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)); 467 468 this.container.find('.drp-buttons') 469 .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)) 470 .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)) 471 .on('click.daterangepicker', 'button.backBtn', $.proxy(this.clickBack, this)); 472 473 if (this.element.is('input') || this.element.is('button')) { 474 this.element.on({ 475 'click.daterangepicker': $.proxy(this.show, this), 476 'focus.daterangepicker': $.proxy(this.show, this), 477 'keyup.daterangepicker': $.proxy(this.elementChanged, this), 478 'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility 479 }); 480 } else { 481 this.element.on('click.daterangepicker', $.proxy(this.toggle, this)); 482 this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this)); 483 } 484 485 // 486 // if attached to a text input, set the initial value 487 // 488 489 this.updateElement(); 490 491 }; 492 493 DateRangePicker.prototype = { 494 495 constructor: DateRangePicker, 496 497 setStartDate: function (startDate) { 498 if (typeof startDate === 'string') 499 this.startDate = moment(startDate, this.locale.format); 500 501 if (typeof startDate === 'object') 502 this.startDate = moment(startDate); 503 504 if (!this.timePicker) 505 this.startDate = this.startDate.startOf('day'); 506 507 if (this.timePicker && this.timePickerIncrement) 508 this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 509 510 if (this.minDate && this.startDate.isBefore(this.minDate)) { 511 this.startDate = this.minDate.clone(); 512 if (this.timePicker && this.timePickerIncrement) 513 this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 514 } 515 516 if (this.maxDate && this.startDate.isAfter(this.maxDate)) { 517 this.startDate = this.maxDate.clone(); 518 if (this.timePicker && this.timePickerIncrement) 519 this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 520 } 521 522 if (!this.isShowing) 523 this.updateElement(); 524 525 this.updateMonthsInView(); 526 }, 527 528 setEndDate: function (endDate) { 529 if (typeof endDate === 'string') 530 this.endDate = moment(endDate, this.locale.format); 531 532 if (typeof endDate === 'object') 533 this.endDate = moment(endDate); 534 535 if (!this.timePicker) 536 this.endDate = this.endDate.endOf('day'); 537 538 if (this.timePicker && this.timePickerIncrement) 539 this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 540 541 if (this.endDate.isBefore(this.startDate)) 542 this.endDate = this.startDate.clone(); 543 544 if (this.maxDate && this.endDate.isAfter(this.maxDate)) 545 this.endDate = this.maxDate.clone(); 546 547 if (this.maxSpan && this.startDate.clone().add(this.maxSpan).isBefore(this.endDate)) 548 this.endDate = this.startDate.clone().add(this.maxSpan); 549 550 this.previousRightTime = this.endDate.clone(); 551 552 // this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + '<span class="vl"></span>' + this.endDate.format(this.locale.format)); 553 //this.container.find('.drp-selected').html(this.startDate.format('MM/DD/YYYY') + '<span class="vl"></span>' + this.endDate.format('MM/DD/YYYY')); 554 555 556 557 558 if (!this.isShowing) 559 this.updateElement(); 560 561 this.updateMonthsInView(); 562 }, 563 564 isInvalidDate: function () { 565 return false; 566 }, 567 568 isCustomDate: function () { 569 return false; 570 }, 571 572 updateView: function () { 573 if (this.timePicker) { 574 this.renderTimePicker('left'); 575 this.renderTimePicker('right'); 576 if (!this.endDate) { 577 this.container.find('.right .calendar-time select').prop('disabled', true).addClass('disabled'); 578 } else { 579 this.container.find('.right .calendar-time select').prop('disabled', false).removeClass('disabled'); 580 } 581 } 582 if (this.endDate) 583 //this.container.find('.drp-selected').html(this.startDate.format('MM/DD/YYYY') + '<span class="vl"></span>' + this.endDate.format('MM/DD/YYYY')); 584 this.updateMonthsInView(); 585 this.updateCalendars(); 586 this.updateFormInputs(); 587 }, 588 589 updateMonthsInView: function () { 590 if (this.endDate) { 591 592 //if both dates are visible already, do nothing 593 if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month && 594 (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) 595 && 596 (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) 597 ) { 598 return; 599 } 600 601 this.leftCalendar.month = this.startDate.clone().date(2); 602 if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) { 603 this.rightCalendar.month = this.endDate.clone().date(2); 604 } else { 605 this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); 606 } 607 608 } else { 609 if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) { 610 this.leftCalendar.month = this.startDate.clone().date(2); 611 this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); 612 } 613 } 614 if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) { 615 this.rightCalendar.month = this.maxDate.clone().date(2); 616 this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month'); 617 } 618 }, 619 620 updateCalendars: function () { 621 622 if (this.timePicker) { 623 var hour, minute, second; 624 if (this.endDate) { 625 hour = parseInt(this.container.find('.left .hourselect').val(), 10); 626 minute = parseInt(this.container.find('.left .minuteselect').val(), 10); 627 if (isNaN(minute)) { 628 minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10); 629 } 630 second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; 631 if (!this.timePicker24Hour) { 632 var ampm = this.container.find('.left .ampmselect').val(); 633 if (ampm === 'PM' && hour < 12) 634 hour += 12; 635 if (ampm === 'AM' && hour === 12) 636 hour = 0; 637 } 638 } else { 639 hour = parseInt(this.container.find('.right .hourselect').val(), 10); 640 minute = parseInt(this.container.find('.right .minuteselect').val(), 10); 641 if (isNaN(minute)) { 642 minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10); 643 } 644 second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; 645 if (!this.timePicker24Hour) { 646 var ampm = this.container.find('.right .ampmselect').val(); 647 if (ampm === 'PM' && hour < 12) 648 hour += 12; 649 if (ampm === 'AM' && hour === 12) 650 hour = 0; 651 } 652 } 653 this.leftCalendar.month.hour(hour).minute(minute).second(second); 654 this.rightCalendar.month.hour(hour).minute(minute).second(second); 655 } 656 657 this.renderCalendar('left'); 658 this.renderCalendar('right'); 659 660 //highlight any predefined range matching the current start and end dates 661 this.container.find('.ranges li').removeClass('active'); 662 if (this.endDate == null) return; 663 664 this.calculateChosenLabel(); 665 }, 666 667 renderCalendar: function (side) { 668 669 // 670 // Build the matrix of dates that will populate the calendar 671 // 672 673 var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar; 674 var month = calendar.month.month(); 675 var year = calendar.month.year(); 676 var hour = calendar.month.hour(); 677 var minute = calendar.month.minute(); 678 var second = calendar.month.second(); 679 var daysInMonth = moment([year, month]).daysInMonth(); 680 var firstDay = moment([year, month, 1]); 681 var lastDay = moment([year, month, daysInMonth]); 682 var lastMonth = moment(firstDay).subtract(1, 'month').month(); 683 var lastYear = moment(firstDay).subtract(1, 'month').year(); 684 var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth(); 685 var dayOfWeek = firstDay.day(); 686 687 //initialize a 6 rows x 7 columns array for the calendar 688 var calendar = []; 689 calendar.firstDay = firstDay; 690 calendar.lastDay = lastDay; 691 692 for (var i = 0; i < 6; i++) { 693 calendar[i] = []; 694 } 695 696 //populate the calendar with date objects 697 var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; 698 if (startDay > daysInLastMonth) 699 startDay -= 7; 700 701 if (dayOfWeek == this.locale.firstDay) 702 startDay = daysInLastMonth - 6; 703 704 var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]); 705 706 var col, row; 707 for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) { 708 if (i > 0 && col % 7 === 0) { 709 col = 0; 710 row++; 711 } 712 calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second); 713 curDate.hour(12); 714 715 if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') { 716 calendar[row][col] = this.minDate.clone(); 717 } 718 719 if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') { 720 calendar[row][col] = this.maxDate.clone(); 721 } 722 723 } 724 725 //make the calendar object available to hoverDate/clickDate 726 if (side == 'left') { 727 this.leftCalendar.calendar = calendar; 728 } else { 729 this.rightCalendar.calendar = calendar; 730 } 731 732 // 733 // Display the calendar 734 // 735 736 var minDate = side == 'left' ? this.minDate : this.startDate; 737 var maxDate = this.maxDate; 738 var selected = side == 'left' ? this.startDate : this.endDate; 739 var arrow = this.locale.direction == 'ltr' ? { left: 'chevron-left', right: 'chevron-right' } : { left: 'chevron-right', right: 'chevron-left' }; 740 741 var html = '<table class="table-condensed">'; 742 html += '<thead>'; 743 html += '<tr>'; 744 745 // add empty cell for week number 746 if (this.showWeekNumbers || this.showISOWeekNumbers) 747 html += '<th></th>'; 748 749 if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) { 750 html += '<th class="prev available"><span></span></th>'; 751 } else { 752 html += '<th></th>'; 753 } 754 755 //var dateHtml = this.locale.monthNames[calendar[1][1].month()]; 756 var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY"); 757 758 if (this.showDropdowns) { 759 var currentMonth = calendar[1][1].month(); 760 var currentYear = calendar[1][1].year(); 761 var maxYear = (maxDate && maxDate.year()) || (this.maxYear); 762 var minYear = (minDate && minDate.year()) || (this.minYear); 763 var inMinYear = currentYear == minYear; 764 var inMaxYear = currentYear == maxYear; 765 766 var monthHtml = '<select class="monthselect">'; 767 for (var m = 0; m < 12; m++) { 768 if ((!inMinYear || (minDate && m >= minDate.month())) && (!inMaxYear || (maxDate && m <= maxDate.month()))) { 769 monthHtml += "<option value='" + m + "'" + 770 (m === currentMonth ? " selected='selected'" : "") + 771 ">" + this.locale.monthNames[m] + "</option>"; 772 } else { 773 monthHtml += "<option value='" + m + "'" + 774 (m === currentMonth ? " selected='selected'" : "") + 775 " disabled='disabled'>" + this.locale.monthNames[m] + "</option>"; 776 } 777 } 778 monthHtml += "</select>"; 779 780 var yearHtml = '<select class="yearselect">'; 781 for (var y = minYear; y <= maxYear; y++) { 782 yearHtml += '<option value="' + y + '"' + 783 (y === currentYear ? ' selected="selected"' : '') + 784 '>' + y + '</option>'; 785 } 786 yearHtml += '</select>'; 787 788 dateHtml = monthHtml; 789 } 790 791 html += '<th colspan="5" class="month">' + dateHtml + '</th>'; 792 if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) { 793 html += '<th class="next available"><span></span></th>'; 794 } else { 795 html += '<th></th>'; 796 } 797 798 html += '</tr>'; 799 html += '<tr>'; 800 801 // add week number label 802 if (this.showWeekNumbers || this.showISOWeekNumbers) 803 html += '<th class="week">' + this.locale.weekLabel + '</th>'; 804 805 $.each(this.locale.daysOfWeek, function (index, dayOfWeek) { 806 html += '<th>' + dayOfWeek.slice(0, -1) + '</th>'; 807 }); 808 809 html += '</tr>'; 810 html += '</thead>'; 811 html += '<tbody>'; 812 813 //adjust maxDate to reflect the maxSpan setting in order to 814 //grey out end dates beyond the maxSpan 815 if (this.endDate == null && this.maxSpan) { 816 var maxLimit = this.startDate.clone().add(this.maxSpan).endOf('day'); 817 if (!maxDate || maxLimit.isBefore(maxDate)) { 818 maxDate = maxLimit; 819 } 820 } 821 822 for (var row = 0; row < 6; row++) { 823 html += '<tr>'; 824 825 // add week number 826 if (this.showWeekNumbers) 827 html += '<td class="week">' + calendar[row][0].week() + '</td>'; 828 else if (this.showISOWeekNumbers) 829 html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>'; 830 831 for (var col = 0; col < 7; col++) { 832 833 var classes = []; 834 835 //highlight today's date 836 if (calendar[row][col].isSame(new Date(), "day")) 837 classes.push('today'); 838 839 //highlight weekends 840 if (calendar[row][col].isoWeekday() > 5) 841 classes.push('weekend'); 842 843 //grey out the dates in other months displayed at beginning and end of this calendar 844 if (calendar[row][col].month() != calendar[1][1].month()) 845 classes.push('off', 'ends'); 846 847 //don't allow selection of dates before the minimum date 848 if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day')) 849 classes.push('off', 'disabled'); 850 851 //don't allow selection of dates after the maximum date 852 if (maxDate && calendar[row][col].isAfter(maxDate, 'day')) 853 classes.push('off', 'disabled'); 854 855 //don't allow selection of date if a custom function decides it's invalid 856 if (this.isInvalidDate(calendar[row][col])) 857 classes.push('off', 'disabled'); 858 859 //highlight the currently selected start date 860 if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) 861 classes.push('active', 'start-date'); 862 863 //highlight the currently selected end date 864 if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) 865 classes.push('active', 'end-date'); 866 867 //highlight dates in-between the selected dates 868 if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate) 869 classes.push('in-range'); 870 871 //apply custom classes for this date 872 var isCustom = this.isCustomDate(calendar[row][col]); 873 if (isCustom !== false) { 874 if (typeof isCustom === 'string') 875 classes.push(isCustom); 876 else 877 Array.prototype.push.apply(classes, isCustom); 878 } 879 880 var cname = '', disabled = false; 881 for (var i = 0; i < classes.length; i++) { 882 cname += classes[i] + ' '; 883 if (classes[i] == 'disabled') 884 disabled = true; 885 } 886 if (!disabled) 887 cname += 'available'; 888 889 // html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '</td>'; 890 html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '"> <a href="javascript:void(0)" class="data-span">' + calendar[row][col].date() + '</a></td>'; 891 892 } 893 html += '</tr>'; 894 } 895 896 html += '</tbody>'; 897 html += '</table>'; 898 899 this.container.find('.drp-calendar.' + side + ' .calendar-table').html(html); 900 901 }, 902 903 renderTimePicker: function (side) { 904 905 // Don't bother updating the time picker if it's currently disabled 906 // because an end date hasn't been clicked yet 907 if (side == 'right' && !this.endDate) return; 908 909 var html, selected, minDate, maxDate = this.maxDate; 910 911 if (this.maxSpan && (!this.maxDate || this.startDate.clone().add(this.maxSpan).isBefore(this.maxDate))) 912 maxDate = this.startDate.clone().add(this.maxSpan); 913 914 if (side == 'left') { 915 selected = this.startDate.clone(); 916 minDate = this.minDate; 917 } else if (side == 'right') { 918 selected = this.endDate.clone(); 919 minDate = this.startDate; 920 921 //Preserve the time already selected 922 var timeSelector = this.container.find('.drp-calendar.right .calendar-time'); 923 if (timeSelector.html() != '') { 924 925 selected.hour(!isNaN(selected.hour()) ? selected.hour() : timeSelector.find('.hourselect option:selected').val()); 926 selected.minute(!isNaN(selected.minute()) ? selected.minute() : timeSelector.find('.minuteselect option:selected').val()); 927 selected.second(!isNaN(selected.second()) ? selected.second() : timeSelector.find('.secondselect option:selected').val()); 928 929 if (!this.timePicker24Hour) { 930 var ampm = timeSelector.find('.ampmselect option:selected').val(); 931 if (ampm === 'PM' && selected.hour() < 12) 932 selected.hour(selected.hour() + 12); 933 if (ampm === 'AM' && selected.hour() === 12) 934 selected.hour(0); 935 } 936 937 } 938 939 if (selected.isBefore(this.startDate)) 940 selected = this.startDate.clone(); 941 942 if (maxDate && selected.isAfter(maxDate)) 943 selected = maxDate.clone(); 944 945 } 946 947 // 948 // hours 949 // 950 951 html = '<select class="hourselect">'; 952 953 var start = this.timePicker24Hour ? 0 : 1; 954 var end = this.timePicker24Hour ? 23 : 12; 955 956 for (var i = start; i <= end; i++) { 957 var i_in_24 = i; 958 if (!this.timePicker24Hour) 959 i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i); 960 961 var time = selected.clone().hour(i_in_24); 962 var disabled = false; 963 if (minDate && time.minute(59).isBefore(minDate)) 964 disabled = true; 965 if (maxDate && time.minute(0).isAfter(maxDate)) 966 disabled = true; 967 968 if (i_in_24 == selected.hour() && !disabled) { 969 html += '<option value="' + i + '" selected="selected">' + i + '</option>'; 970 } else if (disabled) { 971 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>'; 972 } else { 973 html += '<option value="' + i + '">' + i + '</option>'; 974 } 975 } 976 977 html += '</select> '; 978 979 // 980 // minutes 981 // 982 983 html += ': <select class="minuteselect">'; 984 985 for (var i = 0; i < 60; i += this.timePickerIncrement) { 986 var padded = i < 10 ? '0' + i : i; 987 var time = selected.clone().minute(i); 988 989 var disabled = false; 990 if (minDate && time.second(59).isBefore(minDate)) 991 disabled = true; 992 if (maxDate && time.second(0).isAfter(maxDate)) 993 disabled = true; 994 995 if (selected.minute() == i && !disabled) { 996 html += '<option value="' + i + '" selected="selected">' + padded + '</option>'; 997 } else if (disabled) { 998 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>'; 999 } else { 1000 html += '<option value="' + i + '">' + padded + '</option>'; 1001 } 1002 } 1003 1004 html += '</select> '; 1005 1006 // 1007 // seconds 1008 // 1009 1010 if (this.timePickerSeconds) { 1011 html += ': <select class="secondselect">'; 1012 1013 for (var i = 0; i < 60; i++) { 1014 var padded = i < 10 ? '0' + i : i; 1015 var time = selected.clone().second(i); 1016 1017 var disabled = false; 1018 if (minDate && time.isBefore(minDate)) 1019 disabled = true; 1020 if (maxDate && time.isAfter(maxDate)) 1021 disabled = true; 1022 1023 if (selected.second() == i && !disabled) { 1024 html += '<option value="' + i + '" selected="selected">' + padded + '</option>'; 1025 } else if (disabled) { 1026 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>'; 1027 } else { 1028 html += '<option value="' + i + '">' + padded + '</option>'; 1029 } 1030 } 1031 1032 html += '</select> '; 1033 } 1034 1035 // 1036 // AM/PM 1037 // 1038 1039 if (!this.timePicker24Hour) { 1040 html += '<select class="ampmselect">'; 1041 1042 var am_html = ''; 1043 var pm_html = ''; 1044 1045 if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate)) 1046 am_html = ' disabled="disabled" class="disabled"'; 1047 1048 if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate)) 1049 pm_html = ' disabled="disabled" class="disabled"'; 1050 1051 if (selected.hour() >= 12) { 1052 html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>'; 1053 } else { 1054 html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>'; 1055 } 1056 1057 html += '</select>'; 1058 } 1059 1060 this.container.find('.drp-calendar.' + side + ' .calendar-time').html(html); 1061 1062 }, 1063 1064 updateFormInputs: function () { 1065 // $('#travedDatesselect').val(''); 1066 if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) { 1067 this.container.find('button.applyBtn').prop('disabled', false); 1068 // $('#travedDatesselect').val( this.startDate.format('MM/DD/YYYY')+' - '+ this.endDate.format('MM/DD/YYYY')); 1069 1070 } else { 1071 this.container.find('button.applyBtn').prop('disabled', true); 1072 // $('#travedDatesselect').val( this.startDate.format('MM/DD/YYYY')); 1073 1074 } 1075 1076 }, 1077 1078 move: function () { 1079 var parentOffset = { top: 0, left: 0 }, 1080 containerTop, 1081 drops = this.drops; 1082 1083 var parentRightEdge = $(window).width(); 1084 if (!this.parentEl.is('body')) { 1085 parentOffset = { 1086 top: this.parentEl.offset().top - this.parentEl.scrollTop(), 1087 left: this.parentEl.offset().left - this.parentEl.scrollLeft() 1088 }; 1089 parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left; 1090 } 1091 1092 switch (drops) { 1093 case 'auto': 1094 containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; 1095 if (containerTop + this.container.outerHeight() >= this.parentEl[0].scrollHeight) { 1096 containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; 1097 drops = 'up'; 1098 } 1099 break; 1100 case 'up': 1101 containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; 1102 break; 1103 default: 1104 containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; 1105 break; 1106 } 1107 1108 // Force the container to it's actual width 1109 this.container.css({ 1110 top: 0, 1111 left: 0, 1112 right: 'auto' 1113 }); 1114 var containerWidth = this.container.outerWidth(); 1115 1116 this.container.toggleClass('drop-up', drops == 'up'); 1117 1118 if (this.opens == 'left') { 1119 var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth(); 1120 if (containerWidth + containerRight > $(window).width()) { 1121 this.container.css({ 1122 top: containerTop, 1123 right: 'auto', 1124 left: 9 1125 }); 1126 } else { 1127 this.container.css({ 1128 top: containerTop, 1129 right: containerRight, 1130 left: 'auto' 1131 }); 1132 } 1133 } else if (this.opens == 'center') { 1134 var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 1135 - containerWidth / 2; 1136 if (containerLeft < 0) { 1137 this.container.css({ 1138 top: containerTop, 1139 right: 'auto', 1140 left: 9 1141 }); 1142 } else if (containerLeft + containerWidth > $(window).width()) { 1143 this.container.css({ 1144 top: containerTop, 1145 left: 'auto', 1146 right: 0 1147 }); 1148 } else { 1149 this.container.css({ 1150 top: containerTop, 1151 left: containerLeft, 1152 right: 'auto' 1153 }); 1154 } 1155 } else { 1156 var containerLeft = this.element.offset().left - parentOffset.left; 1157 if (containerLeft + containerWidth > $(window).width()) { 1158 this.container.css({ 1159 top: containerTop, 1160 left: 'auto', 1161 right: 0 1162 }); 1163 } else { 1164 this.container.css({ 1165 top: containerTop, 1166 left: containerLeft, 1167 right: 'auto' 1168 }); 1169 } 1170 } 1171 }, 1172 1173 show: function (e) { 1174 if (this.isShowing) return; 1175 var Depatureretundatestest = $('#travedDatesselect').val(); 1176 if (Depatureretundatestest == "") { 1177 this.setStartDate({}); 1178 this.setEndDate({}); 1179 // Create a click proxy that is private to this instance of datepicker, for unbinding 1180 this._outsideClickProxy = $.proxy(function (e) { this.outsideClick(e); }, this); 1181 1182 // Bind global datepicker mousedown for hiding and 1183 $(document) 1184 .on('mousedown.daterangepicker', this._outsideClickProxy) 1185 // also support mobile devices 1186 .on('touchend.daterangepicker', this._outsideClickProxy) 1187 // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them 1188 .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
1189 // and also close when focus changes to outside the picker (eg. tabbing between controls) 1190 .on('focusin.daterangepicker', this._outsideClickProxy); 1191 1192 // Reposition the picker if the window is resized while it's open 1193 $(window).on('resize.daterangepicker', $.proxy(function (e) { this.move(e); }, this)); 1194 $('.daterangepicker.show-ranges').addClass('show-calendar'); 1195 this.oldStartDate = this.startDate.clone(); 1196 this.oldEndDate = this.endDate.clone(); 1197 this.previousRightTime = this.endDate.clone(); 1198 1199 this.updateView(); 1200 this.container.show(); 1201 this.move(); 1202 this.element.trigger('show.daterangepicker', this); 1203 this.isShowing = true; 1204 } 1205 else { 1206 this._outsideClickProxy = $.proxy(function (e) { this.outsideClick(e); }, this); 1207 1208 // Bind global datepicker mousedown for hiding and 1209 $(document) 1210 .on('mousedown.daterangepicker', this._outsideClickProxy) 1211 // also support mobile devices 1212 .on('touchend.daterangepicker', this._outsideClickProxy) 1213 // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them 1214 .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy) 1215 // and also close when focus changes to outside the picker (eg. tabbing between controls) 1216 .on('focusin.daterangepicker', this._outsideClickProxy); 1217 1218 // Reposition the picker if the window is resized while it's open 1219 $(window).on('resize.daterangepicker', $.proxy(function (e) { this.move(e); }, this)); 1220 1221 this.oldStartDate = this.startDate.clone(); 1222 this.oldEndDate = this.endDate.clone(); 1223 this.previousRightTime = this.endDate.clone(); 1224 1225 this.updateView(); 1226 this.container.show(); 1227 this.move(); 1228 this.element.trigger('show.daterangepicker', this); 1229 this.isShowing = true; 1230 1231 } 1232 }, 1233 1234 hide: function (e) { 1235 if (!this.isShowing) return; 1236 1237 //incomplete date selection, revert to last values 1238 if (!this.endDate) { 1239 this.startDate = this.oldStartDate.clone(); 1240 this.endDate = this.oldEndDate.clone(); 1241 } 1242 1243 //if a new date range was selected, invoke the user callback function 1244 if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) 1245 this.callback(this.startDate.clone(), this.endDate.clone(), this.chosenLabel); 1246 1247 //if picker is attached to a text input, update it 1248 this.updateElement(); 1249 1250 $(document).off('.daterangepicker'); 1251 $(window).off('.daterangepicker'); 1252 this.container.hide(); 1253 this.element.trigger('hide.daterangepicker', this); 1254 this.isShowing = false; 1255 $('.daterangepicker.show-ranges').removeClass('show-calendar'); 1256 }, 1257 addFocusLeft: function (e) { 1258 $("#travedDatesselect").parent().addClass('focus-left'); 1259 }, 1260 removeFocusLeft: function (e) { 1261 $("#travedDatesselect").parent().removeClass('focus-left'); 1262 }, 1263 addFocusRight: function (e) { 1264 $("#travedDatesselect").parent().addClass('focus-right'); 1265 }, 1266 removeFocusRight: function (e) { 1267 $("#travedDatesselect").parent().removeClass('focus-right'); 1268 }, 1269 1270 toggle: function (e) { 1271 if (this.isShowing) { 1272 this.hide(); 1273 } else { 1274 this.show(); 1275 } 1276 }, 1277 1278 outsideClick: function (e) { 1279 var target = $(e.target); 1280 // if the page is clicked anywhere except within the daterangerpicker/button 1281 // itself then call this.hide() 1282 if ( 1283 // ie modal dialog fix 1284 e.type == "focusin" || 1285 target.closest(this.element).length || 1286 target.closest(this.container).length || 1287 target.closest('.calendar-table').length 1288 ) return; 1289 this.hide(); 1290 this.element.trigger('outsideClick.daterangepicker', this); 1291 //this.element.trigger('cancel.daterangepicker', this); 1292 this.removeFocusRight(); 1293 this.removeFocusLeft(); 1294 }, 1295 1296 showCalendars: function () { 1297 this.container.addClass('show-calendar'); 1298 this.move(); 1299 this.element.trigger('showCalendar.daterangepicker', this); 1300 }, 1301 1302 hideCalendars: function () { 1303 this.container.removeClass('show-calendar'); 1304 this.element.trigger('hideCalendar.daterangepicker', this); 1305 }, 1306 1307 clickRange: function (e) { 1308 var label = e.target.getAttribute('data-range-key'); 1309 this.chosenLabel = label; 1310 if (label == this.locale.customRangeLabel) { 1311 this.showCalendars();
vendor: 7,938 bytes, lines 1312-1484
1312 } else { 1313 var dates = this.ranges[label]; 1314 this.startDate = dates[0]; 1315 this.endDate = dates[1]; 1316 1317 if (!this.timePicker) { 1318 this.startDate.startOf('day'); 1319 this.endDate.endOf('day'); 1320 } 1321 1322 if (!this.alwaysShowCalendars) 1323 this.hideCalendars(); 1324 this.clickApply(); 1325 } 1326 }, 1327 1328 clickPrev: function (e) { 1329 var cal = $(e.target).parents('.drp-calendar'); 1330 if (cal.hasClass('left')) { 1331 this.leftCalendar.month.subtract(1, 'month'); 1332 if (this.linkedCalendars) 1333 this.rightCalendar.month.subtract(1, 'month'); 1334 } else { 1335 this.rightCalendar.month.subtract(1, 'month'); 1336 } 1337 this.updateCalendars(); 1338 }, 1339 1340 clickNext: function (e) { 1341 var cal = $(e.target).parents('.drp-calendar'); 1342 if (cal.hasClass('left')) { 1343 this.leftCalendar.month.add(1, 'month'); 1344 } else { 1345 this.rightCalendar.month.add(1, 'month'); 1346 if (this.linkedCalendars) 1347 this.leftCalendar.month.add(1, 'month'); 1348 } 1349 this.updateCalendars(); 1350 }, 1351 1352 hoverDate: function (e) { 1353 1354 //ignore dates that can't be selected 1355 if (!$(e.target).hasClass('available')) return; 1356 1357 var title = $(e.target).attr('data-title'); 1358 var row = title.substr(1, 1); 1359 var col = title.substr(3, 1); 1360 var cal = $(e.target).parents('.drp-calendar'); 1361 var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; 1362 1363 //highlight the dates between the start date and the date being hovered as a potential end date 1364 var leftCalendar = this.leftCalendar; 1365 var rightCalendar = this.rightCalendar; 1366 var startDate = this.startDate; 1367 if (!this.endDate) { 1368 this.container.find('.drp-calendar tbody td').each(function (index, el) { 1369 1370 //skip week numbers, only look at dates 1371 if ($(el).hasClass('week')) return; 1372 1373 var title = $(el).attr('data-title'); 1374 var row = title.substr(1, 1); 1375 var col = title.substr(3, 1); 1376 var cal = $(el).parents('.drp-calendar'); 1377 var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col]; 1378 1379 if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) { 1380 $(el).addClass('in-range'); 1381 } else { 1382 $(el).removeClass('in-range'); 1383 } 1384 1385 }); 1386 } 1387 1388 }, 1389 1390 clickDate: function (e) { 1391 1392 if (!$(e.target).hasClass('available')) return; 1393 1394 var title = $(e.target).attr('data-title'); 1395 var row = title.substr(1, 1); 1396 var col = title.substr(3, 1); 1397 var cal = $(e.target).parents('.drp-calendar'); 1398 var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; 1399 1400 // 1401 // this function needs to do a few things: 1402 // * alternate between selecting a start and end date for the range, 1403 // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date 1404 // * if autoapply is enabled, and an end date was chosen, apply the selection 1405 // * if single date picker mode, and time picker isn't enabled, apply the selection immediately 1406 // * if one of the inputs above the calendars was focused, cancel that manual input 1407 // 1408 1409 if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start 1410 if (this.timePicker) { 1411 var hour = parseInt(this.container.find('.left .hourselect').val(), 10); 1412 if (!this.timePicker24Hour) { 1413 var ampm = this.container.find('.left .ampmselect').val(); 1414 if (ampm === 'PM' && hour < 12) 1415 hour += 12; 1416 if (ampm === 'AM' && hour === 12) 1417 hour = 0; 1418 } 1419 var minute = parseInt(this.container.find('.left .minuteselect').val(), 10); 1420 if (isNaN(minute)) { 1421 minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10); 1422 } 1423 var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; 1424 date = date.clone().hour(hour).minute(minute).second(second); 1425 } 1426 this.endDate = null; 1427 this.setStartDate(date.clone()); 1428 this.startDateApply(); 1429 this.container.find('.drp-selected').html(this.startDate.format('MM/DD/YYYY') ); 1430 } else if (!this.endDate && date.isBefore(this.startDate)) { 1431 //special case: clicking the same date for start/end, 1432 //but the time of the end date is before the start date 1433 this.setEndDate(this.startDate.clone()); 1434 } else { // picking end 1435 if (this.timePicker) { 1436 var hour = parseInt(this.container.find('.right .hourselect').val(), 10); 1437 if (!this.timePicker24Hour) { 1438 var ampm = this.container.find('.right .ampmselect').val(); 1439 if (ampm === 'PM' && hour < 12) 1440 hour += 12; 1441 if (ampm === 'AM' && hour === 12) 1442 hour = 0; 1443 } 1444 var minute = parseInt(this.container.find('.right .minuteselect').val(), 10); 1445 if (isNaN(minute)) { 1446 minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10); 1447 } 1448 var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; 1449 date = date.clone().hour(hour).minute(minute).second(second); 1450 } 1451 this.setEndDate(date.clone()); 1452 this.startendDateApply(); 1453 this.container.find('.drp-selected').html(this.startDate.format('MM/DD/YYYY') + '<span class="vl"></span>' + this.endDate.format('MM/DD/YYYY')); 1454 1455 if (this.autoApply) { 1456 this.calculateChosenLabel(); 1457 //this.clickApply(); 1458 1459 } 1460 else { 1461 this.clickAutoApply(); 1462 } 1463 } 1464 1465 if (this.singleDatePicker) { 1466 this.setEndDate(this.startDate); 1467 if (!this.timePicker && this.autoApply) 1468 this.clickApply(); 1469 } 1470 1471 this.updateView(); 1472 1473 //This is to cancel the blur event handler if the mouse was in one of the inputs 1474 e.stopPropagation(); 1475 1476 }, 1477 1478 calculateChosenLabel: function () { 1479 var customRange = true; 1480 var i = 0; 1481 for (var range in this.ranges) { 1482 if (this.timePicker) { 1483 var format = this.timePickerSeconds ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD HH:mm"; 1484 //ignore times when comparing dates if time picker seconds
1484is not enabled 1485 if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) { 1486 customRange = false; 1487 this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key'); 1488 break; 1489 } 1490 } else { 1491 //ignore times when comparing dates if time picker is not enabled 1492 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')) { 1493 customRange = false; 1494 this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key'); 1495 break; 1496 } 1497 } 1498 i++; 1499 } 1500 if (customRange) { 1501 if (this.showCustomRangeLabel) { 1502 this.chosenLabel = this.container.find('.ranges li:last').addClass('active').attr('data-range-key'); 1503 } else { 1504 this.chosenLabel = null; 1505 } 1506 this.showCalendars(); 1507 } 1508 }, 1509 1510 clickApply: function (e) { 1511 this.hide(); 1512 this.element.trigger('apply.daterangepicker', this); 1513 this.removeFocusRight(); 1514 this.removeFocusLeft(); 1515 }, 1516 startDateApply: function (e) { 1517 // $("#travedDatesselect").parent().addClass('focus-left'); 1518 this.addFocusLeft(); 1519 this.removeFocusRight(); 1520 this.element.trigger('startDate.daterangepicker', this); 1521 }, 1522 startendDateApply: function (e) { 1523 this.removeFocusLeft(); 1524 this.addFocusRight(); 1525 this.element.trigger('endDate.daterangepicker', this); 1526 }, 1527 clickAutoApply: function (e) { 1528 this.element.trigger('apply.daterangepicker', this); 1529 }, 1530 clickCancel: function (e) { 1531 this.startDate = this.oldStartDate; 1532 this.endDate = this.oldEndDate; 1533 // this.hide(); 1534 this.element.trigger('cancel.daterangepicker', this); 1535 this.container.find('button.applyBtn').prop('disabled', true); 1536 this.updateCalendars(); 1537 this.removeFocusRight(); 1538 this.removeFocusLeft(); 1539 this.container.find('.drp-selected').html(""); 1540 }, 1541 clickBack: function (e) { 1542 this.hide(); 1543 this.removeFocusRight(); 1544 this.removeFocusLeft(); 1545 }, 1546 monthOrYearChanged: function (e) { 1547 var isLeft = $(e.target).closest('.drp-calendar').hasClass('left'), 1548 leftOrRight = isLeft ? 'left' : 'right', 1549 cal = this.container.find('.drp-calendar.' + leftOrRight); 1550 1551 // Month must be Number for new moment versions 1552 var month = parseInt(cal.find('.monthselect').val(), 10); 1553 var year = cal.find('.yearselect').val(); 1554 1555 if (!isLeft) { 1556 if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) { 1557 month = this.startDate.month(); 1558 year = this.startDate.year(); 1559 } 1560 } 1561 1562 if (this.minDate) { 1563 if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) { 1564 month = this.minDate.month(); 1565 year = this.minDate.year(); 1566 } 1567 } 1568 1569 if (this.maxDate) { 1570 if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) { 1571 month = this.maxDate.month(); 1572 year = this.maxDate.year(); 1573 } 1574 } 1575 1576 if (isLeft) { 1577 this.leftCalendar.month.month(month).year(year); 1578 if (this.linkedCalendars) 1579 this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month'); 1580 } else { 1581 this.rightCalendar.month.month(month).year(year); 1582 if (this.linkedCalendars) 1583 this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month'); 1584 } 1585 this.updateCalendars();
vendor: 4,612 bytes, lines 1586-1714
1586 }, 1587 1588 timeChanged: function (e) { 1589 1590 var cal = $(e.target).closest('.drp-calendar'), 1591 isLeft = cal.hasClass('left'); 1592 1593 var hour = parseInt(cal.find('.hourselect').val(), 10); 1594 var minute = parseInt(cal.find('.minuteselect').val(), 10); 1595 if (isNaN(minute)) { 1596 minute = parseInt(cal.find('.minuteselect option:last').val(), 10); 1597 } 1598 var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0; 1599 1600 if (!this.timePicker24Hour) { 1601 var ampm = cal.find('.ampmselect').val(); 1602 if (ampm === 'PM' && hour < 12) 1603 hour += 12; 1604 if (ampm === 'AM' && hour === 12) 1605 hour = 0; 1606 } 1607 1608 if (isLeft) { 1609 var start = this.startDate.clone(); 1610 start.hour(hour); 1611 start.minute(minute); 1612 start.second(second); 1613 this.setStartDate(start); 1614 if (this.singleDatePicker) { 1615 this.endDate = this.startDate.clone(); 1616 } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) { 1617 this.setEndDate(start.clone()); 1618 } 1619 } else if (this.endDate) { 1620 var end = this.endDate.clone(); 1621 end.hour(hour); 1622 end.minute(minute); 1623 end.second(second); 1624 this.setEndDate(end); 1625 } 1626 1627 //update the calendars so all clickable dates reflect the new time component 1628 this.updateCalendars(); 1629 1630 //update the form inputs above the calendars with the new time 1631 this.updateFormInputs(); 1632 1633 //re-render the time pickers because changing one selection can affect what's enabled in another 1634 this.renderTimePicker('left'); 1635 this.renderTimePicker('right'); 1636 1637 }, 1638 1639 elementChanged: function () { 1640 if (!this.element.is('input')) return; 1641 if (!this.element.val().length) return; 1642 1643 var dateString = this.element.val().split(this.locale.separator), 1644 start = null, 1645 end = null; 1646 1647 if (dateString.length === 2) { 1648 start = moment(dateString[0], 'MM/DD/YYYY'); 1649 end = moment(dateString[1], 'MM/DD/YYYY'); 1650 } 1651 1652 if (this.singleDatePicker || start === null || end === null) { 1653 // start = moment(this.element.val(), this.locale.format); 1654 start = moment(this.element.val(), 'MM/DD/YYYY') 1655 end = start; 1656 } 1657 1658 if (!start.isValid() || !end.isValid()) return; 1659 1660 this.setStartDate(start); 1661 this.setEndDate(end); 1662 this.updateView(); 1663 }, 1664 1665 keydown: function (e) { 1666 //hide on tab or enter 1667 if ((e.keyCode === 9) || (e.keyCode === 13)) { 1668 this.hide(); 1669 } 1670 1671 //hide on esc and prevent propagation 1672 if (e.keyCode === 27) { 1673 e.preventDefault(); 1674 e.stopPropagation(); 1675 1676 this.hide(); 1677 } 1678 }, 1679 1680 updateElement: function () { 1681 if (this.element.is('input') && this.autoUpdateInput) { 1682 var newValue = this.startDate.format(this.locale.format); 1683 if (!this.singleDatePicker) { 1684 newValue += this.locale.separator + this.endDate.format(this.locale.format); 1685 } 1686 if (newValue !== this.element.val()) { 1687 this.element.val(newValue).trigger('change'); 1688 } 1689 } 1690 }, 1691 1692 remove: function () { 1693 this.container.remove(); 1694 this.element.off('.daterangepicker'); 1695 this.element.removeData(); 1696 } 1697 1698 }; 1699 1700 $.fn.daterangepicker = function (options, callback) { 1701 var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options); 1702 this.each(function () { 1703 var el = $(this); 1704 if (el.data('daterangepicker')) 1705 el.data('daterangepicker').remove(); 1706 el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback)); 1707 }); 1708 return this; 1709 }; 1710 1711 return DateRangePicker; 1712 1713})); 1714
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.