1/*! jQuery UI - v1.12.1 - 2019-02-17 2 * http://jqueryui.com 3 * Modified version of jQuery Datepicker 4 * Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 6( function( factory ) { 7 'use strict'; 8 if ( typeof window.define === 'function' && window.define.amd ) { 9 // AMD. Register as an anonymous module. 10 window.define( [ 'jquery' ], factory ); 11 } else { 12 // Browser globals 13 factory( window.jQuery ); 14 } 15}( function( $ ) { 16 'use strict'; 17 /*! 18 * jQuery UI Datepicker 1.12.1 (Modified version of jQuery Datepicker) 19 * http://jqueryui.com 20 * 21 * Copyright jQuery Foundation and other contributors 22 * Released under the MIT license. 23 * http://jquery.org/license 24 * 25 * http://api.jqueryui.com/datepicker/ 26 */ 27 28 var datepicker_instActive; 29 30 $.ui.tm_datepicker = $.ui.tm_datepicker || {}; 31 if ( $.ui.tm_datepicker.version ) { 32 return; 33 } 34 35 $.extend( $.ui, { tm_datepicker: { version: '1.11.4' } } ); 36 37 function datepicker_getZindex( elem ) { 38 var position, value; 39 while ( elem.length && elem[ 0 ] !== document ) { 40 // Ignore z-index if position is set to a value where z-index is ignored by the browser 41 // This makes behavior of this function consistent across browsers 42 // WebKit always returns auto if the element is positioned 43 position = elem.css( 'position' ); 44 if ( position === 'absolute' || position === 'relative' || position === 'fixed' ) { 45 // IE returns 0 when zIndex is not specified 46 // other browsers return a string 47 // we ignore the case of nested elements with an explicit value of 0 48 value = parseInt( elem.css( 'zIndex' ), 10 ); 49 if ( ! isNaN( value ) && value !== 0 ) { 50 return value; 51 } 52 } 53 elem = elem.parent(); 54 } 55 56 return 0; 57 } 58 59 /* 60 * Bind hover events for datepicker elements. 61 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 62 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 63 */ 64 function datepicker_handleMouseover( that ) { 65 if ( ! $.tm_datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 66 $( that ).parents( '.ui-tm-datepicker-calendar' ).find( 'a' ).removeClass( 'ui-state-hover' ); 67 $( that ).addClass( 'ui-state-hover' ); 68 if ( that.className.indexOf( 'ui-tm-datepicker-prev' ) !== -1 ) { 69 $( that ).addClass( 'ui-tm-datepicker-prev-hover' ); 70 } 71 if ( that.className.indexOf( 'ui-tm-datepicker-next' ) !== -1 ) { 72 $( that ).addClass( 'ui-tm-datepicker-next-hover' ); 73 } 74 } 75 } 76 77 function datepicker_bindHover( dpDiv ) { 78 var selector = 'button, .ui-tm-datepicker-prev, .ui-tm-datepicker-next, .ui-tm-datepicker-calendar td a'; 79 return dpDiv 80 .on( 'mouseout', selector, function() { 81 $( this ).removeClass( 'ui-state-hover' ); 82 if ( this.className.indexOf( 'ui-tm-datepicker-prev' ) !== -1 ) { 83 $( this ).removeClass( 'ui-tm-datepicker-prev-hover' ); 84 } 85 if ( this.className.indexOf( 'ui-tm-datepicker-next' ) !== -1 ) { 86 $( this ).removeClass( 'ui-tm-datepicker-next-hover' ); 87 } 88 } ) 89 .on( 'mouseover', selector, function() { 90 datepicker_handleMouseover( this ); 91 } ); 92 } 93 94 /* jQuery extend now ignores nulls! */ 95 function datepicker_extendRemove( target, props ) { 96 var name; 97 98 $.extend( target, props ); 99 for ( name in props ) { 100 if ( props[ name ] === null ) { 101 target[ name ] = props[ name ]; 102 } 103 } 104 return target; 105 } 106 107 /* Date picker manager. 108 Use the singleton instance of this class, $.tm_datepicker, to interact with the date picker. 109 Settings for (groups of) date pickers are maintained in an instance object, 110 allowing multiple different settings on the same page. */ 111 112 function Datepicker() { 113 this._curInst = null; // The current instance in use 114 this._keyEvent = false; // If the last event was a key event 115 this._disabledInputs = []; // List of date picker inputs that have been disabled 116 this._datepickerShowing = false; // True if the popup picker is showing , false if not 117 this._inDialog = false; // True if showing within a "dialog", false if not 118 this._mainDivId = 'ui-tm-datepicker-div'; // The ID of the main datepicker division 119 this._inlineClass = 'ui-tm-datepicker-inline'; // The name of the inline marker class 120 this._appendClass = 'ui-tm-datepicker-append'; // The name of the append marker class 121 this._triggerClass = 'ui-tm-datepicker-trigger'; // The name of the trigger marker class 122 this._dialogClass = 'ui-tm-datepicker-dialog'; // The name of the dialog marker class 123 this._disableClass = 'ui-tm-datepicker-disabled'; // The name of the disabled covering marker class 124 this._unselectableClass = 'ui-tm-datepicker-unselectable'; // The name of the unselectable cell marker class 125 this._currentClass = 'ui-tm-datepicker-current-day'; // The name of the current day marker class 126 this._dayOverClass = 'ui-tm-datepicker-days-cell-over'; // The name of the day hover marker class 127 this.regional = []; // Available regional settings, indexed by language code 128 this.regional[ '' ] = { 129 // Default regional settings 130 closeText: 'Done', // Display text for close link 131 prevText: 'Prev', // Display text for previous month link 132 nextText: 'Next', // Display text for next month link 133 currentText: 'Today', // Display text for current month link 134 monthNames: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], // Names of months for drop-down and formatting 135 monthNamesShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ], // For formatting 136 dayNames: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], // For formatting 137 dayNamesShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], // For formatting 138 dayNamesMin: [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ], // Column headings for days starting at Sunday 139 weekHeader: 'Wk', // Column header for week of the year 140 dateFormat: 'mm/dd/yy', // See format options on parseDate 141 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 142 isRTL: false, // True if right-to-left language, false if left-to-right 143 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 144 yearSuffix: '' // Additional text to append to the year in the month headers 145 }; 146 this._defaults = { 147 // Global defaults for all the date picker instances 148 showOn: 'focus', // "focus" for popup on focus, 149 // "button" for trigger button, or "both" for either
vendor: 5,956 bytes, lines 150-264
150 showAnim: 'fadeIn', // Name of jQuery animation for popup 151 showOptions: {}, // Options for enhanced animations 152 defaultDate: null, // Used when field is blank: actual date, 153 // +/-number for offset from today, null for today 154 appendText: '', // Display text following the input box, e.g. showing the format 155 buttonText: '...', // Text for trigger button 156 buttonImage: '', // URL for trigger button image 157 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 158 hideIfNoPrevNext: false, // True to hide next/previous month links 159 // if not applicable, false to just disable them 160 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 161 gotoCurrent: false, // True if today link goes back to current selection instead 162 changeMonth: false, // True if month can be selected directly, false if only prev/next 163 changeYear: false, // True if year can be selected directly, false if only prev/next 164 yearRange: 'c-10:c+10', // Range of years to display in drop-down, 165 // either relative to today's year (-nn:+nn), relative to currently displayed year 166 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 167 showOtherMonths: false, // True to show dates in other months, false to leave blank 168 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 169 showWeek: false, // True to show week of the year, false to not show it 170 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 171 // takes a Date and returns the number of the week for it 172 shortYearCutoff: '+10', // Short year values < this are in the current century, 173 // > this are in the previous century, 174 // string value starting with "+" for current year + value 175 minDate: null, // The earliest selectable date, or null for no limit 176 maxDate: null, // The latest selectable date, or null for no limit 177 duration: 'fast', // Duration of display/closure 178 beforeShowDay: null, // Function that takes a date and returns an array with 179 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 180 // [2] = cell title (optional), e.g. $.tm_datepicker.noWeekends 181 beforeShow: null, // Function that takes an input field and 182 // returns a set of custom settings for the date picker 183 onSelect: null, // Define a callback function when a date is selected 184 onChangeMonthYear: null, // Define a callback function when the month or year is changed 185 onClose: null, // Define a callback function when the datepicker is closed 186 numberOfMonths: 1, // Number of months to show at a time 187 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 188 stepMonths: 1, // Number of months to step back/forward 189 stepBigMonths: 12, // Number of months to step back/forward for the big links 190 altField: '', // Selector for an alternate field to store selected dates into 191 altFormat: '', // The date format to use for the alternate field 192 constrainInput: true, // The input is constrained by the current date format 193 showButtonPanel: false, // True to show button panel, false to not show it 194 autoSize: false, // True to size the input for the date format, false to leave as is 195 disabled: false // The initial disabled state 196 }; 197 $.extend( this._defaults, this.regional[ '' ] ); 198 this.regional.en = $.extend( true, {}, this.regional[ '' ] ); 199 this.regional[ 'en-US' ] = $.extend( true, {}, this.regional.en ); 200 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-tm-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 201 } 202 203 $.extend( Datepicker.prototype, { 204 /* Class name added to elements to indicate already configured with a date picker. */ 205 markerClassName: 'hasDatepicker', 206 207 //Keep track of the maximum number of rows displayed (see #7043) 208 maxRows: 4, 209 210 // TODO rename to "widget" when switching to widget factory 211 _widgetDatepicker: function() { 212 return this.dpDiv; 213 }, 214 215 /* Override the default settings for all instances of the date picker. 216 * @param settings object - the new settings to use as defaults (anonymous object) 217 * @return the manager object 218 */ 219 setDefaults: function( settings ) { 220 datepicker_extendRemove( this._defaults, settings || {} ); 221 return this; 222 }, 223 224 /* Attach the date picker to a jQuery selection. 225 * @param target element - the target input field or division or span 226 * @param settings object - the new settings to use for this date picker instance (anonymous) 227 */ 228 _attachDatepicker: function( target, settings ) { 229 var nodeName, inline, inst; 230 nodeName = target.nodeName.toLowerCase(); 231 inline = nodeName === 'div' || nodeName === 'span'; 232 if ( ! target.id ) { 233 this.uuid += 1; 234 target.id = 'dp' + this.uuid; 235 } 236 inst = this._newInst( $( target ), inline ); 237 inst.settings = $.extend( {}, settings || {} ); 238 if ( nodeName === 'input' ) { 239 this._connectDatepicker( target, inst ); 240 } else if ( inline ) { 241 this._inlineDatepicker( target, inst ); 242 } 243 }, 244 245 /* Create a new instance object. */ 246 _newInst: function( target, inline ) { 247 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_-])/g, '\\\\$1' ); // escape jQuery meta chars 248 return { 249 id: id, 250 input: target, // associated target 251 selectedDay: 0, 252 selectedMonth: 0, 253 selectedYear: 0, // current selection 254 drawMonth: 0, 255 drawYear: 0, // month being drawn 256 inline: inline, // is datepicker inline or not 257 // presentation div 258 dpDiv: ! inline ? this.dpDiv : datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-tm-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) 259 }; 260 }, 261 262 /* Attach the date picker to an input field. */ 263 _connectDatepicker: function( target, inst ) { 264 var input = $( target );
vendor: 4,072 bytes, lines 265-382
265 inst.append = $( [] ); 266 inst.trigger = $( [] ); 267 if ( input.hasClass( this.markerClassName ) ) { 268 return; 269 } 270 this._attachments( input, inst ); 271 input.addClass( this.markerClassName ).on( 'keydown', this._doKeyDown ).on( 'keypress', this._doKeyPress ).on( 'keyup', this._doKeyUp ); 272 this._autoSize( inst ); 273 $.data( target, 'datepicker', inst ); 274 275 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 276 if ( inst.settings.disabled ) { 277 this._disableDatepicker( target ); 278 } 279 }, 280 281 /* Make attachments based on settings. */ 282 _attachments: function( input, inst ) { 283 var showOn, 284 buttonText, 285 buttonImage, 286 appendText = this._get( inst, 'appendText' ), 287 isRTL = this._get( inst, 'isRTL' ); 288 289 if ( inst.append ) { 290 inst.append.remove(); 291 } 292 if ( appendText ) { 293 inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + '</span>' ); 294 input[ isRTL ? 'before' : 'after' ]( inst.append ); 295 } 296 297 input.off( 'focus', this._showDatepicker ); 298 299 if ( inst.trigger ) { 300 inst.trigger.remove(); 301 } 302 303 showOn = this._get( inst, 'showOn' ); 304 if ( showOn === 'focus' || showOn === 'both' ) { 305 // pop-up date picker when in the marked field 306 input.on( 'focus', this._showDatepicker ); 307 } 308 if ( showOn === 'button' || showOn === 'both' ) { 309 // pop-up date picker when button clicked 310 buttonText = this._get( inst, 'buttonText' ); 311 buttonImage = this._get( inst, 'buttonImage' ); 312 inst.trigger = $( 313 this._get( inst, 'buttonImageOnly' ) 314 ? $( '<img/>' ).addClass( this._triggerClass ).attr( { src: buttonImage, alt: buttonText, title: buttonText } ) 315 : $( "<button type='button'></button>" ) 316 .addClass( this._triggerClass ) 317 .html( ! buttonImage ? buttonText : $( '<img/>' ).attr( { src: buttonImage, alt: buttonText, title: buttonText } ) ) 318 ); 319 input[ isRTL ? 'before' : 'after' ]( inst.trigger ); 320 inst.trigger.on( 'click', function() { 321 if ( $.tm_datepicker._datepickerShowing && $.tm_datepicker._lastInput === input[ 0 ] ) { 322 $.tm_datepicker._hideDatepicker(); 323 } else if ( $.tm_datepicker._datepickerShowing && $.tm_datepicker._lastInput !== input[ 0 ] ) { 324 $.tm_datepicker._hideDatepicker(); 325 $.tm_datepicker._showDatepicker( input[ 0 ] ); 326 } else { 327 $.tm_datepicker._showDatepicker( input[ 0 ] ); 328 } 329 return false; 330 } ); 331 } 332 }, 333 334 /* Apply the maximum length for the date format. */ 335 _autoSize: function( inst ) { 336 var findMax; 337 var max; 338 var maxI; 339 var i; 340 var date; 341 var dateFormat = this._get( inst, 'dateFormat' ); 342 343 if ( this._get( inst, 'autoSize' ) && ! inst.inline ) { 344 date = new Date( 2009, 12 - 1, 20 ); // Ensure double digits 345 dateFormat = this._get( inst, 'dateFormat' ); 346 347 if ( dateFormat.match( /[DM]/ ) ) { 348 findMax = function( names ) { 349 max = 0; 350 maxI = 0; 351 for ( i = 0; i < names.length; i += 1 ) { 352 if ( names[ i ].length > max ) { 353 max = names[ i ].length; 354 maxI = i; 355 } 356 } 357 return maxI; 358 }; 359 date.setMonth( findMax( this._get( inst, dateFormat.match( /MM/ ) ? 'monthNames' : 'monthNamesShort' ) ) ); 360 date.setDate( findMax( this._get( inst, dateFormat.match( /DD/ ) ? 'dayNames' : 'dayNamesShort' ) ) + 20 - date.getDay() ); 361 } 362 inst.input.attr( 'size', this._formatDate( inst, date ).length ); 363 } 364 }, 365 366 /* Attach an inline date picker to a div. */ 367 _inlineDatepicker: function( target, inst ) { 368 var divSpan = $( target ); 369 if ( divSpan.hasClass( this.markerClassName ) ) { 370 return; 371 } 372 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 373 $.data( target, 'datepicker', inst ); 374 this._setDate( inst, this._getDefaultDate( inst ), true ); 375 this._updateDatepicker( inst ); 376 this._updateAlternate( inst ); 377 378 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 379 if ( inst.settings.disabled ) { 380 this._disableDatepicker( target ); 381 } 382
vendor: 3,023 bytes, lines 383-459
383 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 384 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 385 inst.dpDiv.css( 'display', 'block' ); 386 }, 387 388 /* Pop-up the date picker in a "dialog" box. 389 * @param input element - ignored 390 * @param date string or Date - the initial date to display 391 * @param onSelect function - the function to call when a date is selected 392 * @param settings object - update the dialog date picker instance's settings (anonymous object) 393 * @param pos int[2] - coordinates for the dialog's position within the screen or 394 * event - with x/y coordinates or 395 * leave empty for default (screen centre) 396 * @return the manager object 397 */ 398 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 399 var id, 400 browserWidth, 401 browserHeight, 402 scrollX, 403 scrollY, 404 inst = this._dialogInst; // internal instance 405 406 if ( ! inst ) { 407 this.uuid += 1; 408 id = 'dp' + this.uuid; 409 this._dialogInput = $( "<input type='text' id='" + id + "'>" ); 410 this._dialogInput.on( 'keydown', this._doKeyDown ); 411 $( 'body' ).append( this._dialogInput ); 412 inst = this._newInst( this._dialogInput, false ); 413 this._dialogInst = inst; 414 inst.settings = {}; 415 $.data( this._dialogInput[ 0 ], 'datepicker', inst ); 416 } 417 datepicker_extendRemove( inst.settings, settings || {} ); 418 date = date && date.constructor === Date ? this._formatDate( inst, date ) : date; 419 this._dialogInput.val( date ); 420 421 this._pos = pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null; 422 if ( ! this._pos ) { 423 browserWidth = document.documentElement.clientWidth; 424 browserHeight = document.documentElement.clientHeight; 425 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 426 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 427 this._pos = 428 // should use actual width/height below 429 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 430 } 431 432 // Move input on screen for focus, but hidden behind dialog 433 this._dialogInput.css( 'left', this._pos[ 0 ] + 20 + 'px' ).css( 'top', this._pos[ 1 ] + 'px' ); 434 inst.settings.onSelect = onSelect; 435 this._inDialog = true; 436 this.dpDiv.addClass( this._dialogClass ); 437 this._showDatepicker( this._dialogInput[ 0 ] ); 438 if ( $.blockUI ) { 439 $.blockUI( this.dpDiv ); 440 } 441 $.data( this._dialogInput[ 0 ], 'datepicker', inst ); 442 return this; 443 }, 444 445 /* Detach a datepicker from its control. 446 * @param target element - the target input field or division or span 447 */ 448 _destroyDatepicker: function( target ) { 449 var nodeName, 450 $target = $( target ), 451 inst = $.data( target, 'datepicker' ); 452 453 if ( ! $target.hasClass( this.markerClassName ) ) { 454 return; 455 } 456 457 nodeName = target.nodeName.toLowerCase(); 458 $.removeData( target, 'datepicker' ); 459 if ( nodeName === 'input' ) {
vendor: 7,441 bytes, lines 460-684
460 inst.append.remove(); 461 inst.trigger.remove(); 462 $target.removeClass( this.markerClassName ).off( 'focus', this._showDatepicker ).off( 'keydown', this._doKeyDown ).off( 'keypress', this._doKeyPress ).off( 'keyup', this._doKeyUp ); 463 } else if ( nodeName === 'div' || nodeName === 'span' ) { 464 $target.removeClass( this.markerClassName ).empty(); 465 } 466 467 if ( datepicker_instActive === inst ) { 468 datepicker_instActive = null; 469 } 470 }, 471 472 /* Enable the date picker to a jQuery selection. 473 * @param target element - the target input field or division or span 474 */ 475 _enableDatepicker: function( target ) { 476 var nodeName, 477 inline, 478 $target = $( target ), 479 inst = $.data( target, 'datepicker' ); 480 481 if ( ! $target.hasClass( this.markerClassName ) ) { 482 return; 483 } 484 485 nodeName = target.nodeName.toLowerCase(); 486 if ( nodeName === 'input' ) { 487 target.disabled = false; 488 inst.trigger 489 .filter( 'button' ) 490 .each( function() { 491 this.disabled = false; 492 } ) 493 .end() 494 .filter( 'img' ) 495 .css( { opacity: '1.0', cursor: '' } ); 496 } else if ( nodeName === 'div' || nodeName === 'span' ) { 497 inline = $target.children( '.' + this._inlineClass ); 498 inline.children().removeClass( 'ui-state-disabled' ); 499 inline.find( 'select.ui-tm-datepicker-month, select.ui-tm-datepicker-year' ).prop( 'disabled', false ); 500 } 501 this._disabledInputs = $.map( this._disabledInputs, function( value ) { 502 return value === target ? null : value; 503 } ); // delete entry 504 }, 505 506 /* Disable the date picker to a jQuery selection. 507 * @param target element - the target input field or division or span 508 */ 509 _disableDatepicker: function( target ) { 510 var nodeName, 511 inline, 512 $target = $( target ), 513 inst = $.data( target, 'datepicker' ); 514 515 if ( ! $target.hasClass( this.markerClassName ) ) { 516 return; 517 } 518 519 nodeName = target.nodeName.toLowerCase(); 520 if ( nodeName === 'input' ) { 521 target.disabled = true; 522 inst.trigger 523 .filter( 'button' ) 524 .each( function() { 525 this.disabled = true; 526 } ) 527 .end() 528 .filter( 'img' ) 529 .css( { opacity: '0.5', cursor: 'default' } ); 530 } else if ( nodeName === 'div' || nodeName === 'span' ) { 531 inline = $target.children( '.' + this._inlineClass ); 532 inline.children().addClass( 'ui-state-disabled' ); 533 inline.find( 'select.ui-tm-datepicker-month, select.ui-tm-datepicker-year' ).prop( 'disabled', true ); 534 } 535 this._disabledInputs = $.map( this._disabledInputs, function( value ) { 536 return value === target ? null : value; 537 } ); // delete entry 538 this._disabledInputs[ this._disabledInputs.length ] = target; 539 }, 540 541 /* Is the first field in a jQuery collection disabled as a datepicker? 542 * @param target element - the target input field or division or span 543 * @return boolean - true if disabled, false if enabled 544 */ 545 _isDisabledDatepicker: function( target ) { 546 var i; 547 if ( ! target ) { 548 return false; 549 } 550 for ( i = 0; i < this._disabledInputs.length; i += 1 ) { 551 if ( this._disabledInputs[ i ] === target ) { 552 return true; 553 } 554 } 555 return false; 556 }, 557 558 /* Retrieve the instance data for the target control. 559 * @param target element - the target input field or division or span 560 * @return object - the associated instance data 561 * @throws error if a jQuery problem getting data 562 */ 563 _getInst: function( target ) { 564 try { 565 return $.data( target, 'datepicker' ); 566 } catch ( err ) { 567 throw 'Missing instance data for this datepicker'; 568 } 569 }, 570 571 /* Update or retrieve the settings for a date picker attached to an input field or division. 572 * @param target element - the target input field or division or span 573 * @param name object - the new settings to update or 574 * string - the name of the setting to change or retrieve, 575 * when retrieving also "all" for all instance settings or 576 * "defaults" for all global defaults 577 * @param value any - the new value for the setting 578 * (omit if above is an object or to retrieve a value) 579 */ 580 _optionDatepicker: function( target, name, value ) { 581 var settings, 582 date, 583 minDate, 584 maxDate, 585 inst = this._getInst( target ); 586 587 if ( arguments.length === 2 && typeof name === 'string' ) { 588 return name === 'defaults' ? $.extend( {}, $.tm_datepicker._defaults ) : inst ? ( name === 'all' ? $.extend( {}, inst.settings ) : this._get( inst, name ) ) : null; 589 } 590 591 settings = name || {}; 592 if ( typeof name === 'string' ) { 593 settings = {}; 594 settings[ name ] = value; 595 } 596 597 if ( inst ) { 598 if ( this._curInst === inst ) { 599 this._hideDatepicker(); 600 } 601 602 date = this._getDateDatepicker( target, true ); 603 minDate = this._getMinMaxDate( inst, 'min' ); 604 maxDate = this._getMinMaxDate( inst, 'max' ); 605 datepicker_extendRemove( inst.settings, settings ); 606 607 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 608 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 609 inst.settings.minDate = this._formatDate( inst, minDate ); 610 } 611 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 612 inst.settings.maxDate = this._formatDate( inst, maxDate ); 613 } 614 if ( 'disabled' in settings ) { 615 if ( settings.disabled ) { 616 this._disableDatepicker( target ); 617 } else { 618 this._enableDatepicker( target ); 619 } 620 } 621 this._attachments( $( target ), inst ); 622 this._autoSize( inst ); 623 this._setDate( inst, date ); 624 this._updateAlternate( inst ); 625 this._updateDatepicker( inst ); 626 } 627 }, 628 629 // Change method deprecated 630 _changeDatepicker: function( target, name, value ) { 631 this._optionDatepicker( target, name, value ); 632 }, 633 634 /* Redraw the date picker attached to an input field or division. 635 * @param target element - the target input field or division or span 636 */ 637 _refreshDatepicker: function( target ) { 638 var inst = this._getInst( target ); 639 if ( inst ) { 640 this._updateDatepicker( inst ); 641 } 642 }, 643 644 /* Set the dates for a jQuery selection. 645 * @param target element - the target input field or division or span 646 * @param date Date - the new date 647 */ 648 _setDateDatepicker: function( target, date ) { 649 var inst = this._getInst( target ); 650 if ( inst ) { 651 this._setDate( inst, date ); 652 this._updateDatepicker( inst ); 653 this._updateAlternate( inst ); 654 } 655 }, 656 657 /* Get the date(s) for the first entry in a jQuery selection. 658 * @param target element - the target input field or division or span 659 * @param noDefault boolean - true if no default date is to be used 660 * @return Date - the current date 661 */ 662 _getDateDatepicker: function( target, noDefault ) { 663 var inst = this._getInst( target ); 664 if ( inst && ! inst.inline ) { 665 this._setDateFromField( inst, noDefault ); 666 } 667 return inst ? this._getDate( inst ) : null; 668 }, 669 670 /* Handle keystrokes. */ 671 _doKeyDown: function( event ) { 672 var onSelect, 673 dateStr, 674 sel, 675 inst = $.tm_datepicker._getInst( event.target ), 676 handled = true, 677 isRTL = inst.dpDiv.is( '.ui-tm-datepicker-rtl' ); 678 679 inst._keyEvent = true; 680 if ( $.tm_datepicker._datepickerShowing ) { 681 switch ( event.keyCode ) { 682 case 9: 683 $.tm_datepicker._hideDatepicker(); 684 handled = false;
vendor: 4,548 bytes, lines 685-803
685 break; // hide on tab out 686 case 13: 687 sel = $( 'td.' + $.tm_datepicker._dayOverClass + ':not(.' + $.tm_datepicker._currentClass + ')', inst.dpDiv ); 688 if ( sel[ 0 ] ) { 689 $.tm_datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 690 } 691 692 onSelect = $.tm_datepicker._get( inst, 'onSelect' ); 693 if ( onSelect ) { 694 dateStr = $.tm_datepicker._formatDate( inst ); 695 696 // Trigger custom callback 697 onSelect.apply( inst.input ? inst.input[ 0 ] : null, [ dateStr, inst ] ); 698 } else { 699 $.tm_datepicker._hideDatepicker(); 700 } 701 702 return false; // don't submit the form 703 case 27: 704 $.tm_datepicker._hideDatepicker(); 705 break; // hide on escape 706 case 33: 707 $.tm_datepicker._adjustDate( event.target, event.ctrlKey ? -$.tm_datepicker._get( inst, 'stepBigMonths' ) : -$.tm_datepicker._get( inst, 'stepMonths' ), 'M' ); 708 break; // previous month/year on page up/+ ctrl 709 case 34: 710 $.tm_datepicker._adjustDate( event.target, event.ctrlKey ? +$.tm_datepicker._get( inst, 'stepBigMonths' ) : +$.tm_datepicker._get( inst, 'stepMonths' ), 'M' ); 711 break; // next month/year on page down/+ ctrl 712 case 35: 713 if ( event.ctrlKey || event.metaKey ) { 714 $.tm_datepicker._clearDate( event.target ); 715 } 716 handled = event.ctrlKey || event.metaKey; 717 break; // clear on ctrl or command +end 718 case 36: 719 if ( event.ctrlKey || event.metaKey ) { 720 $.tm_datepicker._gotoToday( event.target ); 721 } 722 handled = event.ctrlKey || event.metaKey; 723 break; // current on ctrl or command +home 724 case 37: 725 if ( event.ctrlKey || event.metaKey ) { 726 $.tm_datepicker._adjustDate( event.target, isRTL ? +1 : -1, 'D' ); 727 } 728 handled = event.ctrlKey || event.metaKey; 729 // -1 day on ctrl or command +left 730 if ( event.originalEvent.altKey ) { 731 $.tm_datepicker._adjustDate( event.target, event.ctrlKey ? -$.tm_datepicker._get( inst, 'stepBigMonths' ) : -$.tm_datepicker._get( inst, 'stepMonths' ), 'M' ); 732 } 733 // next month/year on alt +left on Mac 734 break; 735 case 38: 736 if ( event.ctrlKey || event.metaKey ) { 737 $.tm_datepicker._adjustDate( event.target, -7, 'D' ); 738 } 739 handled = event.ctrlKey || event.metaKey; 740 break; // -1 week on ctrl or command +up 741 case 39: 742 if ( event.ctrlKey || event.metaKey ) { 743 $.tm_datepicker._adjustDate( event.target, isRTL ? -1 : +1, 'D' ); 744 } 745 handled = event.ctrlKey || event.metaKey; 746 // +1 day on ctrl or command +right 747 if ( event.originalEvent.altKey ) { 748 $.tm_datepicker._adjustDate( event.target, event.ctrlKey ? +$.tm_datepicker._get( inst, 'stepBigMonths' ) : +$.tm_datepicker._get( inst, 'stepMonths' ), 'M' ); 749 } 750 // next month/year on alt +right 751 break; 752 case 40: 753 if ( event.ctrlKey || event.metaKey ) { 754 $.tm_datepicker._adjustDate( event.target, +7, 'D' ); 755 } 756 handled = event.ctrlKey || event.metaKey; 757 break; // +1 week on ctrl or command +down 758 default: 759 handled = false; 760 } 761 } else if ( event.keyCode === 36 && event.ctrlKey ) { 762 // display the date picker on ctrl+home 763 $.tm_datepicker._showDatepicker( this ); 764 } else { 765 handled = false; 766 } 767 768 if ( handled ) { 769 event.preventDefault(); 770 event.stopPropagation(); 771 } 772 }, 773 774 /* Filter entered characters - based on date format. */ 775 _doKeyPress: function( event ) { 776 var chars, 777 chr, 778 inst = $.tm_datepicker._getInst( event.target ); 779 780 if ( $.tm_datepicker._get( inst, 'constrainInput' ) ) { 781 chars = $.tm_datepicker._possibleChars( $.tm_datepicker._get( inst, 'dateFormat' ) ); 782 chr = String.fromCharCode( event.charCode === null ? event.keyCode : event.charCode ); 783 return event.ctrlKey || event.metaKey || chr < ' ' || ! chars || chars.indexOf( chr ) > -1; 784 } 785 }, 786 787 /* Synchronise manual entry and field/alternate field. */ 788 _doKeyUp: function( event ) { 789 var date, 790 inst = $.tm_datepicker._getInst( event.target ); 791 792 if ( inst.input.val() !== inst.lastVal ) { 793 try { 794 date = $.tm_datepicker.parseDate( $.tm_datepicker._get( inst, 'dateFormat' ), inst.input ? inst.input.val() : null, $.tm_datepicker._getFormatConfig( inst ) ); 795 796 if ( date ) { 797 // only if valid 798 $.tm_datepicker._setDateFromField( inst ); 799 $.tm_datepicker._updateAlternate( inst ); 800 $.tm_datepicker._updateDatepicker( inst ); 801 } 802 } catch ( err ) { 803 return false;
vendor: 14,218 bytes, lines 804-1219
804 } 805 } 806 return true; 807 }, 808 809 /* Pop-up the date picker for a given input field. 810 * If false returned from beforeShow event handler do not show. 811 * @param input element - the input field attached to the date picker or 812 * event - if triggered by focus 813 */ 814 _showDatepicker: function( input ) { 815 var inst; 816 var beforeShow; 817 var beforeShowSettings; 818 var isFixed; 819 var offset; 820 var showAnim; 821 var duration; 822 823 input = input.target || input; 824 if ( input.nodeName.toLowerCase() !== 'input' ) { 825 // find from button/image trigger 826 input = $( 'input', input.parentNode )[ 0 ]; 827 } 828 829 if ( $.tm_datepicker._isDisabledDatepicker( input ) || $.tm_datepicker._lastInput === input ) { 830 // already here 831 return; 832 } 833 834 inst = $.tm_datepicker._getInst( input ); 835 if ( $.tm_datepicker._curInst && $.tm_datepicker._curInst !== inst ) { 836 $.tm_datepicker._curInst.dpDiv.stop( true, true ); 837 if ( inst && $.tm_datepicker._datepickerShowing ) { 838 $.tm_datepicker._hideDatepicker( $.tm_datepicker._curInst.input[ 0 ] ); 839 } 840 } 841 842 beforeShow = $.tm_datepicker._get( inst, 'beforeShow' ); 843 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 844 if ( beforeShowSettings === false ) { 845 return; 846 } 847 datepicker_extendRemove( inst.settings, beforeShowSettings ); 848 849 inst.lastVal = null; 850 $.tm_datepicker._lastInput = input; 851 $.tm_datepicker._setDateFromField( inst ); 852 853 if ( $.tm_datepicker._inDialog ) { 854 // hide cursor 855 input.value = ''; 856 } 857 if ( ! $.tm_datepicker._pos ) { 858 // position below input 859 $.tm_datepicker._pos = $.tm_datepicker._findPos( input ); 860 $.tm_datepicker._pos[ 1 ] += input.offsetHeight; // add the height 861 } 862 863 isFixed = false; 864 $( input ) 865 .parents() 866 .each( function() { 867 isFixed = isFixed || $( this ).css( 'position' ) === 'fixed'; 868 return ! isFixed; 869 } ); 870 871 offset = { left: $.tm_datepicker._pos[ 0 ], top: $.tm_datepicker._pos[ 1 ] }; 872 $.tm_datepicker._pos = null; 873 //to avoid flashes on Firefox 874 inst.dpDiv.empty(); 875 // determine sizing offscreen 876 inst.dpDiv.css( { position: 'absolute', display: 'block', top: '-1000px' } ); 877 $.tm_datepicker._updateDatepicker( inst ); 878 // fix width for dynamic number of date pickers 879 // and adjust position before showing 880 offset = $.tm_datepicker._checkOffset( inst, offset, isFixed ); 881 inst.dpDiv.css( { 882 position: $.tm_datepicker._inDialog && $.blockUI ? 'static' : isFixed ? 'fixed' : 'absolute', 883 display: 'none', 884 left: offset.left + 'px', 885 top: offset.top + 'px' 886 } ); 887 888 if ( ! inst.inline ) { 889 showAnim = $.tm_datepicker._get( inst, 'showAnim' ); 890 duration = $.tm_datepicker._get( inst, 'duration' ); 891 inst.dpDiv.css( 'z-index', datepicker_getZindex( $( input ) ) + 1 ); 892 $.tm_datepicker._datepickerShowing = true; 893 894 if ( $.effects && $.effects.effect[ showAnim ] ) { 895 inst.dpDiv.show( showAnim, $.tm_datepicker._get( inst, 'showOptions' ), duration ); 896 } else { 897 inst.dpDiv[ showAnim || 'show' ]( showAnim ? duration : null ); 898 } 899 900 if ( $.tm_datepicker._shouldFocusInput( inst ) ) { 901 inst.input.trigger( 'focus' ); 902 } 903 904 $.tm_datepicker._curInst = inst; 905 } 906 }, 907 908 /* Generate the date picker content. */ 909 _updateDatepicker: function( inst ) { 910 var origyearshtml; 911 var numMonths; 912 var cols; 913 var width = 17; 914 var activeCell; 915 916 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 917 datepicker_instActive = inst; // for delegate hover events 918 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 919 this._attachHandlers( inst ); 920 921 numMonths = this._getNumberOfMonths( inst ); 922 cols = numMonths[ 1 ]; 923 activeCell = inst.dpDiv.find( '.' + this._dayOverClass + ' a' ); 924 925 if ( activeCell.length > 0 ) { 926 datepicker_handleMouseover.apply( activeCell.get( 0 ), [ activeCell.get( 0 ) ] ); 927 } 928 929 inst.dpDiv.removeClass( 'ui-tm-datepicker-multi-2 ui-tm-datepicker-multi-3 ui-tm-datepicker-multi-4' ).width( '' ); 930 if ( cols > 1 ) { 931 inst.dpDiv.addClass( 'ui-tm-datepicker-multi-' + cols ).css( 'width', ( width * cols ) + 'em' ); 932 } 933 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? 'add' : 'remove' ) + 'Class' ]( 'ui-tm-datepicker-multi' ); 934 inst.dpDiv[ ( this._get( inst, 'isRTL' ) ? 'add' : 'remove' ) + 'Class' ]( 'ui-tm-datepicker-rtl' ); 935 936 if ( inst === $.tm_datepicker._curInst && $.tm_datepicker._datepickerShowing && $.tm_datepicker._shouldFocusInput( inst ) ) { 937 inst.input.trigger( 'focus' ); 938 } 939 940 // deffered render of the years select (to avoid flashes on Firefox) 941 if ( inst.yearshtml ) { 942 origyearshtml = inst.yearshtml; 943 setTimeout( function() { 944 //assure that inst.yearshtml didn't change. 945 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 946 inst.dpDiv.find( 'select.ui-tm-datepicker-year:first' ).replaceWith( inst.yearshtml ); 947 } 948 origyearshtml = null; 949 inst.yearshtml = null; 950 }, 0 ); 951 } 952 }, 953 954 // #6694 - don't focus the input if it's already focused 955 // this breaks the change event in IE 956 // Support: IE and jQuery <1.9 957 _shouldFocusInput: function( inst ) { 958 return inst.input && inst.input.is( ':visible' ) && ! inst.input.is( ':disabled' ) && ! inst.input.is( ':focus' ); 959 }, 960 961 /* Check positioning to remain on screen. */ 962 _checkOffset: function( inst, offset, isFixed ) { 963 var dpWidth = inst.dpDiv.outerWidth(), 964 dpHeight = inst.dpDiv.outerHeight(), 965 inputWidth = inst.input ? inst.input.outerWidth() : 0, 966 inputHeight = inst.input ? inst.input.outerHeight() : 0, 967 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 968 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 969 970 offset.left -= this._get( inst, 'isRTL' ) ? dpWidth - inputWidth : 0; 971 offset.left -= isFixed && offset.left === inst.input.offset().left ? $( document ).scrollLeft() : 0; 972 offset.top -= isFixed && offset.top === inst.input.offset().top + inputHeight ? $( document ).scrollTop() : 0; 973 974 // Now check if datepicker is showing outside window viewport - move to a better place if so. 975 offset.left -= Math.min( offset.left, offset.left + dpWidth > viewWidth && viewWidth > dpWidth ? Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 976 offset.top -= Math.min( offset.top, offset.top + dpHeight > viewHeight && viewHeight > dpHeight ? Math.abs( dpHeight + inputHeight ) : 0 ); 977 978 return offset; 979 }, 980 981 /* Find an object's position on the screen. */ 982 _findPos: function( obj ) { 983 var position, 984 inst = this._getInst( obj ), 985 isRTL = this._get( inst, 'isRTL' ); 986 987 while ( obj && ( obj.type === 'hidden' || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 988 obj = obj[ isRTL ? 'previousSibling' : 'nextSibling' ]; 989 } 990 991 position = $( obj ).offset(); 992 return [ position.left, position.top ]; 993 }, 994 995 /* Hide the date picker from view. 996 * @param input element - the input field attached to the date picker 997 */ 998 _hideDatepicker: function( input ) { 999 var showAnim, 1000 duration, 1001 postProcess, 1002 onClose, 1003 inst = this._curInst; 1004 1005 if ( ! inst || ( input && inst !== $.data( input, 'datepicker' ) ) ) { 1006 return; 1007 } 1008 1009 if ( this._datepickerShowing ) { 1010 showAnim = this._get( inst, 'showAnim' ); 1011 duration = this._get( inst, 'duration' ); 1012 postProcess = function() { 1013 $.tm_datepicker._tidyDialog( inst ); 1014 }; 1015 1016 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 1017 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 1018 inst.dpDiv.hide( showAnim, $.tm_datepicker._get( inst, 'showOptions' ), duration, postProcess ); 1019 } else { 1020 inst.dpDiv[ showAnim === 'slideDown' ? 'slideUp' : showAnim === 'fadeIn' ? 'fadeOut' : 'hide' ]( showAnim ? duration : null, postProcess ); 1021 } 1022 1023 if ( ! showAnim ) { 1024 postProcess(); 1025 } 1026 this._datepickerShowing = false; 1027 1028 onClose = this._get( inst, 'onClose' ); 1029 if ( onClose ) { 1030 onClose.apply( inst.input ? inst.input[ 0 ] : null, [ inst.input ? inst.input.val() : '', inst ] ); 1031 } 1032 1033 this._lastInput = null; 1034 if ( this._inDialog ) { 1035 this._dialogInput.css( { position: 'absolute', left: '0', top: '-100px' } ); 1036 if ( $.blockUI ) { 1037 $.unblockUI(); 1038 $( 'body' ).append( this.dpDiv ); 1039 } 1040 } 1041 this._inDialog = false; 1042 } 1043 }, 1044 1045 /* Tidy up after a dialog display. */ 1046 _tidyDialog: function( inst ) { 1047 inst.dpDiv.removeClass( this._dialogClass ).off( '.ui-tm-datepicker-calendar' ); 1048 }, 1049 1050 /* Close date picker if clicked elsewhere. */ 1051 _checkExternalClick: function( event ) { 1052 var $target; 1053 var inst; 1054 1055 if ( ! $.tm_datepicker._curInst ) { 1056 return; 1057 } 1058 1059 $target = $( event.target ); 1060 inst = $.tm_datepicker._getInst( $target[ 0 ] ); 1061 1062 if ( ( $target[ 0 ].id !== $.tm_datepicker._mainDivId && $target.parents( '#' + $.tm_datepicker._mainDivId ).length === 0 && ! $target.hasClass( $.tm_datepicker.markerClassName ) && ! $target.closest( '.' + $.tm_datepicker._triggerClass ).length && $.tm_datepicker._datepickerShowing && ! ( $.tm_datepicker._inDialog && $.blockUI ) ) || ( $target.hasClass( $.tm_datepicker.markerClassName ) && $.tm_datepicker._curInst !== inst ) ) { 1063 $.tm_datepicker._hideDatepicker(); 1064 } 1065 }, 1066 1067 /* Adjust one of the date sub-fields. */ 1068 _adjustDate: function( id, offset, period ) { 1069 var target = $( id ), 1070 inst = this._getInst( target[ 0 ] ); 1071 1072 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 1073 return; 1074 } 1075 this._adjustInstDate( 1076 inst, 1077 offset + ( period === 'M' ? this._get( inst, 'showCurrentAtPos' ) : 0 ), // undo positioning 1078 period 1079 ); 1080 this._updateDatepicker( inst ); 1081 }, 1082 1083 /* Action for current link. */ 1084 _gotoToday: function( id ) { 1085 var date, 1086 target = $( id ), 1087 inst = this._getInst( target[ 0 ] ); 1088 1089 if ( this._get( inst, 'gotoCurrent' ) && inst.currentDay ) { 1090 inst.selectedDay = inst.currentDay; 1091 inst.drawMonth = inst.currentMonth; 1092 inst.selectedMonth = inst.currentMonth; 1093 inst.drawYear = inst.currentYear; 1094 inst.selectedYear = inst.currentYear; 1095 } else { 1096 date = new Date(); 1097 inst.selectedDay = date.getDate(); 1098 inst.drawMonth = date.getMonth(); 1099 inst.selectedMonth = inst.drawMonth; 1100 inst.drawYear = date.getFullYear(); 1101 inst.selectedYear = inst.drawYear; 1102 } 1103 this._notifyChange( inst ); 1104 this._adjustDate( target ); 1105 }, 1106 1107 /* Action for selecting a new month/year. */ 1108 _selectMonthYear: function( id, select, period ) { 1109 var target = $( id ), 1110 inst = this._getInst( target[ 0 ] ); 1111 1112 inst[ 'selected' + ( period === 'M' ? 'Month' : 'Year' ) ] = parseInt( select.options[ select.selectedIndex ].value, 10 ); 1113 inst[ 'draw' + ( period === 'M' ? 'Month' : 'Year' ) ] = parseInt( select.options[ select.selectedIndex ].value, 10 ); 1114 1115 this._notifyChange( inst ); 1116 this._adjustDate( target ); 1117 }, 1118 1119 /* Action for selecting a day. */ 1120 _selectDay: function( id, month, year, td ) { 1121 var inst, 1122 target = $( id ); 1123 1124 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 1125 return; 1126 } 1127 1128 inst = this._getInst( target[ 0 ] ); 1129 inst.selectedDay = $( 'a', td ).html(); 1130 inst.currentDay = inst.selectedDay; 1131 inst.selectedMonth = month; 1132 inst.currentMonth = month; 1133 inst.selectedYear = year; 1134 inst.currentYear = year; 1135 this._selectDate( id, this._formatDate( inst, inst.currentDay, inst.currentMonth, inst.currentYear ) ); 1136 }, 1137 1138 /* Erase the input field and hide the date picker. */ 1139 _clearDate: function( id ) { 1140 var target = $( id ); 1141 this._selectDate( target, '' ); 1142 }, 1143 1144 /* Update the input field with the selected date. */ 1145 _selectDate: function( id, dateStr ) { 1146 var onSelect, 1147 target = $( id ), 1148 inst = this._getInst( target[ 0 ] ); 1149 1150 dateStr = dateStr !== null ? dateStr : this._formatDate( inst ); 1151 if ( inst.input ) { 1152 inst.input.val( dateStr ); 1153 } 1154 this._updateAlternate( inst ); 1155 1156 onSelect = this._get( inst, 'onSelect' ); 1157 if ( onSelect ) { 1158 onSelect.apply( inst.input ? inst.input[ 0 ] : null, [ dateStr, inst ] ); // trigger custom callback 1159 } else if ( inst.input ) { 1160 inst.input.trigger( 'change' ); // fire the change event 1161 } 1162 1163 if ( inst.inline ) { 1164 this._updateDatepicker( inst ); 1165 } else { 1166 this._hideDatepicker(); 1167 this._lastInput = inst.input[ 0 ]; 1168 if ( typeof inst.input[ 0 ] !== 'object' ) { 1169 inst.input.trigger( 'focus' ); // restore focus 1170 } 1171 this._lastInput = null; 1172 } 1173 }, 1174 1175 /* Update any alternate field to synchronise with the main field. */ 1176 _updateAlternate: function( inst ) { 1177 var altFormat, 1178 date, 1179 dateStr, 1180 altField = this._get( inst, 'altField' ); 1181 1182 if ( altField ) { 1183 // update alternate field too 1184 altFormat = this._get( inst, 'altFormat' ) || this._get( inst, 'dateFormat' ); 1185 date = this._getDate( inst ); 1186 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 1187 $( altField ).val( dateStr ); 1188 } 1189 }, 1190 1191 /* Set as beforeShowDay function to prevent selection of weekends. 1192 * @param date Date - the date to customise 1193 * @return [boolean, string] - is this date selectable?, what is its CSS class? 1194 */ 1195 noWeekends: function( date ) { 1196 var day = date.getDay(); 1197 return [ day > 0 && day < 6, '' ]; 1198 }, 1199 1200 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 1201 * @param date Date - the date to get the week for 1202 * @return number - the number of the week within the year that contains this date 1203 */ 1204 iso8601Week: function( date ) { 1205 var time, 1206 checkDate = new Date( date.getTime() ); 1207 1208 // Find Thursday of this week starting on Monday 1209 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 1210 1211 time = checkDate.getTime(); 1212 checkDate.setMonth( 0 ); // Compare with Jan 1 1213 checkDate.setDate( 1 ); 1214 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 1215 }, 1216 1217 /* Parse a string value into a date object. 1218 * See formatDate below for the possible formats. 1219 *
1220 * @param format string - the expected format of the date 1221 * @param value string - the date in the above format 1222 * @param settings Object - attributes include: 1223 * shortYearCutoff number - the cutoff year for determining the century (optional) 1224 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 1225 * dayNames string[7] - names of the days from Sunday (optional) 1226 * monthNamesShort string[12] - abbreviated names of the months (optional) 1227 * monthNames string[12] - names of the months (optional) 1228 * @return Date - the extracted date value or null if value is blank 1229 */ 1230 parseDate: function( format, value, settings ) { 1231 var iFormat; 1232 var dim; 1233 var extra; 1234 var iValue = 0; 1235 var shortYearCutoffTemp; 1236 var shortYearCutoff; 1237 var dayNamesShort; 1238 var dayNames; 1239 var monthNamesShort; 1240 var monthNames; 1241 var year = -1; 1242 var month = -1; 1243 var day = -1; 1244 var doy = -1; 1245 var literal = false; 1246 var date; 1247 var lookAhead; 1248 var getNumber; 1249 var getName; 1250 var checkLiteral; 1251 var condition; 1252 1253 if ( format === null || value === null ) { 1254 throw 'Invalid arguments'; 1255 } 1256 1257 value = typeof value === 'object' ? value.toString() : value + ''; 1258 if ( value === '' ) { 1259 return null; 1260 } 1261 1262 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff; 1263 shortYearCutoff = typeof shortYearCutoffTemp !== 'string' ? shortYearCutoffTemp : ( new Date().getFullYear() % 100 ) + parseInt( shortYearCutoffTemp, 10 ); 1264 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort; 1265 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames; 1266 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort; 1267 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames; 1268 1269 // Check whether a format character is doubled 1270 lookAhead = function( match ) { 1271 var matches = iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match; 1272 if ( matches ) { 1273 iFormat = iFormat + 1; 1274 } 1275 return matches; 1276 }; 1277 1278 // Extract a number from the string value 1279 getNumber = function( match ) { 1280 var isDoubled = lookAhead( match ), 1281 size = match === '@' ? 14 : match === '!' ? 20 : match === 'y' && isDoubled ? 4 : match === 'o' ? 3 : 2, 1282 minSize = match === 'y' ? size : 1, 1283 digits = new RegExp( '^\\d{' + minSize + ',' + size + '}' ), 1284 num = value.substring( iValue ).match( digits ); 1285 if ( ! num ) { 1286 throw 'Missing number at position ' + iValue; 1287 } 1288 iValue += num[ 0 ].length; 1289 return parseInt( num[ 0 ], 10 ); 1290 }; 1291 1292 // Extract a name from the string value and convert to an index 1293 getName = function( match, shortNames, longNames ) { 1294 var index = -1, 1295 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 1296 return [ [ k, v ] ]; 1297 } ).sort( function( a, b ) { 1298 return -( a[ 1 ].length - b[ 1 ].length ); 1299 } ); 1300 1301 $.each( names, function( i, pair ) { 1302 var name = pair[ 1 ]; 1303 if ( value.substring( iValue, parseInt( iValue, 10 ) + name.length ).toLowerCase() === name.toLowerCase() ) { 1304 index = pair[ 0 ]; 1305 iValue += name.length; 1306 return false; 1307 } 1308 } ); 1309 if ( index !== -1 ) { 1310 return index + 1; 1311 } 1312 throw 'Unknown name at position ' + iValue; 1313 }; 1314 1315 // Confirm that a literal character matches the string value 1316 checkLiteral = function() { 1317 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 1318 throw 'Unexpected literal at position ' + iValue; 1319 } 1320 iValue = iValue + 1; 1321 }; 1322 1323 for ( iFormat = 0; iFormat < format.length; iFormat += 1 ) { 1324 if ( literal ) { 1325 if ( format.charAt( iFormat ) === "'" && ! lookAhead( "'" ) ) { 1326 literal = false; 1327 } else { 1328 checkLiteral(); 1329 } 1330 } else { 1331 switch ( format.charAt( iFormat ) ) { 1332 case 'd': 1333 day = getNumber( 'd' ); 1334 break; 1335 case 'D': 1336 getName( 'D', dayNamesShort, dayNames ); 1337 break; 1338 case 'o': 1339 doy = getNumber( 'o' ); 1340 break; 1341 case 'm':
1342 month = getNumber( 'm' ); 1343 break; 1344 case 'M': 1345 month = getName( 'M', monthNamesShort, monthNames ); 1346 break; 1347 case 'y': 1348 year = getNumber( 'y' ); 1349 break; 1350 case '@': 1351 date = new Date( getNumber( '@' ) ); 1352 year = date.getFullYear(); 1353 month = date.getMonth() + 1; 1354 day = date.getDate(); 1355 break; 1356 case '!': 1357 date = new Date( ( getNumber( '!' ) - this._ticksTo1970 ) / 10000 ); 1358 year = date.getFullYear(); 1359 month = date.getMonth() + 1; 1360 day = date.getDate(); 1361 break; 1362 case "'": 1363 if ( lookAhead( "'" ) ) { 1364 checkLiteral(); 1365 } else { 1366 literal = true; 1367 } 1368 break; 1369 default: 1370 checkLiteral(); 1371 } 1372 } 1373 } 1374 1375 if ( iValue < value.length ) { 1376 extra = value.substring( iValue ); 1377 if ( ! /^\s+/.test( extra ) ) { 1378 throw 'Extra/unparsed characters found in date: ' + extra; 1379 } 1380 } 1381 1382 if ( year === -1 ) { 1383 year = new Date().getFullYear(); 1384 } else if ( year < 100 ) { 1385 year += new Date().getFullYear() - ( new Date().getFullYear() % 100 ) + ( year <= shortYearCutoff ? 0 : -100 ); 1386 } 1387 1388 if ( doy > -1 ) { 1389 month = 1; 1390 day = doy; 1391 condition = true; 1392 do { 1393 dim = this._getDaysInMonth( year, month - 1 ); 1394 if ( day <= dim ) { 1395 condition = false; 1396 } else { 1397 month = month + 1; 1398 day -= dim; 1399 } 1400 } while ( condition ); 1401 } 1402 1403 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 1404 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 1405 throw 'Invalid date'; // E.g. 31/02/00 1406 } 1407 return date; 1408 }, 1409 1410 /* Standard date formats. */ 1411 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) 1412 COOKIE: 'D, dd M yy', 1413 ISO_8601: 'yy-mm-dd', 1414 RFC_822: 'D, d M y', 1415 RFC_850: 'DD, dd-M-y', 1416 RFC_1036: 'D, d M y', 1417 RFC_1123: 'D, d M yy', 1418 RFC_2822: 'D, d M yy', 1419 RSS: 'D, d M y', // RFC 822 1420 TICKS: '!', 1421 TIMESTAMP: '@', 1422 W3C: 'yy-mm-dd', // ISO 8601 1423 1424 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 ) + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000, 1425 1426 /* Format a date object into a string value. 1427 * The format can be combinations of the following: 1428 * d - day of month (no leading zero) 1429 * dd - day of month (two digit) 1430 * o - day of year (no leading zeros) 1431 * oo - day of year (three digit) 1432 * D - day name short 1433 * DD - day name long 1434 * m - month of year (no leading zero) 1435 * mm - month of year (two digit) 1436 * M - month name short 1437 * MM - month name long 1438 * y - year (two digit) 1439 * yy - year (four digit) 1440 * @ - Unix timestamp (ms since 01/01/1970) 1441 * ! - Windows ticks (100ns since 01/01/0001) 1442 * "..." - literal text 1443 * '' - single quote 1444 * 1445 * @param format string - the desired format of the date 1446 * @param date Date - the date value to format 1447 * @param settings Object - attributes include: 1448 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 1449 * dayNames string[7] - names of the days from Sunday (optional) 1450 * monthNamesShort string[12] - abbreviated names of the months (optional) 1451 * monthNames string[12] - names of the months (optional) 1452 * @return string - the date in the above format 1453 */ 1454 formatDate: function( format, date, settings ) { 1455 var iFormat, 1456 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 1457 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 1458 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 1459 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 1460 // Check whether a format character is doubled 1461 lookAhead = function( match ) { 1462 var matches = iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match; 1463 if ( matches ) { 1464 iFormat = iFormat + 1; 1465 } 1466 return matches; 1467 }, 1468 // Format a number, with leading zero if necessary 1469 formatNumber = function( match, value, len ) { 1470 var num = '' + value; 1471 if ( lookAhead( match ) ) { 1472 while ( num.length < len ) { 1473 num = '0' + num; 1474 } 1475 } 1476 return num; 1477 }, 1478 // Format a name, short or long as requested
1479 formatName = function( match, value, shortNames, longNames ) { 1480 return lookAhead( match ) ? longNames[ value ] : shortNames[ value ]; 1481 }, 1482 output = '', 1483 literal = false; 1484 1485 if ( ! date ) { 1486 return ''; 1487 } 1488 1489 if ( date ) { 1490 for ( iFormat = 0; iFormat < format.length; iFormat += 1 ) { 1491 if ( literal ) { 1492 if ( format.charAt( iFormat ) === "'" && ! lookAhead( "'" ) ) { 1493 literal = false; 1494 } else { 1495 output += format.charAt( iFormat ); 1496 } 1497 } else { 1498 switch ( format.charAt( iFormat ) ) { 1499 case 'd': 1500 output += formatNumber( 'd', date.getDate(), 2 ); 1501 break; 1502 case 'D': 1503 output += formatName( 'D', date.getDay(), dayNamesShort, dayNames ); 1504 break; 1505 case 'o': 1506 output += formatNumber( 'o', Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 1507 break; 1508 case 'm': 1509 output += formatNumber( 'm', date.getMonth() + 1, 2 ); 1510 break; 1511 case 'M': 1512 output += formatName( 'M', date.getMonth(), monthNamesShort, monthNames ); 1513 break; 1514 case 'y': 1515 output += lookAhead( 'y' ) ? date.getFullYear() : ( date.getFullYear() % 100 < 10 ? '0' : '' ) + ( date.getFullYear() % 100 ); 1516 break; 1517 case '@': 1518 output += date.getTime(); 1519 break; 1520 case '!': 1521 output += ( date.getTime() * 10000 ) + this._ticksTo1970; 1522 break; 1523 case "'": 1524 if ( lookAhead( "'" ) ) { 1525 output += "'"; 1526 } else { 1527 literal = true; 1528 } 1529 break; 1530 default: 1531 output += format.charAt( iFormat ); 1532 } 1533 } 1534 } 1535 } 1536 return output; 1537 }, 1538 1539 /* Extract all possible characters from the date format. */ 1540 _possibleChars: function( format ) { 1541 var iFormat, 1542 chars = '', 1543 literal = false, 1544 // Check whether a format character is doubled 1545 lookAhead = function( match ) { 1546 var matches = iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match; 1547 if ( matches ) { 1548 iFormat = iFormat + 1; 1549 } 1550 return matches; 1551 }; 1552 1553 for ( iFormat = 0; iFormat < format.length; iFormat += 1 ) { 1554 if ( literal ) { 1555 if ( format.charAt( iFormat ) === "'" && ! lookAhead( "'" ) ) { 1556 literal = false; 1557 } else { 1558 chars += format.charAt( iFormat ); 1559 } 1560 } else { 1561 switch ( format.charAt( iFormat ) ) { 1562 case 'd': 1563 case 'm': 1564 case 'y': 1565 case '@': 1566 chars += '0123456789'; 1567 break; 1568 case 'D': 1569 case 'M': 1570 return null; // Accept anything 1571 case "'": 1572 if ( lookAhead( "'" ) ) { 1573 chars += "'"; 1574 } else { 1575 literal = true; 1576 } 1577 break; 1578 default: 1579 chars += format.charAt( iFormat ); 1580 } 1581 } 1582 } 1583 return chars; 1584 }, 1585 1586 /* Get a setting value, defaulting if necessary. */ 1587 _get: function( inst, name ) { 1588 return inst.settings[ name ] !== undefined ? inst.settings[ name ] : this._defaults[ name ]; 1589 }, 1590 1591 /* Parse existing date and initialise date picker. */ 1592 _setDateFromField: function( inst, noDefault ) { 1593 var dateFormat; 1594 var dates; 1595 var defaultDate; 1596 var date; 1597 var settings; 1598 1599 if ( inst.input.val() === inst.lastVal ) { 1600 return; 1601 } 1602 1603 dateFormat = this._get( inst, 'dateFormat' ); 1604 dates = inst.input ? inst.input.val() : null; 1605 defaultDate = this._getDefaultDate( inst ); 1606 date = defaultDate; 1607 settings = this._getFormatConfig( inst ); 1608 1609 inst.lastVal = dates; 1610 1611 try { 1612 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 1613 } catch ( event ) { 1614 dates = noDefault ? '' : dates; 1615 } 1616 inst.selectedDay = date.getDate(); 1617 inst.selectedMonth = date.getMonth(); 1618 inst.drawMonth = inst.selectedMonth; 1619 inst.selectedYear = date.getFullYear(); 1620 inst.drawYear = inst.selectedYear; 1621 inst.currentDay = dates ? date.getDate() : 0; 1622 inst.currentMonth = dates ? date.getMonth() : 0; 1623 inst.currentYear = dates ? date.getFullYear() : 0; 1624 this._adjustInstDate( inst ); 1625 }, 1626 1627 /* Retrieve the default date shown on opening. */ 1628 _getDefaultDate: function( inst ) { 1629 return this._restrictMinMax( inst, this._determineDate( inst, this._get( inst, 'defaultDate' ), new Date() ) ); 1630 }, 1631 1632 /* A date may be specified as an exact value or a relative one. */ 1633 _determineDate: function( inst, date, defaultDate ) { 1634 var offsetNumeric = function( offset ) { 1635 var sdate = new Date(); 1636 sdate.setDate( sdate.getDate() + offset ); 1637 return sdate; 1638 }, 1639 offsetString = function( offset ) { 1640 var sdate; 1641 var year; 1642 var month; 1643 var day; 1644 var pattern; 1645 var matches; 1646 1647 try { 1648 return $.tm_datepicker.parseDate( $.tm_datepicker._get( inst, 'dateFormat' ), offset, $.tm_datepicker._getFormatConfig( inst ) ); 1649 } catch ( e ) { 1650 // Ignore 1651 } 1652 1653 sdate = ( offset.toLowerCase().match( /^c/ ) ? $.tm_datepicker._getDate( inst ) : null ) || new Date(); 1654 year = sdate.getFullYear();
vendor: 4,468 bytes, lines 1655-1780
1655 month = sdate.getMonth(); 1656 day = sdate.getDate(); 1657 pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; 1658 matches = pattern.exec( offset ); 1659 1660 while ( matches ) { 1661 switch ( matches[ 2 ] || 'd' ) { 1662 case 'd': 1663 case 'D': 1664 day += parseInt( matches[ 1 ], 10 ); 1665 break; 1666 case 'w': 1667 case 'W': 1668 day += parseInt( matches[ 1 ], 10 ) * 7; 1669 break; 1670 case 'm': 1671 case 'M': 1672 month += parseInt( matches[ 1 ], 10 ); 1673 day = Math.min( day, $.tm_datepicker._getDaysInMonth( year, month ) ); 1674 break; 1675 case 'y': 1676 case 'Y': 1677 year += parseInt( matches[ 1 ], 10 ); 1678 day = Math.min( day, $.tm_datepicker._getDaysInMonth( year, month ) ); 1679 break; 1680 } 1681 matches = pattern.exec( offset ); 1682 } 1683 return new Date( year, month, day ); 1684 }, 1685 newDate = date === null || date === '' ? defaultDate : typeof date === 'string' ? offsetString( date ) : typeof date === 'number' ? ( ! Number.isFinite( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ); 1686 1687 newDate = newDate && newDate.toString() === 'Invalid Date' ? defaultDate : newDate; 1688 if ( newDate ) { 1689 newDate.setHours( 0 ); 1690 newDate.setMinutes( 0 ); 1691 newDate.setSeconds( 0 ); 1692 newDate.setMilliseconds( 0 ); 1693 } 1694 return this._daylightSavingAdjust( newDate ); 1695 }, 1696 1697 /* Handle switch to/from daylight saving. 1698 * Hours may be non-zero on daylight saving cut-over: 1699 * > 12 when midnight changeover, but then cannot generate 1700 * midnight datetime, so jump to 1AM, otherwise reset. 1701 * @param date (Date) the date to check 1702 * @return (Date) the corrected date 1703 */ 1704 _daylightSavingAdjust: function( date ) { 1705 if ( ! date ) { 1706 return null; 1707 } 1708 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 1709 return date; 1710 }, 1711 1712 /* Set the date(s) directly. */ 1713 _setDate: function( inst, date, noChange ) { 1714 var clear = ! date, 1715 origMonth = inst.selectedMonth, 1716 origYear = inst.selectedYear, 1717 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 1718 1719 inst.currentDay = newDate.getDate(); 1720 inst.selectedDay = inst.currentDay; 1721 inst.currentMonth = newDate.getMonth(); 1722 inst.drawMonth = inst.currentMonth; 1723 inst.selectedMonth = inst.currentMonth; 1724 inst.currentYear = newDate.getFullYear(); 1725 inst.drawYear = inst.currentYear; 1726 inst.selectedYear = inst.currentYear; 1727 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && ! noChange ) { 1728 this._notifyChange( inst ); 1729 } 1730 this._adjustInstDate( inst ); 1731 if ( inst.input ) { 1732 inst.input.val( clear ? '' : this._formatDate( inst ) ); 1733 } 1734 }, 1735 1736 /* Retrieve the date(s) directly. */ 1737 _getDate: function( inst ) { 1738 var startDate = ! inst.currentYear || ( inst.input && inst.input.val() === '' ) ? null : this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ); 1739 return startDate; 1740 }, 1741 1742 /* Attach the onxxx handlers. These are declared statically so 1743 * they work with static code transformers like Caja. 1744 */ 1745 _attachHandlers: function( inst ) { 1746 var stepMonths = this._get( inst, 'stepMonths' ), 1747 id = '#' + inst.id.replace( /\\\\/g, '\\' ); 1748 inst.dpDiv.find( '[data-handler]' ).map( function() { 1749 var handler = { 1750 prevM: function() { 1751 $.tm_datepicker._adjustDate( id, -1, 'M' ); 1752 }, 1753 nextM: function() { 1754 $.tm_datepicker._adjustDate( id, +1, 'M' ); 1755 }, 1756 prevY: function() { 1757 $.tm_datepicker._adjustDate( id, -1, 'Y' ); 1758 }, 1759 nextY: function() { 1760 $.tm_datepicker._adjustDate( id, +1, 'Y' ); 1761 }, 1762 prev: function() { 1763 $.tm_datepicker._adjustDate( id, -stepMonths, 'M' ); 1764 }, 1765 next: function() { 1766 $.tm_datepicker._adjustDate( id, +stepMonths, 'M' ); 1767 }, 1768 hide: function() { 1769 $.tm_datepicker._hideDatepicker(); 1770 }, 1771 today: function() { 1772 /*var tempDate = new Date(), 1773 today = $.tm_datepicker._daylightSavingAdjust( 1774 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())); 1775 $.tm_datepicker._setDate(inst, today); 1776 $.tm_datepicker._gotoToday(id);*/ 1777 }, 1778 selectDay: function() { 1779 $.tm_datepicker._selectDay( id, +this.getAttribute( 'data-month' ), +this.getAttribute( 'data-year' ), this ); 1780 return false;
1781 }, 1782 selectMonth: function() { 1783 $.tm_datepicker._selectMonthYear( id, this, 'M' ); 1784 return false; 1785 }, 1786 selectYear: function() { 1787 $.tm_datepicker._selectMonthYear( id, this, 'Y' ); 1788 return false; 1789 } 1790 }; 1791 $( this ).on( this.getAttribute( 'data-event' ), handler[ this.getAttribute( 'data-handler' ) ] ); 1792 return null; 1793 } ); 1794 }, 1795 /* Determines if we should allow a "next/prev" month display change. */ 1796 _tm_canAdjustMonth: function( inst, offset, curYear, curMonth ) { 1797 var date = this._daylightSavingAdjust( new Date( curYear, curMonth + offset, 1 ) ); 1798 1799 if ( offset < 0 ) { 1800 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 1801 } 1802 return this._isInRange( inst, date ); 1803 }, 1804 1805 /* Generate the HTML for the current state of the date picker. */ 1806 _generateHTML: function( inst ) { 1807 var maxDraw, 1808 prevText, 1809 prev, 1810 nextText, 1811 next, 1812 currentText, 1813 gotoDate, 1814 firstDay, 1815 showWeek, 1816 dayNames, 1817 dayNamesMin, 1818 monthNames, 1819 beforeShowDay, 1820 showOtherMonths, 1821 selectOtherMonths, 1822 defaultDate, 1823 html, 1824 dow, 1825 row, 1826 group, 1827 col, 1828 selectedDate, 1829 cornerClass, 1830 calender, 1831 thead, 1832 day, 1833 daysInMonth, 1834 leadDays, 1835 curRows, 1836 numRows, 1837 printDate, 1838 dRow, 1839 tbody, 1840 daySettings, 1841 otherMonth, 1842 unselectable, 1843 tempDate = new Date(), 1844 today = this._daylightSavingAdjust( new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 1845 isRTL = this._get( inst, 'isRTL' ), 1846 showButtonPanel = this._get( inst, 'showButtonPanel' ), 1847 hideIfNoPrevNext = this._get( inst, 'hideIfNoPrevNext' ), 1848 navigationAsDateFormat = this._get( inst, 'navigationAsDateFormat' ), 1849 numMonths = this._getNumberOfMonths( inst ), 1850 showCurrentAtPos = this._get( inst, 'showCurrentAtPos' ), 1851 stepMonths = this._get( inst, 'stepMonths' ), 1852 isMultiMonth = numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1, 1853 currentDate = this._daylightSavingAdjust( ! inst.currentDay ? new Date( 9999, 9, 9 ) : new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ), 1854 minDate = this._getMinMaxDate( inst, 'min' ), 1855 maxDate = this._getMinMaxDate( inst, 'max' ), 1856 drawMonth = inst.drawMonth - showCurrentAtPos, 1857 drawYear = inst.drawYear, 1858 tm_month, 1859 tm_year, 1860 tm_prev_arrow_m, 1861 tm_next_arrow_m, 1862 tm_prev_arrow_y, 1863 tm_next_arrow_y, 1864 tm_controls, 1865 tm_buttonPanel; 1866 var can_adjust_1; 1867 var can_adjust_2; 1868 var can_adjust_3; 1869 var can_adjust_4; 1870 1871 if ( drawMonth < 0 ) { 1872 drawMonth += 12; 1873 drawYear -= 1; 1874 } 1875 if ( maxDate ) { 1876 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 1877 maxDraw = minDate && maxDraw < minDate ? minDate : maxDraw; 1878 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 1879 drawMonth -= 1; 1880 if ( drawMonth < 0 ) { 1881 drawMonth = 11; 1882 drawYear -= 1; 1883 } 1884 } 1885 } 1886 inst.drawMonth = drawMonth; 1887 inst.drawYear = drawYear; 1888 1889 prevText = this._get( inst, 'prevText' ); 1890 prevText = ! navigationAsDateFormat ? prevText : this.formatDate( prevText, this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), this._getFormatConfig( inst ) ); 1891 1892 prev = this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ? "<a class='ui-tm-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? 'e' : 'w' ) + "'>" + prevText + '</span></a>' : hideIfNoPrevNext ? '' : "<a class='ui-tm-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? 'e' : 'w' ) + "'>" + prevText + '</span></a>'; 1893 1894 nextText = this._get( inst, 'nextText' ); 1895 nextText = ! navigationAsDateFormat ? nextText : this.formatDate( nextText, this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), this._getFormatConfig( inst ) ); 1896 1897 next = this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ? "<a class='ui-tm-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? 'w' : 'e' ) + "'>" + nextText + '</span></a>' : hideIfNoPrevNext ? '' : "<a class='ui-tm-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? 'w' : 'e' ) + "'>" + nextText + '</span></a>'; 1898 1899 currentText = this._get( inst, 'currentText' ); 1900 gotoDate = this._get( inst, 'gotoCurrent' ) && inst.currentDay ? currentDate : today; 1901 currentText = ! navigationAsDateFormat ? currentText : this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ); 1902 1903 tm_controls = ! inst.inline ? "<div class='tm-ui-dp-btn-wrap tm-ui-dp-close'><div role='button' class='tm-ui-dp-btn ui-tm-datepicker-close' data-handler='hide' data-event='click'>" + this._get( inst, 'closeText' ) + '</div></div>' : ''; 1904 1905 tm_buttonPanel = showButtonPanel ? "<div class='tm-ui-dp-buttonpane'>" + ( isRTL ? tm_controls : '' ) + ( this._isInRange( inst, gotoDate ) ? "<div class='tm-ui-dp-btn-wrap tm-ui-dp-current'><div role='button' class='tm-ui-dp-btn ui-tm-datepicker-current' data-handler='today' data-event='click'" + '>' + currentText + '</div></div>' : '' ) + ( isRTL ? '' : tm_controls ) + '</div>' : ''; 1906 1907 firstDay = parseInt( this._get( inst, 'firstDay' ), 10 ); 1908 firstDay = isNaN( firstDay ) ? 0 : firstDay; 1909 1910 showWeek = this._get( inst, 'showWeek' ); 1911 dayNames = this._get( inst, 'dayNames' ); 1912 dayNamesMin = this._get( inst, 'dayNamesMin' ); 1913 monthNames = this._get( inst, 'monthNames' ); 1914 //monthNamesShort = this._get(inst, "monthNamesShort"); 1915 beforeShowDay = this._get( inst, 'beforeShowDay' ); 1916 showOtherMonths = this._get( inst, 'showOtherMonths' ); 1917 selectOtherMonths = this._get( inst, 'selectOtherMonths' ); 1918 defaultDate = this._getDefaultDate( inst ); 1919 html = ''; 1920 1921 can_adjust_1 = this._tm_canAdjustMonth( inst, -1, drawYear, drawMonth ); 1922 can_adjust_2 = this._tm_canAdjustMonth( inst, +1, drawYear, drawMonth ); 1923 can_adjust_3 = this._tm_canAdjustMonth( inst, -12, drawYear, drawMonth ); 1924 can_adjust_4 = this._tm_canAdjustMonth( inst, +12, drawYear, drawMonth ); 1925 1926 tm_prev_arrow_m = '<div class="tm-ui-dp-button-prev tm-ui-dp-button">' + '<div ' + ( can_adjust_1 ? 'data-handler="prevM" data-event="click" ' : '' ) + 'aria-label="' + prevText + '" class="' + ( can_adjust_1 ? '' : 'tm-ui-dp-button-disabled ' ) + 'tm-ui-dp-button-arrow tcfa tcfa-angle-left" tabindex="0" role="button"></div>' + '</div>'; 1927 tm_next_arrow_m = '<div class="tm-ui-dp-button-next tm-ui-dp-button">' + '<div ' + ( can_adjust_2 ? 'data-handler="nextM" data-event="click" ' : '' ) + 'aria-label="' + nextText + '" class="' + ( can_adjust_2 ? '' : 'tm-ui-dp-button-disabled ' ) + 'tm-ui-dp-button-arrow tcfa tcfa-angle-right" tabindex="0" role="button"></div>' + '</div>'; 1928 tm_prev_arrow_y = '<div class="tm-ui-dp-button-prev tm-ui-dp-button">' + '<div ' + ( can_adjust_3 ? 'data-handler="prevY" data-event="click" ' : '' ) + 'aria-label="' + prevText + '" class="' + ( can_adjust_3 ? '' : 'tm-ui-dp-button-disabled ' ) + 'tm-ui-dp-button-arrow tcfa tcfa-angle-left" tabindex="0" role="button"></div>' + '</div>'; 1929 tm_next_arrow_y = '<div class="tm-ui-dp-button-next tm-ui-dp-button">' + '<div ' + ( can_adjust_4 ? 'data-handler="nextY" data-event="click" ' : '' ) + 'aria-label="' + nextText + '" class="' + ( can_adjust_4 ? '' : 'tm-ui-dp-button-disabled ' ) + 'tm-ui-dp-button-arrow tcfa tcfa-angle-right" tabindex="0" role="button"></div>' + '</div>'; 1930
1931 tm_month = hideIfNoPrevNext ? '' : '<div class="tm-ui-dp-title-button">' + ( isRTL ? tm_next_arrow_m : tm_prev_arrow_m ) + '<span aria-label="' + monthNames[ drawMonth ] + '" role="button" class="tm-ui-dp-month">' + monthNames[ drawMonth ] + '</span>' + ( isRTL ? tm_prev_arrow_m : tm_next_arrow_m ) + '</div>'; 1932 1933 tm_year = hideIfNoPrevNext ? '' : '<div class="tm-ui-dp-title-button">' + ( isRTL ? tm_next_arrow_y : tm_prev_arrow_y ) + '<span class="tm-ui-dp-year" role="button" aria-label="' + drawYear + '">' + drawYear + '</span>' + ( isRTL ? tm_prev_arrow_y : tm_next_arrow_y ) + '</div>'; 1934 1935 html += "<div class='tm-ui-dp-wrap'>" + "<div class='tm-ui-dp-overlay'></div>" + "<div class='tm-ui-dp'>" + "<div class='tm-ui-dp-container'>" + "<div class='tm-ui-dp-inner-container'>" + "<div class='tm-ui-dp-ui'>" + "<div class='tm-ui-dp-ui-inner'>" + "<div class='tm-ui-dp-main-wrap'>" + "<div class='tm-ui-dp-main'>"; 1936 1937 for ( row = 0; row < numMonths[ 0 ]; row += 1 ) { 1938 group = ''; 1939 this.maxRows = 4; 1940 for ( col = 0; col < numMonths[ 1 ]; col += 1 ) { 1941 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 1942 cornerClass = ' ui-corner-all'; 1943 calender = ''; 1944 if ( isMultiMonth ) { 1945 calender += "<div class='ui-tm-datepicker-group"; 1946 if ( numMonths[ 1 ] > 1 ) { 1947 switch ( col ) { 1948 case 0: 1949 calender += ' ui-tm-datepicker-group-first'; 1950 cornerClass = ' ui-corner-' + ( isRTL ? 'right' : 'left' ); 1951 break; 1952 case numMonths[ 1 ] - 1: 1953 calender += ' ui-tm-datepicker-group-last'; 1954 cornerClass = ' ui-corner-' + ( isRTL ? 'left' : 'right' ); 1955 break; 1956 default: 1957 calender += ' ui-tm-datepicker-group-middle'; 1958 cornerClass = ''; 1959 break; 1960 } 1961 } 1962 calender += "'>"; 1963 } 1964 calender += 1965 "<div class='tm-ui-dp-header ui-tm-datepicker-header ui-widget-header ui-helper-clearfix" + 1966 cornerClass + 1967 "'>" + 1968 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : '' ) + 1969 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : '' ) + 1970 // month headers 1971 1972 '<div class="ui-tm-datepicker-title tm-ui-dp-title">' + 1973 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? tm_year + tm_month : tm_month + tm_year ) : '' ) + 1974 '</div>' + 1975 '</div>'; 1976 1977 calender += "<div class='tm-ui-dp-main-content'>"; 1978 1979 /* Days start */ 1980 calender += "<div class='tm-ui-dp-main-header-wrap'><div class='tm-ui-dp-main-header'>"; 1981 calender += "<table class='ui-tm-datepicker-calendar'><tbody>" + '<tr>'; 1982 thead = showWeek ? "<th class='ui-tm-datepicker-week-col'>" + this._get( inst, 'weekHeader' ) + '</th>' : ''; 1983 for ( dow = 0; dow < 7; dow += 1 ) { 1984 // days of the week 1985 day = ( dow + firstDay ) % 7; 1986 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-tm-datepicker-week-end'" : '' ) + '>
1986' + "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + '</span></th>'; 1987 } 1988 calender += thead + '</tr></tbody></table>'; 1989 calender += '</div></div>'; 1990 /* Days end */ 1991 1992 calender += "<div class='tm-ui-dp-main-table'>"; 1993 1994 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 1995 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 1996 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 1997 } 1998 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 1999 curRows = 6; 2000 numRows = isMultiMonth ? ( this.maxRows > curRows ? this.maxRows : curRows ) : curRows; //If multiple months, use the higher number of rows 2001 // (see #7043) 2002 this.maxRows = numRows; 2003 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 2004 for ( dRow = 0; dRow < numRows; dRow += 1 ) { 2005 // create date picker rows 2006 calender += "<div class='tm-ui-dp-main-row'>"; 2007 tbody = ! showWeek ? '' : "<div class='ui-tm-datepicker-week-col'>" + this._get( inst, 'calculateWeek' )( printDate ) + '</div>'; 2008 for ( dow = 0; dow < 7; dow += 1 ) { 2009 // create date picker days 2010 daySettings = beforeShowDay ? beforeShowDay.apply( inst.input ? inst.input[ 0 ] : null, [ printDate ] ) : [ true, '' ]; 2011 otherMonth = printDate.getMonth() !== drawMonth; 2012 unselectable = ( otherMonth && ! selectOtherMonths ) || ! daySettings[ 0 ] || ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 2013 2014 tbody += 2015 "<div class='tm-ui-dp-main-cell " + 2016 ( ( dow + firstDay + 6 ) % 7 >= 5 ? ' ui-tm-datepicker-week-end' : '' ) + // highlight weekends 2017 ( otherMonth ? ' ui-tm-datepicker-other-month' : '' ) + // highlight days from other months 2018 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? ' ' + this._dayOverClass : '' ) + 2019 ( unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled' : '' ) + // highlight unselectable days 2020 ( otherMonth && ! showOtherMonths ? '' : ' ' + daySettings[ 1 ] + ( printDate.getTime() === currentDate.getTime() ? ' ' + this._currentClass : '' ) + ( printDate.getTime() === today.getTime() ? ' ui-tm-datepicker-today' : '' ) ) + 2021 "'" + // highlight today (if different) 2022 ( ( ! otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, ''' ) + "'" : '' ) + // cell 2023 // title 2024 ( unselectable ? '' : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + 2025 '>' + // actions 2026 "<div class='tm-ui-dp-main-cell-inner'>" + 2027 "<div class='tm-ui-dp-main-cell-content'>" + 2028 ( otherMonth && ! showOtherMonths ? ' ' : unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + '</span>' : "<a class='ui-state-default" + ( printDate.getTime() === today.getTime() ? ' ui-state-highlight' : '' ) + ( printDate.getTime() === currentDate.getTime() ? ' ui-state-active' : '' ) + ( otherMonth ? ' ui-priority-secondary' : '' ) + "' href='#'>" + printDate.getDate() + '</a>' ) + 2029 '</div></div>' + 2030 '</div>'; // display selectable date 2031 printDate.setDate( printDate.getDate() + 1 ); 2032 printDate = this._daylightSavingAdjust( printDate ); 2033 } 2034 calender += tbody + '</div>'; 2035 } 2036 drawMonth += 1; 2037 if ( drawMonth > 11 ) { 2038 drawMonth = 0; 2039 drawYear += 1; 2040 } 2041 2042 calender += '</div>'; 2043 2044 calender += '</div>' + ( isMultiMonth ? '</div>' + ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ? "<div class='ui-tm-datepicker-row-break'></div>" : '' ) : '' ); 2045 group += calender; 2046 } 2047 html += group; 2048 } 2049 html += '</div></div></div></div></div>'; 2050 html += tm_buttonPanel; 2051 html += '</div></div></div>'; 2052 inst._keyEvent = false; 2053 return html; 2054 }, 2055 2056 /* Generate the month and year header. */ 2057 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, secondary, monthNames, monthNamesShort ) { 2058 var inMinYear, 2059 inMaxYear, 2060 month, 2061 years, 2062 thisYear, 2063 determineYear, 2064 year, 2065 endYear, 2066 changeMonth = this._get( inst, 'changeMonth' ), 2067 changeYear = this._get( inst, 'changeYear' ), 2068 showMonthAfterYear = this._get( inst, 'showMonthAfterYear' ), 2069 html = "<div class='ui-tm-datepicker-title'>", 2070 monthHtml = ''; 2071 2072 // month selection 2073 if ( secondary || ! changeMonth ) { 2074 monthHtml += "<span class='ui-tm-datepicker-month'>" + monthNames[ drawMonth ] + '</span>'; 2075 } else { 2076 inMinYear = minDate && minDate.getFullYear() === drawYear; 2077 inMaxYear = maxDate && maxDate.getFullYear() === drawYear; 2078 monthHtml += "<select class='ui-tm-datepicker-month' data-handler='selectMonth' data-event='change'>"; 2079 for ( month = 0; month < 12; month += 1 ) { 2080 if ( ( ! inMinYear || month >= minDate.getMonth() ) && ( ! inMaxYear || month <= maxDate.getMonth() ) ) { 2081 monthHtml += "<option value='" + month + "'" + ( month === drawMonth ? " selected='selected'" : '' ) + '>
2081' + monthNamesShort[ month ] + '</option>'; 2082 } 2083 } 2084 monthHtml += '</select>'; 2085 } 2086 2087 if ( ! showMonthAfterYear ) { 2088 html += monthHtml + ( secondary || ! ( changeMonth && changeYear ) ? ' ' : '' ); 2089 } 2090 2091 // year selection 2092 if ( ! inst.yearshtml ) { 2093 inst.yearshtml = ''; 2094 if ( secondary || ! changeYear ) { 2095 html += "<span class='ui-tm-datepicker-year'>" + drawYear + '</span>'; 2096 } else { 2097 // determine range of years to display 2098 years = this._get( inst, 'yearRange' ).split( ':' ); 2099 thisYear = new Date().getFullYear(); 2100 determineYear = function( value ) { 2101 var syear = value.match( /c[+-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : value.match( /[+-].*/ ) ? thisYear + parseInt( value, 10 ) : parseInt( value, 10 ); 2102 return isNaN( syear ) ? thisYear : syear; 2103 }; 2104 year = determineYear( years[ 0 ] ); 2105 endYear = Math.max( year, determineYear( years[ 1 ] || '' ) ); 2106 year = minDate ? Math.max( year, minDate.getFullYear() ) : year; 2107 endYear = maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear; 2108 inst.yearshtml += "<select class='ui-tm-datepicker-year' data-handler='selectYear' data-event='change'>"; 2109 for ( ; year <= endYear; year += 1 ) { 2110 inst.yearshtml += "<option value='" + year + "'" + ( year === drawYear ? " selected='selected'" : '' ) + '>
vendor: 6,708 bytes, lines 2110-2284
2110' + year + '</option>'; 2111 } 2112 inst.yearshtml += '</select>'; 2113 2114 html += inst.yearshtml; 2115 inst.yearshtml = null; 2116 } 2117 } 2118 2119 html += this._get( inst, 'yearSuffix' ); 2120 if ( showMonthAfterYear ) { 2121 html += ( secondary || ! ( changeMonth && changeYear ) ? ' ' : '' ) + monthHtml; 2122 } 2123 html += '</div>'; // Close datepicker_header 2124 return html; 2125 }, 2126 2127 /* Adjust one of the date sub-fields. */ 2128 _adjustInstDate: function( inst, offset, period ) { 2129 var year = inst.selectedYear + ( period === 'Y' ? offset : 0 ), 2130 month = inst.selectedMonth + ( period === 'M' ? offset : 0 ), 2131 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === 'D' ? offset : 0 ), 2132 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 2133 2134 inst.selectedDay = date.getDate(); 2135 inst.selectedMonth = date.getMonth(); 2136 inst.drawMonth = inst.selectedMonth; 2137 inst.selectedYear = date.getFullYear(); 2138 inst.drawYear = inst.selectedYear; 2139 if ( period === 'M' || period === 'Y' ) { 2140 this._notifyChange( inst ); 2141 } 2142 }, 2143 2144 /* Ensure a date is within any min/max bounds. */ 2145 _restrictMinMax: function( inst, date ) { 2146 var minDate = this._getMinMaxDate( inst, 'min' ), 2147 maxDate = this._getMinMaxDate( inst, 'max' ), 2148 newDate = minDate && date < minDate ? minDate : date; 2149 return maxDate && newDate > maxDate ? maxDate : newDate; 2150 }, 2151 2152 /* Notify change of month/year. */ 2153 _notifyChange: function( inst ) { 2154 var onChange = this._get( inst, 'onChangeMonthYear' ); 2155 if ( onChange ) { 2156 onChange.apply( inst.input ? inst.input[ 0 ] : null, [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 2157 } 2158 }, 2159 2160 /* Determine the number of months to show. */ 2161 _getNumberOfMonths: function( inst ) { 2162 var numMonths = this._get( inst, 'numberOfMonths' ); 2163 return numMonths === null ? [ 1, 1 ] : typeof numMonths === 'number' ? [ 1, numMonths ] : numMonths; 2164 }, 2165 2166 /* Determine the current maximum date - ensure no time components are set. */ 2167 _getMinMaxDate: function( inst, minMax ) { 2168 return this._determineDate( inst, this._get( inst, minMax + 'Date' ), null ); 2169 }, 2170 2171 /* Find the number of days in a given month. */ 2172 _getDaysInMonth: function( year, month ) { 2173 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 2174 }, 2175 2176 /* Find the day of the week of the first of a month. */ 2177 _getFirstDayOfMonth: function( year, month ) { 2178 return new Date( year, month, 1 ).getDay(); 2179 }, 2180 2181 /* Determines if we should allow a "next/prev" month display change. */ 2182 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 2183 var numMonths = this._getNumberOfMonths( inst ), 2184 date = this._daylightSavingAdjust( new Date( curYear, curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 2185 2186 if ( offset < 0 ) { 2187 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 2188 } 2189 return this._isInRange( inst, date ); 2190 }, 2191 2192 /* Is the given date in the accepted range? */ 2193 _isInRange: function( inst, date ) { 2194 var yearSplit, 2195 currentYear, 2196 minDate = this._getMinMaxDate( inst, 'min' ), 2197 maxDate = this._getMinMaxDate( inst, 'max' ), 2198 minYear = null, 2199 maxYear = null, 2200 years = this._get( inst, 'yearRange' ); 2201 if ( years ) { 2202 yearSplit = years.split( ':' ); 2203 currentYear = new Date().getFullYear(); 2204 minYear = parseInt( yearSplit[ 0 ], 10 ); 2205 maxYear = parseInt( yearSplit[ 1 ], 10 ); 2206 if ( yearSplit[ 0 ].match( /[+-].*/ ) ) { 2207 minYear += currentYear; 2208 } 2209 if ( yearSplit[ 1 ].match( /[+-].*/ ) ) { 2210 maxYear += currentYear; 2211 } 2212 } 2213 2214 return ( ! minDate || date.getTime() >= minDate.getTime() ) && ( ! maxDate || date.getTime() <= maxDate.getTime() ) && ( ! minYear || date.getFullYear() >= minYear ) && ( ! maxYear || date.getFullYear() <= maxYear ); 2215 }, 2216 2217 /* Provide the configuration settings for formatting/parsing. */ 2218 _getFormatConfig: function( inst ) { 2219 var shortYearCutoff = this._get( inst, 'shortYearCutoff' ); 2220 shortYearCutoff = typeof shortYearCutoff !== 'string' ? shortYearCutoff : ( new Date().getFullYear() % 100 ) + parseInt( shortYearCutoff, 10 ); 2221 return { 2222 shortYearCutoff: shortYearCutoff, 2223 dayNamesShort: this._get( inst, 'dayNamesShort' ), 2224 dayNames: this._get( inst, 'dayNames' ), 2225 monthNamesShort: this._get( inst, 'monthNamesShort' ), 2226 monthNames: this._get( inst, 'monthNames' ) 2227 }; 2228 }, 2229 2230 /* Format the given date for display. */ 2231 _formatDate: function( inst, day, month, year ) { 2232 var date; 2233 2234 if ( ! day ) { 2235 inst.currentDay = inst.selectedDay; 2236 inst.currentMonth = inst.selectedMonth; 2237 inst.currentYear = inst.selectedYear; 2238 } 2239 date = day ? ( typeof day === 'object' ? day : this._daylightSavingAdjust( new Date( year, month, day ) ) ) : this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ); 2240 return this.formatDate( this._get( inst, 'dateFormat' ), date, this._getFormatConfig( inst ) ); 2241 } 2242 } ); 2243 2244 /* Invoke the datepicker functionality. 2245 @param options string - a command, optionally followed by additional parameters or 2246 Object - settings for attaching new datepicker functionality 2247 @return jQuery object */ 2248 $.fn.tm_datepicker = function( options ) { 2249 var otherArgs; 2250 2251 /* Verify an empty collection wasn't passed - Fixes #6976 */ 2252 if ( ! this.length ) { 2253 return this; 2254 } 2255 2256 /* Initialise the date picker. */ 2257 if ( ! $.tm_datepicker.initialized ) { 2258 $( document ).on( 'mousedown', $.tm_datepicker._checkExternalClick ); 2259 $.tm_datepicker.initialized = true; 2260 } 2261 2262 /* Append datepicker main container to body if not exist. */ 2263 if ( $( '#' + $.tm_datepicker._mainDivId ).length === 0 ) { 2264 $( 'body' ).append( $.tm_datepicker.dpDiv ); 2265 } 2266 2267 otherArgs = Array.prototype.slice.call( arguments, 1 ); 2268 if ( typeof options === 'string' && ( options === 'isDisabled' || options === 'getDate' || options === 'widget' ) ) { 2269 return $.tm_datepicker[ '_' + options + 'Datepicker' ].apply( $.tm_datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 2270 } 2271 if ( options === 'option' && arguments.length === 2 && typeof arguments[ 1 ] === 'string' ) { 2272 return $.tm_datepicker[ '_' + options + 'Datepicker' ].apply( $.tm_datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 2273 } 2274 return this.each( function() { 2275 if ( typeof options === 'string' ) { 2276 $.tm_datepicker[ '_' + options + 'Datepicker' ].apply( $.tm_datepicker, [ this ].concat( otherArgs ) ); 2277 } else { 2278 $.tm_datepicker._attachDatepicker( this, options ); 2279 } 2280 } ); 2281 }; 2282 2283 $.tm_datepicker = new Datepicker(); // singleton instance 2284 $.tm_datepicker.initialized = false;
2285 $.tm_datepicker.uuid = new Date().getTime(); 2286 $.tm_datepicker.version = '1.11.4'; 2287} ) );
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.