source: schedule/js/jquery-ui-1.10.1.custom.js

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