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