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