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