JAVASCRIPT   31

DateRangePicker

Guest on 29th April 2022 01:27:16 AM

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

Raw Paste


Login or Register to edit or fork this paste. It's free.