1/*! 2 * Datepicker for Bootstrap v1.5.1 (https://github.com/eternicode/bootstrap-datepicker) 3 * 4 * Copyright 2012 Stefan Petre 5 * Improvements by Andrew Rowls 6 * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) 7 */(function(factory){ 8 if (typeof define === "function" && define.amd) { 9 define(["jquery"], factory); 10 } else if (typeof exports === 'object') { 11 factory(require('jquery')); 12 } else { 13 factory(jQuery); 14 } 15}(function($, undefined){ 16 17 function UTCDate(){ 18 return new Date(Date.UTC.apply(Date, arguments)); 19 } 20 function UTCToday(){ 21 var today = new Date(); 22 return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); 23 } 24 function isUTCEquals(date1, date2) { 25 return ( 26 date1.getUTCFullYear() === date2.getUTCFullYear() && 27 date1.getUTCMonth() === date2.getUTCMonth() && 28 date1.getUTCDate() === date2.getUTCDate() 29 ); 30 } 31 function alias(method){ 32 return function(){ 33 return this[method].apply(this, arguments); 34 }; 35 } 36 function isValidDate(d) { 37 return d && !isNaN(d.getTime()); 38 } 39 40 var DateArray = (function(){ 41 var extras = { 42 get: function(i){ 43 return this.slice(i)[0]; 44 }, 45 contains: function(d){ 46 // Array.indexOf is not cross-browser; 47 // $.inArray doesn't work with Dates 48 var val = d && d.valueOf(); 49 for (var i=0, l=this.length; i < l; i++) 50 if (this[i].valueOf() === val) 51 return i; 52 return -1; 53 }, 54 remove: function(i){ 55 this.splice(i,1); 56 }, 57 replace: function(new_array){ 58 if (!new_array) 59 return; 60 if (!$.isArray(new_array)) 61 new_array = [new_array]; 62 this.clear(); 63 this.push.apply(this, new_array); 64 }, 65 clear: function(){ 66 this.length = 0; 67 }, 68 copy: function(){ 69 var a = new DateArray(); 70 a.replace(this); 71 return a; 72 } 73 }; 74 75 return function(){ 76 var a = []; 77 a.push.apply(a, arguments); 78 $.extend(a, extras); 79 return a; 80 }; 81 })(); 82 83 84 // Picker object 85 86 var Datepicker = function(element, options){ 87 $(element).data('datepicker', this); 88 this._process_options(options); 89 90 this.dates = new DateArray(); 91 this.viewDate = this.o.defaultViewDate; 92 this.focusDate = null; 93 94 this.element = $(element); 95 this.isInline = false; 96 this.isInput = this.element.is('input'); 97 this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; 98 this.hasInput = this.component && this.element.find('input').length; 99 if (this.component && this.component.length === 0) 100 this.component = false; 101 102 this.picker = $(DPGlobal.template); 103 this._buildEvents(); 104 this._attachEvents(); 105 106 if (this.isInline){ 107 this.picker.addClass('datepicker-inline').appendTo(this.element); 108 } 109 else { 110 this.picker.addClass('datepicker-dropdown dropdown-menu'); 111 } 112 113 if (this.o.rtl){ 114 this.picker.addClass('datepicker-rtl'); 115 } 116 117 this.viewMode = this.o.startView; 118 119 if (this.o.calendarWeeks) 120 this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear') 121 .attr('colspan', function(i, val){ 122 return parseInt(val) + 1; 123 }); 124 125 this._allow_update = false; 126 127 this.setStartDate(this._o.startDate); 128 this.setEndDate(this._o.endDate); 129 this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); 130 this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted); 131 this.setDatesDisabled(this.o.datesDisabled); 132 133 this.fillDow(); 134 this.fillMonths(); 135 136 this._allow_update = true; 137 138 this.update(); 139 this.showMode(); 140 141 if (this.isInline){ 142 this.show(); 143 } 144 }; 145 146 Datepicker.prototype = { 147 constructor: Datepicker, 148 149 _process_options: function(opts){ 150 // Store raw options for reference 151 this._o = $.extend({}, this._o, opts); 152 // Processed options 153 var o = this.o = $.extend({}, this._o); 154 155 // Check if "de-DE" style date is available, if not language should 156 // fallback to 2 letter code eg "de" 157 var lang = o.language; 158 if (!dates[lang]){ 159 lang = lang.split('-')[0]; 160 if (!dates[lang]) 161 lang = defaults.language; 162 } 163 o.language = lang; 164 165 switch (o.startView){ 166 case 2: 167 case 'decade': 168 o.startView = 2; 169 break; 170 case 1: 171 case 'year': 172 o.startView = 1; 173 break; 174 default: 175 o.startView = 0; 176 } 177 178 switch (o.minViewMode){ 179 case 1: 180 case 'months': 181 o.minViewMode = 1; 182 break; 183 case 2: 184 case 'years': 185 o.minViewMode = 2; 186 break; 187 default: 188 o.minViewMode = 0; 189 } 190 191 switch (o.maxViewMode) { 192 case 0: 193 case 'days': 194 o.maxViewMode = 0; 195 break; 196 case 1: 197 case 'months': 198 o.maxViewMode = 1; 199 break; 200 default: 201 o.maxViewMode = 2; 202 } 203 204 o.startView = Math.min(o.startView, o.maxViewMode); 205 o.startView = Math.max(o.startView, o.minViewMode); 206 207 // true, false, or Number > 0 208 if (o.multidate !== true){ 209 o.multidate = Number(o.multidate) || false; 210 if (o.multidate !== false) 211 o.multidate = Math.max(0, o.multidate); 212 } 213 o.multidateSeparator = String(o.multidateSeparator); 214 215 o.weekStart %= 7; 216 o.weekEnd = (o.weekStart + 6) % 7; 217 218 var format = DPGlobal.parseFormat(o.format); 219 if (o.startDate !== -Infinity){ 220 if (!!o.startDate){ 221 if (o.startDate instanceof Date) 222 o.startDate = this._local_to_utc(this._zero_time(o.startDate)); 223 else 224 o.startDate = DPGlobal.parseDate(o.startDate, format, o.language); 225 } 226 else { 227 o.startDate = -Infinity; 228 } 229 } 230 if (o.endDate !== Infinity){ 231 if (!!o.endDate){ 232 if (o.endDate instanceof Date) 233 o.endDate = this._local_to_utc(this._zero_time(o.endDate)); 234 else 235 o.endDate = DPGlobal.parseDate(o.endDate, format, o.language); 236 } 237 else { 238 o.endDate = Infinity; 239 } 240 } 241 242 o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; 243 if (!$.isArray(o.daysOfWeekDisabled)) 244 o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); 245 o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ 246 return parseInt(d, 10); 247 }); 248 249 o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[]; 250 if (!$.isArray(o.daysOfWeekHighlighted)) 251 o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/); 252 o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){ 253 return parseInt(d, 10); 254 }); 255 256 o.datesDisabled = o.datesDisabled||[]; 257 if (!$.isArray(o.datesDisabled)) { 258 var datesDisabled = []; 259 datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language)); 260 o.datesDisabled = datesDisabled; 261 } 262 o.datesDisabled = $.map(o.datesDisabled,function(d){ 263 return DPGlobal.parseDate(d, format, o.language); 264 }); 265 266 var plc = String(o.orientation).toLowerCase().split(/\s+/g), 267 _plc = o.orientation.toLowerCase(); 268 plc = $.grep(plc, function(word){ 269 return /^auto|left|right|top|bottom$/.test(word); 270 }); 271 o.orientation = {x: 'auto', y: 'auto'}; 272 if (!_plc || _plc === 'auto') 273 ; // no action 274 else if (plc.length === 1){ 275 switch (plc[0]){ 276 case 'top': 277 case 'bottom': 278 o.orientation.y = plc[0]; 279 break; 280 case 'left': 281 case 'right': 282 o.orientation.x = plc[0]; 283 break; 284 } 285 } 286 else { 287 _plc = $.grep(plc, function(word){ 288 return /^left|right$/.test(word); 289 }); 290 o.orientation.x = _plc[0] || 'auto'; 291 292 _plc = $.grep(plc, function(word){ 293 return /^top|bottom$/.test(word); 294 }); 295 o.orientation.y = _plc[0] || 'auto'; 296 } 297 if (o.defaultViewDate) { 298 var year = o.defaultViewDate.year || new Date().getFullYear();
299 var month = o.defaultViewDate.month || 0; 300 var day = o.defaultViewDate.day || 1; 301 o.defaultViewDate = UTCDate(year, month, day); 302 } else { 303 o.defaultViewDate = UTCToday(); 304 } 305 }, 306 _events: [], 307 _secondaryEvents: [], 308 _applyEvents: function(evs){ 309 for (var i=0, el, ch, ev; i < evs.length; i++){ 310 el = evs[i][0]; 311 if (evs[i].length === 2){ 312 ch = undefined; 313 ev = evs[i][1]; 314 } 315 else if (evs[i].length === 3){ 316 ch = evs[i][1]; 317 ev = evs[i][2]; 318 } 319 el.on(ev, ch); 320 } 321 }, 322 _unapplyEvents: function(evs){ 323 for (var i=0, el, ev, ch; i < evs.length; i++){ 324 el = evs[i][0]; 325 if (evs[i].length === 2){ 326 ch = undefined; 327 ev = evs[i][1]; 328 } 329 else if (evs[i].length === 3){ 330 ch = evs[i][1]; 331 ev = evs[i][2]; 332 } 333 el.off(ev, ch); 334 } 335 }, 336 _buildEvents: function(){ 337 var events = { 338 keyup: $.proxy(function(e){ 339 if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1) 340 this.update(); 341 }, this), 342 keydown: $.proxy(this.keydown, this), 343 paste: $.proxy(this.paste, this) 344 }; 345 346 if (this.o.showOnFocus === true) { 347 events.focus = $.proxy(this.show, this); 348 } 349 350 if (this.isInput) { // single input 351 this._events = [ 352 [this.element, events] 353 ]; 354 } 355 else if (this.component && this.hasInput) { // component: input + button 356 this._events = [ 357 // For components that are not readonly, allow keyboard nav 358 [this.element.find('input'), events], 359 [this.component, { 360 click: $.proxy(this.show, this) 361 }] 362 ]; 363 } 364 else if (this.element.is('div')){ // inline datepicker 365 this.isInline = true; 366 } 367 else { 368 this._events = [ 369 [this.element, { 370 click: $.proxy(this.show, this) 371 }] 372 ]; 373 } 374 this._events.push( 375 // Component: listen for blur on element descendants 376 [this.element, '*', { 377 blur: $.proxy(function(e){ 378 this._focused_from = e.target; 379 }, this) 380 }], 381 // Input: listen for blur on element 382 [this.element, { 383 blur: $.proxy(function(e){ 384 this._focused_from = e.target; 385 }, this) 386 }] 387 ); 388 389 if (this.o.immediateUpdates) { 390 // Trigger input updates immediately on changed year/month 391 this._events.push([this.element, { 392 'changeYear changeMonth': $.proxy(function(e){ 393 this.update(e.date); 394 }, this) 395 }]); 396 } 397 398 this._secondaryEvents = [ 399 [this.picker, { 400 click: $.proxy(this.click, this) 401 }], 402 [$(window), { 403 resize: $.proxy(this.place, this) 404 }], 405 [$(document), { 406 mousedown: $.proxy(function(e){ 407 // Clicked outside the datepicker, hide it 408 if (!( 409 this.element.is(e.target) || 410 this.element.find(e.target).length || 411 this.picker.is(e.target) || 412 this.picker.find(e.target).length || 413 this.picker.hasClass('datepicker-inline') 414 )){ 415 this.hide(); 416 } 417 }, this) 418 }] 419 ]; 420 }, 421 _attachEvents: function(){ 422 this._detachEvents(); 423 this._applyEvents(this._events); 424 }, 425 _detachEvents: function(){ 426 this._unapplyEvents(this._events); 427 }, 428 _attachSecondaryEvents: function(){ 429 this._detachSecondaryEvents(); 430 this._applyEvents(this._secondaryEvents); 431 }, 432 _detachSecondaryEvents: function(){ 433 this._unapplyEvents(this._secondaryEvents); 434 }, 435 _trigger: function(event, altdate){ 436 var date = altdate || this.dates.get(-1), 437 local_date = this._utc_to_local(date); 438 439 this.element.trigger({ 440 type: event, 441 date: local_date, 442 dates: $.map(this.dates, this._utc_to_local), 443 format: $.proxy(function(ix, format){ 444 if (arguments.length === 0){ 445 ix = this.dates.length - 1; 446 format = this.o.format; 447 } 448 else if (typeof ix === 'string'){ 449 format = ix; 450 ix = this.dates.length - 1; 451 } 452 format = format || this.o.format; 453 var date = this.dates.get(ix); 454 return DPGlobal.formatDate(date, format, this.o.language); 455 }, this) 456 }); 457 }, 458 459 show: function(){ 460 var element = this.component ? this.element.find('input') : this.element; 461 if (element.attr('readonly') && this.o.enableOnReadonly === false) 462 return; 463 if (!this.isInline) 464 this.picker.appendTo(this.o.container); 465 this.place(); 466 this.picker.show(); 467 this._attachSecondaryEvents(); 468 this._trigger('show'); 469 if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) { 470 $(this.element).blur(); 471 } 472 return this; 473 }, 474 475 hide: function(){ 476 if (this.isInline) 477 return this; 478 if (!this.picker.is(':visible')) 479 return this; 480 this.focusDate = null; 481 this.picker.hide().detach(); 482 this._detachSecondaryEvents(); 483 this.viewMode = this.o.startView; 484 this.showMode(); 485 486 if ( 487 this.o.forceParse && 488 ( 489 this.isInput && this.element.val() || 490 this.hasInput && this.element.find('input').val() 491 ) 492 ) 493 this.setValue(); 494 this._trigger('hide'); 495 return this; 496 }, 497 498 remove: function(){ 499 this.hide(); 500 this._detachEvents(); 501 this._detachSecondaryEvents(); 502 this.picker.remove(); 503 delete this.element.data().datepicker; 504 if (!this.isInput){ 505 delete this.element.data().date; 506 } 507 return this; 508 }, 509 510 paste: function(evt){ 511 var dateString; 512 if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types 513 && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) { 514 dateString = evt.originalEvent.clipboardData.getData('text/plain'); 515 } 516 else if (window.clipboardData) { 517 dateString = window.clipboardData.getData('Text'); 518 } 519 else { 520 return; 521 } 522 this.setDate(dateString); 523 this.update(); 524 evt.preventDefault(); 525 }, 526 527 _utc_to_local: function(utc){ 528 return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); 529 }, 530 _local_to_utc: function(local){ 531 return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); 532 }, 533 _zero_time: function(local){ 534 return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); 535 }, 536 _zero_utc_time: function(utc){ 537 return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); 538 }, 539 540 getDates: function(){ 541 return $.map(this.dates, this._utc_to_local); 542 }, 543 544 getUTCDates: function(){ 545 return $.map(this.dates, function(d){ 546 return new Date(d); 547 }); 548 }, 549 550 getDate: function(){ 551 return this._utc_to_local(this.getUTCDate()); 552 }, 553 554 getUTCDate: function(){ 555 var selected_date = this.dates.get(-1); 556 if (typeof selected_date !== 'undefined') { 557 return new Date(selected_date); 558 } else { 559 return null; 560 } 561 }, 562 563 clearDates: function(){ 564 var element; 565 if (this.isInput) { 566 element = this.element; 567 } else if (this.component) { 568 element = this.element.find('input'); 569 } 570 571 if (element) { 572 element.val(''); 573 } 574 575 this.update(); 576 this._trigger('changeDate'); 577 578 if (this.o.autoclose) { 579 this.hide(); 580 } 581 }, 582 setDates: function(){ 583 var args = $.isArray(arguments[0]) ? arguments[0] : arguments; 584 this.update.apply(this, args); 585 this._trigger('changeDate'); 586 this.setValue(); 587 return this; 588 }, 589 590 setUTCDates: function(){ 591 var args = $.isArray(arguments[0]) ? arguments[0] : arguments; 592 this.update.apply(this, $.map(args, this._utc_to_local)); 593 this._trigger('changeDate'); 594 this.setValue(); 595 return this; 596 }, 597 598 setDate: alias('setDates'), 599 setUTCDate: alias('setUTCDates'), 600 601 setValue: function(){ 602 var formatted = this.getFormattedDate(); 603 if (!this.isInput){ 604 if (this.component){ 605 this.element.find('input').val(formatted); 606 } 607 } 608 else { 609 this.element.val(formatted); 610 } 611 return this; 612 }, 613 614 getFormattedDate: function(format){ 615 if (format === undefined) 616 format = this.o.format; 617 618 var lang = this.o.language; 619 return $.map(this.dates, function(d){ 620 return DPGlobal.formatDate(d, format, lang); 621 }).join(this.o.multidateSeparator); 622 }, 623 624 setStartDate: function(startDate){ 625 this._process_options({startDate: startDate}); 626 this.update(); 627 this.updateNavArrows(); 628 return this; 629 }, 630
vendor: 6,311 bytes, lines 631-852
631 setEndDate: function(endDate){ 632 this._process_options({endDate: endDate}); 633 this.update(); 634 this.updateNavArrows(); 635 return this; 636 }, 637 638 setDaysOfWeekDisabled: function(daysOfWeekDisabled){ 639 this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); 640 this.update(); 641 this.updateNavArrows(); 642 return this; 643 }, 644 645 setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){ 646 this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted}); 647 this.update(); 648 return this; 649 }, 650 651 setDatesDisabled: function(datesDisabled){ 652 this._process_options({datesDisabled: datesDisabled}); 653 this.update(); 654 this.updateNavArrows(); 655 }, 656 657 place: function(){ 658 if (this.isInline) 659 return this; 660 var calendarWidth = this.picker.outerWidth(), 661 calendarHeight = this.picker.outerHeight(), 662 visualPadding = 10, 663 container = $(this.o.container), 664 windowWidth = container.width(), 665 scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(), 666 appendOffset = container.offset(); 667 668 var parentsZindex = []; 669 this.element.parents().each(function(){ 670 var itemZIndex = $(this).css('z-index'); 671 if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex)); 672 }); 673 var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset; 674 var offset = this.component ? this.component.parent().offset() : this.element.offset(); 675 var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); 676 var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); 677 var left = offset.left - appendOffset.left, 678 top = offset.top - appendOffset.top; 679 680 if (this.o.container !== 'body') { 681 top += scrollTop; 682 } 683 684 this.picker.removeClass( 685 'datepicker-orient-top datepicker-orient-bottom '+ 686 'datepicker-orient-right datepicker-orient-left' 687 ); 688 689 if (this.o.orientation.x !== 'auto'){ 690 this.picker.addClass('datepicker-orient-' + this.o.orientation.x); 691 if (this.o.orientation.x === 'right') 692 left -= calendarWidth - width; 693 } 694 // auto x orientation is best-placement: if it crosses a window 695 // edge, fudge it sideways 696 else { 697 if (offset.left < 0) { 698 // component is outside the window on the left side. Move it into visible range 699 this.picker.addClass('datepicker-orient-left'); 700 left -= offset.left - visualPadding; 701 } else if (left + calendarWidth > windowWidth) { 702 // the calendar passes the widow right edge. Align it to component right side 703 this.picker.addClass('datepicker-orient-right'); 704 left += width - calendarWidth; 705 } else { 706 // Default to left 707 this.picker.addClass('datepicker-orient-left'); 708 } 709 } 710 711 // auto y orientation is best-situation: top or bottom, no fudging, 712 // decision based on which shows more of the calendar 713 var yorient = this.o.orientation.y, 714 top_overflow; 715 if (yorient === 'auto'){ 716 top_overflow = -scrollTop + top - calendarHeight; 717 yorient = top_overflow < 0 ? 'bottom' : 'top'; 718 } 719 720 this.picker.addClass('datepicker-orient-' + yorient); 721 if (yorient === 'top') 722 top -= calendarHeight + parseInt(this.picker.css('padding-top')); 723 else 724 top += height; 725 726 727 // v 728 if (left<5) { 729 left=5; 730 this.picker.addClass('datepicker-orient-right'); 731 } 732 733 if (this.o.rtl) { 734 var right = windowWidth - (left + width); 735 this.picker.css({ 736 top: top, 737 right: right, 738 zIndex: zIndex 739 }); 740 } else { 741 this.picker.css({ 742 top: top, 743 left: left, 744 zIndex: zIndex 745 }); 746 } 747 return this; 748 }, 749 750 _allow_update: true, 751 update: function(){ 752 if (!this._allow_update) 753 return this; 754 755 var oldDates = this.dates.copy(), 756 dates = [], 757 fromArgs = false; 758 if (arguments.length){ 759 $.each(arguments, $.proxy(function(i, date){ 760 if (date instanceof Date) 761 date = this._local_to_utc(date); 762 dates.push(date); 763 }, this)); 764 fromArgs = true; 765 } 766 else { 767 dates = this.isInput 768 ? this.element.val() 769 : this.element.data('date') || this.element.find('input').val(); 770 if (dates && this.o.multidate) 771 dates = dates.split(this.o.multidateSeparator); 772 else 773 dates = [dates]; 774 delete this.element.data().date; 775 } 776 777 dates = $.map(dates, $.proxy(function(date){ 778 return DPGlobal.parseDate(date, this.o.format, this.o.language); 779 }, this)); 780 dates = $.grep(dates, $.proxy(function(date){ 781 return ( 782 !this.dateWithinRange(date) || 783 !date 784 ); 785 }, this), true); 786 this.dates.replace(dates); 787 788 if (this.dates.length) 789 this.viewDate = new Date(this.dates.get(-1)); 790 else if (this.viewDate < this.o.startDate) 791 this.viewDate = new Date(this.o.startDate); 792 else if (this.viewDate > this.o.endDate) 793 this.viewDate = new Date(this.o.endDate); 794 else 795 this.viewDate = this.o.defaultViewDate; 796 797 if (fromArgs){ 798 // setting date by clicking 799 this.setValue(); 800 } 801 else if (dates.length){ 802 // setting date by typing 803 if (String(oldDates) !== String(this.dates)) 804 this._trigger('changeDate'); 805 } 806 if (!this.dates.length && oldDates.length) 807 this._trigger('clearDate'); 808 809 this.fill(); 810 this.element.change(); 811 return this; 812 }, 813 814 fillDow: function(){ 815 var dowCnt = this.o.weekStart, 816 html = '<tr>'; 817 if (this.o.calendarWeeks){ 818 this.picker.find('.datepicker-days .datepicker-switch') 819 .attr('colspan', function(i, val){ 820 return parseInt(val) + 1; 821 }); 822 html += '<th class="cw"> </th>'; 823 } 824 while (dowCnt < this.o.weekStart + 7){ 825 html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>'; 826 } 827 html += '</tr>'; 828 this.picker.find('.datepicker-days thead').append(html); 829 }, 830 831 fillMonths: function(){ 832 var html = '', 833 i = 0; 834 while (i < 12){ 835 html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>'; 836 } 837 this.picker.find('.datepicker-months td').html(html); 838 }, 839 840 setRange: function(range){ 841 if (!range || !range.length) 842 delete this.range; 843 else 844 this.range = $.map(range, function(d){ 845 return d.valueOf(); 846 }); 847 this.fill(); 848 }, 849 850 getClassNames: function(date){ 851 var cls = [], 852 year = this.viewDate.getUTCFullYear(),
853 month = this.viewDate.getUTCMonth(), 854 today = new Date(); 855 if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){ 856 cls.push('old'); 857 } 858 else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){ 859 cls.push('new'); 860 } 861 if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) 862 cls.push('focused'); 863 // Compare internal UTC date with local today, not UTC today 864 if (this.o.todayHighlight && 865 date.getUTCFullYear() === today.getFullYear() && 866 date.getUTCMonth() === today.getMonth() && 867 date.getUTCDate() === today.getDate()){ 868 cls.push('today'); 869 } 870 if (this.dates.contains(date) !== -1) 871 cls.push('active'); 872 if (!this.dateWithinRange(date) || this.dateIsDisabled(date)){ 873 cls.push('disabled'); 874 } 875 if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){ 876 cls.push('highlighted'); 877 } 878 879 if (this.range){ 880 if (date > this.range[0] && date < this.range[this.range.length-1]){ 881 cls.push('range'); 882 } 883 if ($.inArray(date.valueOf(), this.range) !== -1){ 884 cls.push('selected'); 885 } 886 if (date.valueOf() === this.range[0]){ 887 cls.push('range-start'); 888 } 889 if (date.valueOf() === this.range[this.range.length-1]){ 890 cls.push('range-end'); 891 } 892 } 893 return cls; 894 }, 895 896 fill: function(){ 897 var d = new Date(this.viewDate), 898 year = d.getUTCFullYear(), 899 month = d.getUTCMonth(), 900 startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, 901 startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, 902 endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, 903 endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, 904 todaytxt = dates[this.o.language].today || dates['en'].today || '', 905 cleartxt = dates[this.o.language].clear || dates['en'].clear || '', 906 titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat, 907 tooltip; 908 if (isNaN(year) || isNaN(month)) 909 return; 910 this.picker.find('.datepicker-days thead .datepicker-switch') 911 .text(DPGlobal.formatDate(new UTCDate(year, month), titleFormat, this.o.language)); 912 this.picker.find('tfoot .today') 913 .text(todaytxt) 914 .toggle(this.o.todayBtn !== false); 915 this.picker.find('tfoot .clear') 916 .text(cleartxt) 917 .toggle(this.o.clearBtn !== false); 918 this.picker.find('thead .datepicker-title') 919 .text(this.o.title) 920 .toggle(this.o.title !== ''); 921 this.updateNavArrows(); 922 this.fillMonths(); 923 var prevMonth = UTCDate(year, month-1, 28), 924 day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); 925 prevMonth.setUTCDate(day); 926 prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); 927 var nextMonth = new Date(prevMonth); 928 if (prevMonth.getUTCFullYear() < 100){ 929 nextMonth.setUTCFullYear(prevMonth.getUTCFullYear()); 930 } 931 nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); 932 nextMonth = nextMonth.valueOf(); 933 var html = []; 934 var clsName; 935 while (prevMonth.valueOf() < nextMonth){ 936 if (prevMonth.getUTCDay() === this.o.weekStart){ 937 html.push('<tr>'); 938 if (this.o.calendarWeeks){ 939 // ISO 8601: First week contains first thursday. 940 // ISO also states week starts on Monday, but we can be more abstract here. 941 var 942 // Start of current week: based on weekstart/current date 943 ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5), 944 // Thursday of this week 945 th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5), 946 // First Thursday of year, year from thursday 947 yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5), 948 // Calendar week: ms between thursdays, div ms per day, div 7 days 949 calWeek = (th - yth) / 864e5 / 7 + 1; 950 html.push('<td class="cw">'+ calWeek +'</td>'); 951 952 } 953 } 954 clsName = this.getClassNames(prevMonth); 955 clsName.push('day'); 956 957 if (this.o.beforeShowDay !== $.noop){ 958 var before = this.o.beforeShowDay(this._utc_to_local(prevMonth)); 959 if (before === undefined) 960 before = {}; 961 else if (typeof(before) === 'boolean') 962 before = {enabled: before}; 963 else if (typeof(before) === 'string') 964 before = {classes: before}; 965 if (before.enabled === false) 966 clsName.push('disabled'); 967 if (before.classes) 968 clsName = clsName.concat(before.classes.split(/\s+/)); 969 if (before.tooltip) 970 tooltip = before.tooltip; 971 } 972 973 clsName = $.unique(clsName); 974 html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '><div>'+prevMonth.getUTCDate() + '</div></td>'); 975 tooltip = null; 976 if (prevMonth.getUTCDay() === this.o.weekEnd){ 977 html.push('</tr>'); 978 } 979 prevMonth.setUTCDate(prevMonth.getUTCDate()+1); 980 } 981 this.picker.find('.datepicker-days tbody').empty().append(html.join('')); 982 983 var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months'; 984 var months = this.picker.find('.datepicker-months') 985 .find('.datepicker-switch') 986 .text(this.o.maxViewMode < 2 ? monthsTitle : year) 987 .end() 988 .find('span').removeClass('active'); 989 990 $.each(this.dates, function(i, d){ 991 if (d.getUTCFullYear() === year) 992 months.eq(d.getUTCMonth()).addClass('active'); 993 }); 994 995 if (year < startYear || year > endYear){ 996 months.addClass('disabled'); 997 } 998 if (year === startYear){ 999 months.slice(0, startMonth).addClass('disabled'); 1000 } 1001 if (year === endYear){ 1002 months.slice(endMonth+1).addClass('disabled'); 1003 } 1004 1005 if (this.o.beforeShowMonth !== $.noop){ 1006 var that = this; 1007 $.each(months, function(i, month){ 1008 if (!$(month).hasClass('disabled')) { 1009 var moDate = new Date(year, i, 1); 1010 var before = that.o.beforeShowMonth(moDate); 1011 if (before === false) 1012 $(month).addClass('disabled'); 1013 } 1014 }); 1015 } 1016 1017 html = ''; 1018 year = parseInt(year/10, 10) * 10; 1019 var yearCont = this.picker.find('.datepicker-years') 1020 .find('.datepicker-switch') 1021 .text(year + '-' + (year + 9)) 1022 .end() 1023 .find('td'); 1024 year -= 1; 1025 var years = $.map(this.dates, function(d){ 1026 return d.getUTCFullYear(); 1027 }), 1028 classes;
1029 for (var i = -1; i < 11; i++){ 1030 classes = ['year']; 1031 tooltip = null; 1032 1033 if (i === -1) 1034 classes.push('old'); 1035 else if (i === 10) 1036 classes.push('new'); 1037 if ($.inArray(year, years) !== -1) 1038 classes.push('active'); 1039 if (year < startYear || year > endYear) 1040 classes.push('disabled'); 1041 1042 if (this.o.beforeShowYear !== $.noop) { 1043 var yrBefore = this.o.beforeShowYear(new Date(year, 0, 1)); 1044 if (yrBefore === undefined) 1045 yrBefore = {}; 1046 else if (typeof(yrBefore) === 'boolean') 1047 yrBefore = {enabled: yrBefore}; 1048 else if (typeof(yrBefore) === 'string') 1049 yrBefore = {classes: yrBefore}; 1050 if (yrBefore.enabled === false) 1051 classes.push('disabled'); 1052 if (yrBefore.classes) 1053 classes = classes.concat(yrBefore.classes.split(/\s+/)); 1054 if (yrBefore.tooltip) 1055 tooltip = yrBefore.tooltip; 1056 } 1057 1058 html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>' + year + '</span>'; 1059 year += 1; 1060 } 1061 yearCont.html(html); 1062 }, 1063 1064 updateNavArrows: function(){ 1065 if (!this._allow_update) 1066 return; 1067 1068 var d = new Date(this.viewDate), 1069 year = d.getUTCFullYear(), 1070 month = d.getUTCMonth(); 1071 switch (this.viewMode){ 1072 case 0: 1073 if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){ 1074 this.picker.find('.prev').css({visibility: 'hidden'}); 1075 } 1076 else { 1077 this.picker.find('.prev').css({visibility: 'visible'}); 1078 } 1079 if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){ 1080 this.picker.find('.next').css({visibility: 'hidden'}); 1081 } 1082 else { 1083 this.picker.find('.next').css({visibility: 'visible'}); 1084 } 1085 break; 1086 case 1: 1087 case 2: 1088 if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){ 1089 this.picker.find('.prev').css({visibility: 'hidden'}); 1090 } 1091 else { 1092 this.picker.find('.prev').css({visibility: 'visible'}); 1093 } 1094 if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){ 1095 this.picker.find('.next').css({visibility: 'hidden'}); 1096 } 1097 else { 1098 this.picker.find('.next').css({visibility: 'visible'}); 1099 } 1100 break; 1101 } 1102 }, 1103 1104 click: function(e){ 1105 e.preventDefault(); 1106 e.stopPropagation(); 1107 var target = $(e.target).closest('span, td, th'), 1108 year, month, day; 1109 if (target.length === 1){ 1110 switch (target[0].nodeName.toLowerCase()){ 1111 case 'th': 1112 switch (target[0].className){ 1113 case 'datepicker-switch': 1114 this.showMode(1); 1115 break; 1116 case 'prev': 1117 case 'next': 1118 var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1); 1119 switch (this.viewMode){ 1120 case 0: 1121 this.viewDate = this.moveMonth(this.viewDate, dir); 1122 this._trigger('changeMonth', this.viewDate); 1123 break; 1124 case 1: 1125 case 2: 1126 this.viewDate = this.moveYear(this.viewDate, dir); 1127 if (this.viewMode === 1) 1128 this._trigger('changeYear', this.viewDate); 1129 break; 1130 } 1131 this.fill(); 1132 break; 1133 case 'today': 1134 this.showMode(-2); 1135 var which = this.o.todayBtn === 'linked' ? null : 'view'; 1136 this._setDate(UTCToday(), which); 1137 break; 1138 case 'clear': 1139 this.clearDates(); 1140 break; 1141 } 1142 break; 1143 case 'span': 1144 if (!target.hasClass('disabled')){ 1145 this.viewDate.setUTCDate(1); 1146 if (target.hasClass('month')){ 1147 day = 1; 1148 month = target.parent().find('span').index(target); 1149 year = this.viewDate.getUTCFullYear(); 1150 this.viewDate.setUTCMonth(month); 1151 this._trigger('changeMonth', this.viewDate); 1152 if (this.o.minViewMode === 1){ 1153 this._setDate(UTCDate(year, month, day)); 1154 this.showMode(); 1155 } else { 1156 this.showMode(-1); 1157 } 1158 } 1159 else { 1160 day = 1;
1161 month = 0; 1162 year = parseInt(target.text(), 10)||0; 1163 this.viewDate.setUTCFullYear(year); 1164 this._trigger('changeYear', this.viewDate); 1165 if (this.o.minViewMode === 2){ 1166 this._setDate(UTCDate(year, month, day)); 1167 } 1168 this.showMode(-1); 1169 } 1170 this.fill(); 1171 } 1172 break; 1173 case 'td': 1174 // v Îν ÏαÏήÏÎµÎ¹Ï ÏÎ¬Î½Ï Ïε μια ημεÏομηνία 1175 if (target.hasClass('day') && !target.hasClass('disabled')){ 1176 day = parseInt(target.text(), 10)||1; 1177 year = this.viewDate.getUTCFullYear(); 1178 month = this.viewDate.getUTCMonth(); 1179 1180 dayofweek = getDayOfWeek(year+"-"+pad(month+1,2)+"-"+pad(day,2)); 1181 1182 // v Kan'ta apo twra auta 1183 $(".calendar-footer .daynumber").html(day); 1184 $(".calendar-footer .dayofweek").html(dayofweek); 1185 $(".calendar-footer .price1").html("$..."); 1186 $(".calendar-footer .price2").html("$..."); 1187 // v 1188 getPrice(day,month,year); 1189 1190 if (target.hasClass('old')){ 1191 if (month === 0){ 1192 month = 11; 1193 year -= 1; 1194 } 1195 else { 1196 month -= 1; 1197 } 1198 } 1199 else if (target.hasClass('new')){ 1200 if (month === 11){ 1201 month = 0; 1202 year += 1; 1203 } 1204 else { 1205 month += 1; 1206 } 1207 } 1208 this._setDate(UTCDate(year, month, day)); 1209 } 1210 break; 1211 } 1212 } 1213 if (this.picker.is(':visible') && this._focused_from){ 1214 $(this._focused_from).focus(); 1215 } 1216 delete this._focused_from; 1217 }, 1218 1219 _toggle_multidate: function(date){ 1220 var ix = this.dates.contains(date); 1221 if (!date){ 1222 this.dates.clear(); 1223 } 1224 1225 if (ix !== -1){ 1226 if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){ 1227 this.dates.remove(ix); 1228 } 1229 } else if (this.o.multidate === false) { 1230 this.dates.clear(); 1231 this.dates.push(date); 1232 } 1233 else { 1234 this.dates.push(date); 1235 } 1236 1237 if (typeof this.o.multidate === 'number') 1238 while (this.dates.length > this.o.multidate) 1239 this.dates.remove(0); 1240 }, 1241 1242 _setDate: function(date, which){ 1243 if (!which || which === 'date') 1244 this._toggle_multidate(date && new Date(date)); 1245 if (!which || which === 'view') 1246 this.viewDate = date && new Date(date); 1247 1248 this.fill(); 1249 this.setValue(); 1250 if (!which || which !== 'view') { 1251 this._trigger('changeDate'); 1252 } 1253 var element; 1254 if (this.isInput){ 1255 element = this.element; 1256 } 1257 else if (this.component){ 1258 element = this.element.find('input'); 1259 } 1260 if (element){ 1261 element.change(); 1262 } 1263 if (this.o.autoclose && (!which || which === 'date')){ 1264 this.hide(); 1265 } 1266 }, 1267 1268 moveDay: function(date, dir){ 1269 var newDate = new Date(date); 1270 newDate.setUTCDate(date.getUTCDate() + dir); 1271 1272 return newDate; 1273 }, 1274 1275 moveWeek: function(date, dir){ 1276 return this.moveDay(date, dir * 7); 1277 }, 1278 1279 moveMonth: function(date, dir){ 1280 if (!isValidDate(date)) 1281 return this.o.defaultViewDate; 1282 if (!dir) 1283 return date; 1284 var new_date = new Date(date.valueOf()), 1285 day = new_date.getUTCDate(), 1286 month = new_date.getUTCMonth(), 1287 mag = Math.abs(dir), 1288 new_month, test; 1289 dir = dir > 0 ? 1 : -1; 1290 if (mag === 1){ 1291 test = dir === -1 1292 // If going back one month, make sure month is not current month 1293 // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) 1294 ? function(){ 1295 return new_date.getUTCMonth() === month; 1296 } 1297 // If going forward one month, make sure month is as expected 1298 // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) 1299 : function(){ 1300 return new_date.getUTCMonth() !== new_month; 1301 }; 1302 new_month = month + dir; 1303 new_date.setUTCMonth(new_month); 1304 // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 1305 if (new_month < 0 || new_month > 11) 1306 new_month = (new_month + 12) % 12; 1307 } 1308 else { 1309 // For magnitudes >1, move one month at a time... 1310 for (var i=0; i < mag; i++) 1311 // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... 1312 new_date = this.moveMonth(new_date, dir); 1313 // ...then reset the day, keeping it in the new month 1314 new_month = new_date.getUTCMonth(); 1315 new_date.setUTCDate(day); 1316 test = function(){ 1317 return new_month !== new_date.getUTCMonth(); 1318 }; 1319 } 1320 // Common date-resetting loop -- if date is beyond end of month, make it 1321 // end of month 1322 while (test()){ 1323 new_date.setUTCDate(--day); 1324 new_date.setUTCMonth(new_month); 1325 } 1326 return new_date; 1327 }, 1328 1329 moveYear: function(date, dir){ 1330 return this.moveMonth(date, dir*12); 1331 }, 1332 1333 moveAvailableDate: function(date, dir, fn){ 1334 do { 1335 date = this[fn](date, dir); 1336 1337 if (!this.dateWithinRange(date)) 1338 return false;
vendor: 4,695 bytes, lines 1339-1522
1339 1340 fn = 'moveDay'; 1341 } 1342 while (this.dateIsDisabled(date)); 1343 1344 return date; 1345 }, 1346 1347 weekOfDateIsDisabled: function(date){ 1348 return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1; 1349 }, 1350 1351 dateIsDisabled: function(date){ 1352 return ( 1353 this.weekOfDateIsDisabled(date) || 1354 $.grep(this.o.datesDisabled, function(d){ 1355 return isUTCEquals(date, d); 1356 }).length > 0 1357 ); 1358 }, 1359 1360 dateWithinRange: function(date){ 1361 return date >= this.o.startDate && date <= this.o.endDate; 1362 }, 1363 1364 keydown: function(e){ 1365 if (!this.picker.is(':visible')){ 1366 if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker 1367 this.show(); 1368 e.stopPropagation(); 1369 } 1370 return; 1371 } 1372 var dateChanged = false, 1373 dir, newViewDate, 1374 focusDate = this.focusDate || this.viewDate; 1375 switch (e.keyCode){ 1376 case 27: // escape 1377 if (this.focusDate){ 1378 this.focusDate = null; 1379 this.viewDate = this.dates.get(-1) || this.viewDate; 1380 this.fill(); 1381 } 1382 else 1383 this.hide(); 1384 e.preventDefault(); 1385 e.stopPropagation(); 1386 break; 1387 case 37: // left 1388 case 38: // up 1389 case 39: // right 1390 case 40: // down 1391 if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7) 1392 break; 1393 dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1; 1394 if (e.ctrlKey){ 1395 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear'); 1396 1397 if (newViewDate) 1398 this._trigger('changeYear', this.viewDate); 1399 } 1400 else if (e.shiftKey){ 1401 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth'); 1402 1403 if (newViewDate) 1404 this._trigger('changeMonth', this.viewDate); 1405 } 1406 else if (e.keyCode === 37 || e.keyCode === 39){ 1407 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay'); 1408 } 1409 else if (!this.weekOfDateIsDisabled(focusDate)){ 1410 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek'); 1411 } 1412 if (newViewDate){ 1413 this.focusDate = this.viewDate = newViewDate; 1414 this.setValue(); 1415 this.fill(); 1416 e.preventDefault(); 1417 } 1418 break; 1419 case 13: // enter 1420 if (!this.o.forceParse) 1421 break; 1422 focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; 1423 if (this.o.keyboardNavigation) { 1424 this._toggle_multidate(focusDate); 1425 dateChanged = true; 1426 } 1427 this.focusDate = null; 1428 this.viewDate = this.dates.get(-1) || this.viewDate; 1429 this.setValue(); 1430 this.fill(); 1431 if (this.picker.is(':visible')){ 1432 e.preventDefault(); 1433 e.stopPropagation(); 1434 if (this.o.autoclose) 1435 this.hide(); 1436 } 1437 break; 1438 case 9: // tab 1439 this.focusDate = null; 1440 this.viewDate = this.dates.get(-1) || this.viewDate; 1441 this.fill(); 1442 this.hide(); 1443 break; 1444 } 1445 if (dateChanged){ 1446 if (this.dates.length) 1447 this._trigger('changeDate'); 1448 else 1449 this._trigger('clearDate'); 1450 var element; 1451 if (this.isInput){ 1452 element = this.element; 1453 } 1454 else if (this.component){ 1455 element = this.element.find('input'); 1456 } 1457 if (element){ 1458 element.change(); 1459 } 1460 } 1461 }, 1462 1463 showMode: function(dir){ 1464 if (dir){ 1465 this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir)); 1466 } 1467 this.picker 1468 .children('div') 1469 .hide() 1470 .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName) 1471 .show(); 1472 this.updateNavArrows(); 1473 } 1474 }; 1475 1476 var DateRangePicker = function(element, options){ 1477 $(element).data('datepicker', this); 1478 this.element = $(element); 1479 this.inputs = $.map(options.inputs, function(i){ 1480 return i.jquery ? i[0] : i; 1481 }); 1482 delete options.inputs; 1483 1484 datepickerPlugin.call($(this.inputs), options) 1485 .on('changeDate', $.proxy(this.dateUpdated, this)); 1486 1487 this.pickers = $.map(this.inputs, function(i){ 1488 return $(i).data('datepicker'); 1489 }); 1490 this.updateDates(); 1491 }; 1492 DateRangePicker.prototype = { 1493 updateDates: function(){ 1494 this.dates = $.map(this.pickers, function(i){ 1495 return i.getUTCDate(); 1496 }); 1497 this.updateRanges(); 1498 }, 1499 updateRanges: function(){ 1500 var range = $.map(this.dates, function(d){ 1501 return d.valueOf(); 1502 }); 1503 $.each(this.pickers, function(i, p){ 1504 p.setRange(range); 1505 }); 1506 }, 1507 dateUpdated: function(e){ 1508 // `this.updating` is a workaround for preventing infinite recursion 1509 // between `changeDate` triggering and `setUTCDate` calling. Until 1510 // there is a better mechanism. 1511 if (this.updating) 1512 return; 1513 this.updating = true; 1514 1515 var dp = $(e.target).data('datepicker'); 1516 1517 if (typeof(dp) === "undefined") { 1518 return; 1519 } 1520 1521 var new_date = dp.getUTCDate(), 1522 i = $.inArray(e.target, this.inputs),
1523 j = i - 1, 1524 k = i + 1, 1525 l = this.inputs.length; 1526 if (i === -1) 1527 return; 1528 1529 $.each(this.pickers, function(i, p){ 1530 if (!p.getUTCDate()) 1531 p.setUTCDate(new_date); 1532 }); 1533 1534 if (new_date < this.dates[j]){ 1535 // Date being moved earlier/left 1536 while (j >= 0 && new_date < this.dates[j]){ 1537 this.pickers[j--].setUTCDate(new_date); 1538 } 1539 } 1540 else if (new_date > this.dates[k]){ 1541 // Date being moved later/right 1542 while (k < l && new_date > this.dates[k]){ 1543 this.pickers[k++].setUTCDate(new_date); 1544 } 1545 } 1546 this.updateDates(); 1547 1548 delete this.updating; 1549 }, 1550 remove: function(){ 1551 $.map(this.pickers, function(p){ p.remove(); }); 1552 delete this.element.data().datepicker; 1553 } 1554 }; 1555 1556 function opts_from_el(el, prefix){ 1557 // Derive options from element data-attrs 1558 var data = $(el).data(), 1559 out = {}, inkey, 1560 replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'); 1561 prefix = new RegExp('^' + prefix.toLowerCase()); 1562 function re_lower(_,a){ 1563 return a.toLowerCase(); 1564 } 1565 for (var key in data) 1566 if (prefix.test(key)){ 1567 inkey = key.replace(replace, re_lower); 1568 out[inkey] = data[key]; 1569 } 1570 return out; 1571 } 1572 1573 function opts_from_locale(lang){ 1574 // Derive options from locale plugins 1575 var out = {}; 1576 // Check if "de-DE" style date is available, if not language should 1577 // fallback to 2 letter code eg "de" 1578 if (!dates[lang]){ 1579 lang = lang.split('-')[0]; 1580 if (!dates[lang]) 1581 return; 1582 } 1583 var d = dates[lang]; 1584 $.each(locale_opts, function(i,k){ 1585 if (k in d) 1586 out[k] = d[k]; 1587 }); 1588 return out; 1589 } 1590 1591 var old = $.fn.datepicker; 1592 var datepickerPlugin = function(option){ 1593 var args = Array.apply(null, arguments); 1594 args.shift(); 1595 var internal_return; 1596 this.each(function(){ 1597 var $this = $(this), 1598 data = $this.data('datepicker'), 1599 options = typeof option === 'object' && option; 1600 if (!data){ 1601 var elopts = opts_from_el(this, 'date'), 1602 // Preliminary otions 1603 xopts = $.extend({}, defaults, elopts, options), 1604 locopts = opts_from_locale(xopts.language), 1605 // Options priority: js args, data-attrs, locales, defaults 1606 opts = $.extend({}, defaults, locopts, elopts, options); 1607 if ($this.hasClass('input-daterange') || opts.inputs){ 1608 $.extend(opts, { 1609 inputs: opts.inputs || $this.find('input').toArray() 1610 }); 1611 data = new DateRangePicker(this, opts); 1612 } 1613 else { 1614 data = new Datepicker(this, opts); 1615 } 1616 $this.data('datepicker', data); 1617 } 1618 if (typeof option === 'string' && typeof data[option] === 'function'){ 1619 internal_return = data[option].apply(data, args); 1620 } 1621 }); 1622 1623 if ( 1624 internal_return === undefined || 1625 internal_return instanceof Datepicker || 1626 internal_return instanceof DateRangePicker 1627 ) 1628 return this; 1629 1630 if (this.length > 1) 1631 throw new Error('Using only allowed for the collection of a single element (' + option + ' function)'); 1632 else 1633 return internal_return; 1634 }; 1635 $.fn.datepicker = datepickerPlugin; 1636 1637 var defaults = $.fn.datepicker.defaults = { 1638 autoclose: false, 1639 beforeShowDay: $.noop, 1640 beforeShowMonth: $.noop, 1641 beforeShowYear: $.noop, 1642 calendarWeeks: false, 1643 clearBtn: false, 1644 toggleActive: false, 1645 daysOfWeekDisabled: [], 1646 daysOfWeekHighlighted: [], 1647 datesDisabled: [], 1648 endDate: Infinity, 1649 forceParse: true, 1650 format: 'mm/dd/yyyy', 1651 keyboardNavigation: true, 1652 language: 'en', 1653 minViewMode: 0, 1654 maxViewMode: 2, 1655 multidate: false, 1656 multidateSeparator: ',', 1657 orientation: "auto", 1658 rtl: false, 1659 startDate: -Infinity, 1660 startView: 0, 1661 todayBtn: false, 1662 todayHighlight: false, 1663 weekStart: 0, 1664 disableTouchKeyboard: false, 1665 enableOnReadonly: true, 1666 showOnFocus: true, 1667 zIndexOffset: 10, 1668 container: 'body', 1669 immediateUpdates: false, 1670 title: '' 1671 }; 1672 var locale_opts = $.fn.datepicker.locale_opts = [ 1673 'format', 1674 'rtl', 1675 'weekStart' 1676 ]; 1677 1678 // v here 1679 $.fn.datepicker.Constructor = Datepicker; 1680 var dates = $.fn.datepicker.dates = { 1681 en: { 1682 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 1683 daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 1684 daysMin: ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"], 1685 months: ["JAN", "FEB", "MAR", "APR", "MAY", "JUNE", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"], 1686 monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 1687 today: "Today", 1688 clear: "Clear", 1689 titleFormat: "MM yyyy" 1690 } 1691 }; 1692 1693 var DPGlobal = { 1694 modes: [ 1695 { 1696 clsName: 'days', 1697 navFnc: 'Month', 1698 navStep: 1 1699 }, 1700 { 1701 clsName: 'months', 1702 navFnc: 'FullYear', 1703 navStep: 1 1704 }, 1705 { 1706 clsName: 'years', 1707 navFnc: 'FullYear', 1708 navStep: 10 1709 }], 1710 isLeapYear: function(year){ 1711 return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 1712 }, 1713 getDaysInMonth: function(year, month){ 1714 return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; 1715 }, 1716 validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, 1717 nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g, 1718 parseFormat: function(format){ 1719 if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function') 1720 return format; 1721 // IE treats \0 as a string end in inputs (truncating the value), 1722 // so it's a bad format delimiter, anyway 1723 var separators = format.replace(this.validParts, '\0').split('\0'), 1724 parts = format.match(this.validParts); 1725 if (!separators || !separators.length || !parts || parts.length === 0){ 1726 throw new Error("Invalid date format."); 1727 } 1728 return {separators: separators, parts: parts}; 1729 }, 1730 parseDate: function(date, format, language){ 1731 if (!date) 1732 return undefined; 1733 if (date instanceof Date) 1734 return date; 1735 if (typeof format === 'string') 1736 format = DPGlobal.parseFormat(format); 1737 if (format.toValue) 1738 return format.toValue(date, format, language); 1739 var part_re = /([\-+]\d+)([dmwy])/, 1740 parts = date.match(/([\-+]\d+)([dmwy])/g), 1741 fn_map = { 1742 d: 'moveDay', 1743 m: 'moveMonth', 1744 w: 'moveWeek', 1745 y: 'moveYear' 1746 }, 1747 part, dir, i, fn;
vendor: 5,469 bytes, lines 1748-1929
1748 if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ 1749 date = new Date(); 1750 for (i=0; i < parts.length; i++){ 1751 part = part_re.exec(parts[i]); 1752 dir = parseInt(part[1]); 1753 fn = fn_map[part[2]]; 1754 date = Datepicker.prototype[fn](date, dir); 1755 } 1756 return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); 1757 } 1758 parts = date && date.match(this.nonpunctuation) || []; 1759 date = new Date(); 1760 var parsed = {}, 1761 setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], 1762 setters_map = { 1763 yyyy: function(d,v){ 1764 return d.setUTCFullYear(v); 1765 }, 1766 yy: function(d,v){ 1767 return d.setUTCFullYear(2000+v); 1768 }, 1769 m: function(d,v){ 1770 if (isNaN(d)) 1771 return d; 1772 v -= 1; 1773 while (v < 0) v += 12; 1774 v %= 12; 1775 d.setUTCMonth(v); 1776 while (d.getUTCMonth() !== v) 1777 d.setUTCDate(d.getUTCDate()-1); 1778 return d; 1779 }, 1780 d: function(d,v){ 1781 return d.setUTCDate(v); 1782 } 1783 }, 1784 val, filtered; 1785 setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; 1786 setters_map['dd'] = setters_map['d']; 1787 date = UTCToday(); 1788 var fparts = format.parts.slice(); 1789 // Remove noop parts 1790 if (parts.length !== fparts.length){ 1791 fparts = $(fparts).filter(function(i,p){ 1792 return $.inArray(p, setters_order) !== -1; 1793 }).toArray(); 1794 } 1795 // Process remainder 1796 function match_part(){ 1797 var m = this.slice(0, parts[i].length), 1798 p = parts[i].slice(0, m.length); 1799 return m.toLowerCase() === p.toLowerCase(); 1800 } 1801 if (parts.length === fparts.length){ 1802 var cnt; 1803 for (i=0, cnt = fparts.length; i < cnt; i++){ 1804 val = parseInt(parts[i], 10); 1805 part = fparts[i]; 1806 if (isNaN(val)){ 1807 switch (part){ 1808 case 'MM': 1809 filtered = $(dates[language].months).filter(match_part); 1810 val = $.inArray(filtered[0], dates[language].months) + 1; 1811 break; 1812 case 'M': 1813 filtered = $(dates[language].monthsShort).filter(match_part); 1814 val = $.inArray(filtered[0], dates[language].monthsShort) + 1; 1815 break; 1816 } 1817 } 1818 parsed[part] = val; 1819 } 1820 var _date, s; 1821 for (i=0; i < setters_order.length; i++){ 1822 s = setters_order[i]; 1823 if (s in parsed && !isNaN(parsed[s])){ 1824 _date = new Date(date); 1825 setters_map[s](_date, parsed[s]); 1826 if (!isNaN(_date)) 1827 date = _date; 1828 } 1829 } 1830 } 1831 return date; 1832 }, 1833 formatDate: function(date, format, language){ 1834 if (!date) 1835 return ''; 1836 if (typeof format === 'string') 1837 format = DPGlobal.parseFormat(format); 1838 if (format.toDisplay) 1839 return format.toDisplay(date, format, language); 1840 var val = { 1841 d: date.getUTCDate(), 1842 D: dates[language].daysShort[date.getUTCDay()], 1843 DD: dates[language].days[date.getUTCDay()], 1844 m: date.getUTCMonth() + 1, 1845 M: dates[language].monthsShort[date.getUTCMonth()], 1846 MM: dates[language].months[date.getUTCMonth()], 1847 yy: date.getUTCFullYear().toString().substring(2), 1848 yyyy: date.getUTCFullYear() 1849 }; 1850 val.dd = (val.d < 10 ? '0' : '') + val.d; 1851 val.mm = (val.m < 10 ? '0' : '') + val.m; 1852 date = []; 1853 var seps = $.extend([], format.separators); 1854 for (var i=0, cnt = format.parts.length; i <= cnt; i++){ 1855 if (seps.length) 1856 date.push(seps.shift()); 1857 date.push(val[format.parts[i]]); 1858 } 1859 return date.join(''); 1860 }, 1861 headTemplate: '<thead>'+ 1862 '<tr>'+ 1863 '<th colspan="7" class="datepicker-title"></th>'+ 1864 '</tr>'+ 1865 '<tr>'+ 1866 '<th colspan="3" class="prev">«</th>'+ 1867 '<th colspan="3"class="datepicker-switch"></th>'+ 1868 '<th class="next">»</th>'+ 1869 '</tr>'+ 1870 '</thead>', 1871 contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', 1872 footTemplate: '<tfoot>'+ 1873 '<tr>'+ 1874 '<th colspan="7" class="today"></th>'+ 1875 '</tr>'+ 1876 '<tr>'+ 1877 '<th colspan="7" class="clear"></th>'+ 1878 '</tr>'+ 1879 '</tfoot>' 1880 }; 1881 DPGlobal.template = '<div class="datepicker">'+ 1882 '<div class="datepicker-days">'+ 1883 '<table class=" table-condensed">'+ 1884 DPGlobal.headTemplate+ 1885 '<tbody></tbody>'+ 1886 DPGlobal.footTemplate+ 1887 '</table>'+ 1888 '<div class="calendar-footer">'+ 1889 ' <div class="daynumber">..</div><div class="dayofweek">...</div>'+ 1890 ' <div class="price price1">$...</div><div class="price price2">$...</div>'+ 1891 ' <div class="product product1">8 YEARS & OLDER</div><div class="product product2">7 YEARS & YOUNGER</div>'+ 1892 '</div> '+ 1893 '</div>'+ 1894 '<div class="datepicker-months">'+ 1895 '<table class="table-condensed">'+ 1896 DPGlobal.headTemplate+ 1897 DPGlobal.contTemplate+ 1898 DPGlobal.footTemplate+ 1899 '</table>'+ 1900 '</div>'+ 1901 '<div class="datepicker-years">'+ 1902 '<table class="table-condensed">'+ 1903 DPGlobal.headTemplate+ 1904 DPGlobal.contTemplate+ 1905 DPGlobal.footTemplate+ 1906 '</table>'+ 1907 '</div>'+ 1908 '</div>'; 1909 1910 $.fn.datepicker.DPGlobal = DPGlobal; 1911 1912 1913 /* DATEPICKER NO CONFLICT 1914 * =================== */ 1915 1916 $.fn.datepicker.noConflict = function(){ 1917 $.fn.datepicker = old; 1918 return this; 1919 }; 1920 1921 /* DATEPICKER VERSION 1922 * =================== */ 1923 $.fn.datepicker.version = '1.5.1'; 1924 1925 /* DATEPICKER DATA-API 1926 * ================== */ 1927 1928 $(document).on( 1929 'focus.datepicker.data-api click.datepicker.data-api',
1930 '[data-provide="datepicker"]', 1931 function(e){ 1932 var $this = $(this); 1933 if ($this.data('datepicker')) 1934 return; 1935 e.preventDefault(); 1936 // component click requires us to explicitly show it 1937 datepickerPlugin.call($this, 'show'); 1938 } 1939 ); 1940 $(function(){ 1941 datepickerPlugin.call($('[data-provide="datepicker-inline"]')); 1942 }); 1943 1944})); 1945 1946 1947 1948 1949 1950// v 1951 1952function pad(num, size) { 1953 var s = num+""; 1954 while (s.length < size) s = "0" + s; 1955 return s; 1956} 1957 1958function getDayOfWeek(date) { 1959 console.log(date); 1960 var dayOfWeek = new Date(date).getDay(); 1961 return isNaN(dayOfWeek) ? null : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayOfWeek]; 1962} 1963 1964function getPrice(day,month,year) { 1965 1966 mysqldate = year+"-"+pad(month+1,2)+"-"+pad(day,2); 1967 1968 $.ajax({ 1969 url: "/en/ajax_calls/price-for-date/&modonly=1", 1970 type: "post", 1971 dataType: "json", 1972 data: {date:mysqldate}, 1973 success: function(data){ 1974 1975 dayofweek = getDayOfWeek(year+"-"+pad(month+1,2)+"-"+pad(day,2)); 1976 1977 //console.log(dayofweek+"*"); 1978 if (data.price2==undefined) { 1979 data.price2=data.price1; 1980 } 1981 1982 $(".calendar-footer .daynumber").html(day); 1983 $(".calendar-footer .dayofweek").html(dayofweek); 1984 $(".calendar-footer .price1").html("$"+data.price1); 1985 $(".calendar-footer .price2").html("$"+data.price2); 1986 1987 $(".product_price.price1").html(data.price1); 1988 $(".product_price.price2").html(data.price2); 1989 1990 1991 }, 1992 error: function(){ 1993 1994 } 1995 }); // end of ajax call 1996}
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.