Subversion Repositories Applications.papyrus

Rev

Rev 1959 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1959 Rev 2150
1
/*
1
/*
2
 * jQuery UI Datepicker @VERSION
2
 * jQuery UI Datepicker 1.8.6
3
 *
3
 *
4
 * Copyright (c) 2006, 2007, 2008 Marc Grabanski
4
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5
 * Dual licensed under the MIT (MIT-LICENSE.txt)
5
 * Dual licensed under the MIT or GPL Version 2 licenses.
6
 * and GPL (GPL-LICENSE.txt) licenses.
6
 * http://jquery.org/license
7
 * 
7
 *
8
 * http://docs.jquery.com/UI/Datepicker
8
 * http://docs.jquery.com/UI/Datepicker
9
 *
9
 *
10
 * Depends:
10
 * Depends:
11
 *	ui.core.js
11
 *	jquery.ui.core.js
12
 *
-
 
13
 * Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).
-
 
14
 */
12
 */
-
 
13
(function( $, undefined ) {
15
   
14
 
16
(function($) { // hide the namespace
15
$.extend($.ui, { datepicker: { version: "1.8.6" } });
-
 
16
 
17
 
17
var PROP_NAME = 'datepicker';
18
var PROP_NAME = 'datepicker';
18
var dpuuid = new Date().getTime();
19
 
19
 
20
/* Date picker manager.
20
/* Date picker manager.
21
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
21
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
22
   Settings for (groups of) date pickers are maintained in an instance object,
22
   Settings for (groups of) date pickers are maintained in an instance object,
23
   allowing multiple different settings on the same page. */
23
   allowing multiple different settings on the same page. */
24
 
24
 
25
function Datepicker() {
25
function Datepicker() {
26
	this.debug = false; // Change this to true to start debugging
26
	this.debug = false; // Change this to true to start debugging
27
	this._curInst = null; // The current instance in use
27
	this._curInst = null; // The current instance in use
28
	this._keyEvent = false; // If the last event was a key event
28
	this._keyEvent = false; // If the last event was a key event
29
	this._disabledInputs = []; // List of date picker inputs that have been disabled
29
	this._disabledInputs = []; // List of date picker inputs that have been disabled
30
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
30
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
31
	this._inDialog = false; // True if showing within a "dialog", false if not
31
	this._inDialog = false; // True if showing within a "dialog", false if not
32
	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
32
	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
33
	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
33
	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
34
	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
34
	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
35
	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
35
	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
36
	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
36
	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
37
	this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class
-
 
38
	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
37
	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
39
	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
38
	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
40
	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
39
	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
41
	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
40
	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
42
	this._weekOverClass = 'ui-datepicker-week-over'; // The name of the week hover marker class
-
 
43
	this.regional = []; // Available regional settings, indexed by language code
41
	this.regional = []; // Available regional settings, indexed by language code
44
	this.regional[''] = { // Default regional settings
42
	this.regional[''] = { // Default regional settings
45
		clearText: 'Clear', // Display text for clear link
-
 
46
		clearStatus: 'Erase the current date', // Status text for clear link
-
 
47
		closeText: 'Close', // Display text for close link
43
		closeText: 'Done', // Display text for close link
48
		closeStatus: 'Close without change', // Status text for close link
-
 
49
		prevText: '<Prev', // Display text for previous month link
44
		prevText: 'Prev', // Display text for previous month link
50
		prevStatus: 'Show the previous month', // Status text for previous month link
-
 
51
		prevBigText: '<<', // Display text for previous year link
-
 
52
		prevBigStatus: 'Show the previous year', // Status text for previous year link
-
 
53
		nextText: 'Next>', // Display text for next month link
45
		nextText: 'Next', // Display text for next month link
54
		nextStatus: 'Show the next month', // Status text for next month link
-
 
55
		nextBigText: '>>', // Display text for next year link
-
 
56
		nextBigStatus: 'Show the next year', // Status text for next year link
-
 
57
		currentText: 'Today', // Display text for current month link
46
		currentText: 'Today', // Display text for current month link
58
		currentStatus: 'Show the current month', // Status text for current month link
-
 
59
		monthNames: ['January','February','March','April','May','June',
47
		monthNames: ['January','February','March','April','May','June',
60
			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
48
			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
61
		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
49
		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
62
		monthStatus: 'Show a different month', // Status text for selecting a month
-
 
63
		yearStatus: 'Show a different year', // Status text for selecting a year
-
 
64
		weekHeader: 'Wk', // Header for the week of the year column
-
 
65
		weekStatus: 'Week of the year', // Status text for the week of the year column
-
 
66
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
50
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
67
		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
51
		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
68
		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
52
		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
69
		dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
-
 
70
		dateStatus: 'Select DD, M d', // Status text for the date selection
53
		weekHeader: 'Wk', // Column header for week of the year
71
		dateFormat: 'mm/dd/yy', // See format options on parseDate
54
		dateFormat: 'mm/dd/yy', // See format options on parseDate
72
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
55
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
73
		initStatus: 'Select a date', // Initial Status text on opening
56
		isRTL: false, // True if right-to-left language, false if left-to-right
74
		isRTL: false // True if right-to-left language, false if left-to-right
57
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
-
 
58
		yearSuffix: '' // Additional text to append to the year in the month headers
75
	};
59
	};
76
	this._defaults = { // Global defaults for all the date picker instances
60
	this._defaults = { // Global defaults for all the date picker instances
77
		showOn: 'focus', // 'focus' for popup on focus,
61
		showOn: 'focus', // 'focus' for popup on focus,
78
			// 'button' for trigger button, or 'both' for either
62
			// 'button' for trigger button, or 'both' for either
79
		showAnim: 'show', // Name of jQuery animation for popup
63
		showAnim: 'fadeIn', // Name of jQuery animation for popup
80
		showOptions: {}, // Options for enhanced animations
64
		showOptions: {}, // Options for enhanced animations
81
		defaultDate: null, // Used when field is blank: actual date,
65
		defaultDate: null, // Used when field is blank: actual date,
82
			// +/-number for offset from today, null for today
66
			// +/-number for offset from today, null for today
83
		appendText: '', // Display text following the input box, e.g. showing the format
67
		appendText: '', // Display text following the input box, e.g. showing the format
84
		buttonText: '...', // Text for trigger button
68
		buttonText: '...', // Text for trigger button
85
		buttonImage: '', // URL for trigger button image
69
		buttonImage: '', // URL for trigger button image
86
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
70
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
87
		closeAtTop: true, // True to have the clear/close at the top,
-
 
88
			// false to have them at the bottom
-
 
89
		mandatory: false, // True to hide the Clear link, false to include it
-
 
90
		hideIfNoPrevNext: false, // True to hide next/previous month links
71
		hideIfNoPrevNext: false, // True to hide next/previous month links
91
			// if not applicable, false to just disable them
72
			// if not applicable, false to just disable them
92
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
73
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
93
		showBigPrevNext: false, // True to show big prev/next links
-
 
94
		gotoCurrent: false, // True if today link goes back to current selection instead
74
		gotoCurrent: false, // True if today link goes back to current selection instead
95
		changeMonth: true, // True if month can be selected directly, false if only prev/next
75
		changeMonth: false, // True if month can be selected directly, false if only prev/next
96
		changeYear: true, // True if year can be selected directly, false if only prev/next
76
		changeYear: false, // True if year can be selected directly, false if only prev/next
97
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
-
 
98
		yearRange: '-10:+10', // Range of years to display in drop-down,
77
		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
99
			// either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
78
			// either relative to today's year (-nn:+nn), relative to currently displayed year
100
		changeFirstDay: true, // True to click on day name to change, false to remain as set
79
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
101
		highlightWeek: false, // True to highlight the selected week
-
 
102
		showOtherMonths: false, // True to show dates in other months, false to leave blank
80
		showOtherMonths: false, // True to show dates in other months, false to leave blank
-
 
81
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
103
		showWeeks: false, // True to show week of the year, false to omit
82
		showWeek: false, // True to show week of the year, false to not show it
104
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
83
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
105
			// takes a Date and returns the number of the week for it
84
			// takes a Date and returns the number of the week for it
106
		shortYearCutoff: '+10', // Short year values < this are in the current century,
85
		shortYearCutoff: '+10', // Short year values < this are in the current century,
107
			// > this are in the previous century,
86
			// > this are in the previous century,
108
			// string value starting with '+' for current year + value
87
			// string value starting with '+' for current year + value
109
		showStatus: false, // True to show status bar at bottom, false to not show it
-
 
110
		statusForDate: this.dateStatus, // Function to provide status text for a date -
-
 
111
			// takes date and instance as parameters, returns display text
-
 
112
		minDate: null, // The earliest selectable date, or null for no limit
88
		minDate: null, // The earliest selectable date, or null for no limit
113
		maxDate: null, // The latest selectable date, or null for no limit
89
		maxDate: null, // The latest selectable date, or null for no limit
114
		duration: 'normal', // Duration of display/closure
90
		duration: 'fast', // Duration of display/closure
115
		beforeShowDay: null, // Function that takes a date and returns an array with
91
		beforeShowDay: null, // Function that takes a date and returns an array with
116
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
92
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
117
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
93
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
118
		beforeShow: null, // Function that takes an input field and
94
		beforeShow: null, // Function that takes an input field and
119
			// returns a set of custom settings for the date picker
95
			// returns a set of custom settings for the date picker
120
		onSelect: null, // Define a callback function when a date is selected
96
		onSelect: null, // Define a callback function when a date is selected
121
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
97
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
122
		onClose: null, // Define a callback function when the datepicker is closed
98
		onClose: null, // Define a callback function when the datepicker is closed
123
		numberOfMonths: 1, // Number of months to show at a time
99
		numberOfMonths: 1, // Number of months to show at a time
124
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
100
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
125
		stepMonths: 1, // Number of months to step back/forward
101
		stepMonths: 1, // Number of months to step back/forward
126
		stepBigMonths: 12, // Number of months to step back/forward for the big links
102
		stepBigMonths: 12, // Number of months to step back/forward for the big links
127
		rangeSelect: false, // Allows for selecting a date range on one date picker
-
 
128
		rangeSeparator: ' - ', // Text between two dates in a range
-
 
129
		altField: '', // Selector for an alternate field to store selected dates into
103
		altField: '', // Selector for an alternate field to store selected dates into
130
		altFormat: '', // The date format to use for the alternate field
104
		altFormat: '', // The date format to use for the alternate field
131
		constrainInput: true // The input is constrained by the current date format
105
		constrainInput: true, // The input is constrained by the current date format
-
 
106
		showButtonPanel: false, // True to show button panel, false to not show it
-
 
107
		autoSize: false // True to size the input for the date format, false to leave as is
132
	};
108
	};
133
	$.extend(this._defaults, this.regional['']);
109
	$.extend(this._defaults, this.regional['']);
134
	this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>');
110
	this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>');
135
}
111
}
136
 
112
 
137
$.extend(Datepicker.prototype, {
113
$.extend(Datepicker.prototype, {
138
	/* Class name added to elements to indicate already configured with a date picker. */
114
	/* Class name added to elements to indicate already configured with a date picker. */
139
	markerClassName: 'hasDatepicker',
115
	markerClassName: 'hasDatepicker',
140
	
116
 
141
	/* Debug logging (if enabled). */
117
	/* Debug logging (if enabled). */
142
	log: function () {
118
	log: function () {
143
		if (this.debug)
119
		if (this.debug)
144
			console.log.apply('', arguments);
120
			console.log.apply('', arguments);
145
	},
121
	},
-
 
122
	
-
 
123
	// TODO rename to "widget" when switching to widget factory
-
 
124
	_widgetDatepicker: function() {
-
 
125
		return this.dpDiv;
-
 
126
	},
146
	
127
 
147
	/* Override the default settings for all instances of the date picker. 
128
	/* Override the default settings for all instances of the date picker.
148
	   @param  settings  object - the new settings to use as defaults (anonymous object)
129
	   @param  settings  object - the new settings to use as defaults (anonymous object)
149
	   @return the manager object */
130
	   @return the manager object */
150
	setDefaults: function(settings) {
131
	setDefaults: function(settings) {
151
		extendRemove(this._defaults, settings || {});
132
		extendRemove(this._defaults, settings || {});
152
		return this;
133
		return this;
153
	},
134
	},
154
	
135
 
155
	/* Attach the date picker to a jQuery selection.
136
	/* Attach the date picker to a jQuery selection.
156
	   @param  target    element - the target input field or division or span
137
	   @param  target    element - the target input field or division or span
157
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
138
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
158
	_attachDatepicker: function(target, settings) {
139
	_attachDatepicker: function(target, settings) {
159
		// check for settings on the control itself - in namespace 'date:'
140
		// check for settings on the control itself - in namespace 'date:'
160
		var inlineSettings = null;
141
		var inlineSettings = null;
161
		for (attrName in this._defaults) {
142
		for (var attrName in this._defaults) {
162
			var attrValue = target.getAttribute('date:' + attrName);
143
			var attrValue = target.getAttribute('date:' + attrName);
163
			if (attrValue) {
144
			if (attrValue) {
164
				inlineSettings = inlineSettings || {};
145
				inlineSettings = inlineSettings || {};
165
				try {
146
				try {
166
					inlineSettings[attrName] = eval(attrValue);
147
					inlineSettings[attrName] = eval(attrValue);
167
				} catch (err) {
148
				} catch (err) {
168
					inlineSettings[attrName] = attrValue;
149
					inlineSettings[attrName] = attrValue;
169
				}
150
				}
170
			}
151
			}
171
		}
152
		}
172
		var nodeName = target.nodeName.toLowerCase();
153
		var nodeName = target.nodeName.toLowerCase();
173
		var inline = (nodeName == 'div' || nodeName == 'span');
154
		var inline = (nodeName == 'div' || nodeName == 'span');
174
		if (!target.id)
155
		if (!target.id) {
-
 
156
			this.uuid += 1;
175
			target.id = 'dp' + (++this.uuid);
157
			target.id = 'dp' + this.uuid;
-
 
158
		}
176
		var inst = this._newInst($(target), inline);
159
		var inst = this._newInst($(target), inline);
177
		inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 
160
		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
178
		if (nodeName == 'input') {
161
		if (nodeName == 'input') {
179
			this._connectDatepicker(target, inst);
162
			this._connectDatepicker(target, inst);
180
		} else if (inline) {
163
		} else if (inline) {
181
			this._inlineDatepicker(target, inst);
164
			this._inlineDatepicker(target, inst);
182
		}
165
		}
183
	},
166
	},
184
	
167
 
185
	/* Create a new instance object. */
168
	/* Create a new instance object. */
186
	_newInst: function(target, inline) {
169
	_newInst: function(target, inline) {
187
		var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
170
		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
188
		return {id: id, input: target, // associated target
171
		return {id: id, input: target, // associated target
189
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
172
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
190
			drawMonth: 0, drawYear: 0, // month being drawn
173
			drawMonth: 0, drawYear: 0, // month being drawn
191
			inline: inline, // is datepicker inline or not
174
			inline: inline, // is datepicker inline or not
192
			dpDiv: (!inline ? this.dpDiv : // presentation div
175
			dpDiv: (!inline ? this.dpDiv : // presentation div
193
			$('<div class="' + this._inlineClass + '"></div>'))};
176
			$('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
194
	},
177
	},
195
	
178
 
196
	/* Attach the date picker to an input field. */
179
	/* Attach the date picker to an input field. */
197
	_connectDatepicker: function(target, inst) {
180
	_connectDatepicker: function(target, inst) {
198
		var input = $(target);
181
		var input = $(target);
-
 
182
		inst.append = $([]);
-
 
183
		inst.trigger = $([]);
199
		if (input.hasClass(this.markerClassName))
184
		if (input.hasClass(this.markerClassName))
200
			return;
185
			return;
-
 
186
		this._attachments(input, inst);
-
 
187
		input.addClass(this.markerClassName).keydown(this._doKeyDown).
-
 
188
			keypress(this._doKeyPress).keyup(this._doKeyUp).
-
 
189
			bind("setData.datepicker", function(event, key, value) {
-
 
190
				inst.settings[key] = value;
-
 
191
			}).bind("getData.datepicker", function(event, key) {
-
 
192
				return this._get(inst, key);
-
 
193
			});
-
 
194
		this._autoSize(inst);
-
 
195
		$.data(target, PROP_NAME, inst);
-
 
196
	},
-
 
197
 
-
 
198
	/* Make attachments based on settings. */
-
 
199
	_attachments: function(input, inst) {
201
		var appendText = this._get(inst, 'appendText');
200
		var appendText = this._get(inst, 'appendText');
202
		var isRTL = this._get(inst, 'isRTL');
201
		var isRTL = this._get(inst, 'isRTL');
-
 
202
		if (inst.append)
-
 
203
			inst.append.remove();
203
		if (appendText)
204
		if (appendText) {
204
			input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
205
			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
-
 
206
			input[isRTL ? 'before' : 'after'](inst.append);
-
 
207
		}
-
 
208
		input.unbind('focus', this._showDatepicker);
-
 
209
		if (inst.trigger)
-
 
210
			inst.trigger.remove();
205
		var showOn = this._get(inst, 'showOn');
211
		var showOn = this._get(inst, 'showOn');
206
		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
212
		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
207
			input.focus(this._showDatepicker);
213
			input.focus(this._showDatepicker);
208
		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
214
		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
209
			var buttonText = this._get(inst, 'buttonText');
215
			var buttonText = this._get(inst, 'buttonText');
210
			var buttonImage = this._get(inst, 'buttonImage');
216
			var buttonImage = this._get(inst, 'buttonImage');
211
			var trigger = $(this._get(inst, 'buttonImageOnly') ? 
217
			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
212
				$('<img/>').addClass(this._triggerClass).
218
				$('<img/>').addClass(this._triggerClass).
213
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
219
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
214
				$('<button type="button"></button>').addClass(this._triggerClass).
220
				$('<button type="button"></button>').addClass(this._triggerClass).
215
					html(buttonImage == '' ? buttonText : $('<img/>').attr(
221
					html(buttonImage == '' ? buttonText : $('<img/>').attr(
216
					{ src:buttonImage, alt:buttonText, title:buttonText })));
222
					{ src:buttonImage, alt:buttonText, title:buttonText })));
217
			input[isRTL ? 'before' : 'after'](trigger);
223
			input[isRTL ? 'before' : 'after'](inst.trigger);
218
			trigger.click(function() {
224
			inst.trigger.click(function() {
219
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
225
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
220
					$.datepicker._hideDatepicker();
226
					$.datepicker._hideDatepicker();
221
				else
227
				else
222
					$.datepicker._showDatepicker(target);
228
					$.datepicker._showDatepicker(input[0]);
223
				return false;
229
				return false;
224
			});
230
			});
225
		}
231
		}
-
 
232
	},
-
 
233
 
226
		input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
234
	/* Apply the maximum length for the date format. */
-
 
235
	_autoSize: function(inst) {
227
			bind("setData.datepicker", function(event, key, value) {
236
		if (this._get(inst, 'autoSize') && !inst.inline) {
-
 
237
			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
-
 
238
			var dateFormat = this._get(inst, 'dateFormat');
228
				inst.settings[key] = value;
239
			if (dateFormat.match(/[DM]/)) {
229
			}).bind("getData.datepicker", function(event, key) {
240
				var findMax = function(names) {
-
 
241
					var max = 0;
-
 
242
					var maxI = 0;
-
 
243
					for (var i = 0; i < names.length; i++) {
-
 
244
						if (names[i].length > max) {
230
				return this._get(inst, key);
245
							max = names[i].length;
-
 
246
							maxI = i;
-
 
247
						}
-
 
248
					}
-
 
249
					return maxI;
231
			});
250
				};
-
 
251
				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
232
		$.data(target, PROP_NAME, inst);
252
					'monthNames' : 'monthNamesShort'))));
-
 
253
				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
-
 
254
					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
-
 
255
			}
-
 
256
			inst.input.attr('size', this._formatDate(inst, date).length);
-
 
257
		}
233
	},
258
	},
234
	
259
 
235
	/* Attach an inline date picker to a div. */
260
	/* Attach an inline date picker to a div. */
236
	_inlineDatepicker: function(target, inst) {
261
	_inlineDatepicker: function(target, inst) {
237
		var divSpan = $(target);
262
		var divSpan = $(target);
238
		if (divSpan.hasClass(this.markerClassName))
263
		if (divSpan.hasClass(this.markerClassName))
239
			return;
264
			return;
240
		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
265
		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
241
			bind("setData.datepicker", function(event, key, value){
266
			bind("setData.datepicker", function(event, key, value){
242
				inst.settings[key] = value;
267
				inst.settings[key] = value;
243
			}).bind("getData.datepicker", function(event, key){
268
			}).bind("getData.datepicker", function(event, key){
244
				return this._get(inst, key);
269
				return this._get(inst, key);
245
			});
270
			});
246
		$.data(target, PROP_NAME, inst);
271
		$.data(target, PROP_NAME, inst);
247
		this._setDate(inst, this._getDefaultDate(inst));
272
		this._setDate(inst, this._getDefaultDate(inst), true);
248
		this._updateDatepicker(inst);
273
		this._updateDatepicker(inst);
249
	},
-
 
250
	
-
 
251
	/* Tidy up after displaying the date picker. */
-
 
252
	_inlineShow: function(inst) {
274
		this._updateAlternate(inst);
253
		var numMonths = this._getNumberOfMonths(inst); // fix width for dynamic number of date pickers
-
 
254
		inst.dpDiv.width(numMonths[1] * $('.ui-datepicker', inst.dpDiv[0]).width());
-
 
255
	},
275
	},
256
	
276
 
257
	/* Pop-up the date picker in a "dialog" box.
277
	/* Pop-up the date picker in a "dialog" box.
258
	   @param  input     element - ignored
278
	   @param  input     element - ignored
259
	   @param  dateText  string - the initial date to display (in the current format)
279
	   @param  date      string or Date - the initial date to display
260
	   @param  onSelect  function - the function(dateText) to call when a date is selected
280
	   @param  onSelect  function - the function to call when a date is selected
261
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
281
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
262
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
282
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
263
	                     event - with x/y coordinates or
283
	                     event - with x/y coordinates or
264
	                     leave empty for default (screen centre)
284
	                     leave empty for default (screen centre)
265
	   @return the manager object */
285
	   @return the manager object */
266
	_dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
286
	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
267
		var inst = this._dialogInst; // internal instance
287
		var inst = this._dialogInst; // internal instance
268
		if (!inst) {
288
		if (!inst) {
-
 
289
			this.uuid += 1;
269
			var id = 'dp' + (++this.uuid);
290
			var id = 'dp' + this.uuid;
270
			this._dialogInput = $('<input type="text" id="' + id +
291
			this._dialogInput = $('<input type="text" id="' + id +
271
				'" size="1" style="position: absolute; top: -100px;"/>');
292
				'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
272
			this._dialogInput.keydown(this._doKeyDown);
293
			this._dialogInput.keydown(this._doKeyDown);
273
			$('body').append(this._dialogInput);
294
			$('body').append(this._dialogInput);
274
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
295
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
275
			inst.settings = {};
296
			inst.settings = {};
276
			$.data(this._dialogInput[0], PROP_NAME, inst);
297
			$.data(this._dialogInput[0], PROP_NAME, inst);
277
		}
298
		}
278
		extendRemove(inst.settings, settings || {});
299
		extendRemove(inst.settings, settings || {});
-
 
300
		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
279
		this._dialogInput.val(dateText);
301
		this._dialogInput.val(date);
280
		
302
 
281
		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
303
		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
282
		if (!this._pos) {
304
		if (!this._pos) {
283
			var browserWidth = window.innerWidth || document.documentElement.clientWidth ||	document.body.clientWidth;
305
			var browserWidth = document.documentElement.clientWidth;
284
			var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
306
			var browserHeight = document.documentElement.clientHeight;
285
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
307
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
286
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
308
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
287
			this._pos = // should use actual width/height below
309
			this._pos = // should use actual width/height below
288
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
310
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
289
		}
311
		}
290
		
312
 
291
		// move input on screen for focus, but hidden behind dialog
313
		// move input on screen for focus, but hidden behind dialog
292
		this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
314
		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
293
		inst.settings.onSelect = onSelect;
315
		inst.settings.onSelect = onSelect;
294
		this._inDialog = true;
316
		this._inDialog = true;
295
		this.dpDiv.addClass(this._dialogClass);
317
		this.dpDiv.addClass(this._dialogClass);
296
		this._showDatepicker(this._dialogInput[0]);
318
		this._showDatepicker(this._dialogInput[0]);
297
		if ($.blockUI)
319
		if ($.blockUI)
298
			$.blockUI(this.dpDiv);
320
			$.blockUI(this.dpDiv);
299
		$.data(this._dialogInput[0], PROP_NAME, inst);
321
		$.data(this._dialogInput[0], PROP_NAME, inst);
300
		return this;
322
		return this;
301
	},
323
	},
302
	
324
 
303
	/* Detach a datepicker from its control.
325
	/* Detach a datepicker from its control.
304
	   @param  target    element - the target input field or division or span */
326
	   @param  target    element - the target input field or division or span */
305
	_destroyDatepicker: function(target) {
327
	_destroyDatepicker: function(target) {
306
		var $target = $(target);
328
		var $target = $(target);
-
 
329
		var inst = $.data(target, PROP_NAME);
307
		if (!$target.hasClass(this.markerClassName)) {
330
		if (!$target.hasClass(this.markerClassName)) {
308
			return;
331
			return;
309
		}
332
		}
310
		var nodeName = target.nodeName.toLowerCase();
333
		var nodeName = target.nodeName.toLowerCase();
311
		$.removeData(target, PROP_NAME);
334
		$.removeData(target, PROP_NAME);
312
		if (nodeName == 'input') {
335
		if (nodeName == 'input') {
313
			$target.siblings('.' + this._appendClass).remove().end().
336
			inst.append.remove();
314
				siblings('.' + this._triggerClass).remove().end().
337
			inst.trigger.remove();
315
				removeClass(this.markerClassName).
338
			$target.removeClass(this.markerClassName).
316
				unbind('focus', this._showDatepicker).
339
				unbind('focus', this._showDatepicker).
317
				unbind('keydown', this._doKeyDown).
340
				unbind('keydown', this._doKeyDown).
318
				unbind('keypress', this._doKeyPress);
341
				unbind('keypress', this._doKeyPress).
-
 
342
				unbind('keyup', this._doKeyUp);
319
		} else if (nodeName == 'div' || nodeName == 'span')
343
		} else if (nodeName == 'div' || nodeName == 'span')
320
			$target.removeClass(this.markerClassName).empty();
344
			$target.removeClass(this.markerClassName).empty();
321
	},
345
	},
322
	
346
 
323
	/* Enable the date picker to a jQuery selection.
347
	/* Enable the date picker to a jQuery selection.
324
	   @param  target    element - the target input field or division or span */
348
	   @param  target    element - the target input field or division or span */
325
	_enableDatepicker: function(target) {
349
	_enableDatepicker: function(target) {
326
		var $target = $(target);
350
		var $target = $(target);
-
 
351
		var inst = $.data(target, PROP_NAME);
327
		if (!$target.hasClass(this.markerClassName)) {
352
		if (!$target.hasClass(this.markerClassName)) {
328
			return;
353
			return;
329
		}
354
		}
330
		var nodeName = target.nodeName.toLowerCase();
355
		var nodeName = target.nodeName.toLowerCase();
331
		if (nodeName == 'input') {
356
		if (nodeName == 'input') {
332
		target.disabled = false;
357
			target.disabled = false;
333
			$target.siblings('button.' + this._triggerClass).
358
			inst.trigger.filter('button').
334
			each(function() { this.disabled = false; }).end().
359
				each(function() { this.disabled = false; }).end().
335
				siblings('img.' + this._triggerClass).
-
 
336
				css({opacity: '1.0', cursor: ''});
360
				filter('img').css({opacity: '1.0', cursor: ''});
337
		}
361
		}
338
		else if (nodeName == 'div' || nodeName == 'span') {
362
		else if (nodeName == 'div' || nodeName == 'span') {
339
			$target.children('.' + this._disableClass).remove();
363
			var inline = $target.children('.' + this._inlineClass);
-
 
364
			inline.children().removeClass('ui-state-disabled');
340
		}
365
		}
341
		this._disabledInputs = $.map(this._disabledInputs,
366
		this._disabledInputs = $.map(this._disabledInputs,
342
			function(value) { return (value == target ? null : value); }); // delete entry
367
			function(value) { return (value == target ? null : value); }); // delete entry
343
	},
368
	},
344
	
369
 
345
	/* Disable the date picker to a jQuery selection.
370
	/* Disable the date picker to a jQuery selection.
346
	   @param  target    element - the target input field or division or span */
371
	   @param  target    element - the target input field or division or span */
347
	_disableDatepicker: function(target) {
372
	_disableDatepicker: function(target) {
348
		var $target = $(target);
373
		var $target = $(target);
-
 
374
		var inst = $.data(target, PROP_NAME);
349
		if (!$target.hasClass(this.markerClassName)) {
375
		if (!$target.hasClass(this.markerClassName)) {
350
			return;
376
			return;
351
		}
377
		}
352
		var nodeName = target.nodeName.toLowerCase();
378
		var nodeName = target.nodeName.toLowerCase();
353
		if (nodeName == 'input') {
379
		if (nodeName == 'input') {
354
		target.disabled = true;
380
			target.disabled = true;
355
			$target.siblings('button.' + this._triggerClass).
381
			inst.trigger.filter('button').
356
			each(function() { this.disabled = true; }).end().
382
				each(function() { this.disabled = true; }).end().
357
				siblings('img.' + this._triggerClass).
-
 
358
				css({opacity: '0.5', cursor: 'default'});
383
				filter('img').css({opacity: '0.5', cursor: 'default'});
359
		}
384
		}
360
		else if (nodeName == 'div' || nodeName == 'span') {
385
		else if (nodeName == 'div' || nodeName == 'span') {
361
			var inline = $target.children('.' + this._inlineClass);
386
			var inline = $target.children('.' + this._inlineClass);
362
			var offset = inline.offset();
-
 
363
			var relOffset = {left: 0, top: 0};
-
 
364
			inline.parents().each(function() {
387
			inline.children().addClass('ui-state-disabled');
365
				if ($(this).css('position') == 'relative') {
-
 
366
					relOffset = $(this).offset();
-
 
367
					return false;
-
 
368
				}
-
 
369
			});
-
 
370
			$target.prepend('<div class="' + this._disableClass + '" style="' +
-
 
371
				($.browser.msie ? 'background-color: transparent; ' : '') +
-
 
372
				'width: ' + inline.width() + 'px; height: ' + inline.height() +
-
 
373
				'px; left: ' + (offset.left - relOffset.left) +
-
 
374
				'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
-
 
375
		}
388
		}
376
		this._disabledInputs = $.map(this._disabledInputs,
389
		this._disabledInputs = $.map(this._disabledInputs,
377
			function(value) { return (value == target ? null : value); }); // delete entry
390
			function(value) { return (value == target ? null : value); }); // delete entry
378
		this._disabledInputs[this._disabledInputs.length] = target;
391
		this._disabledInputs[this._disabledInputs.length] = target;
379
	},
392
	},
380
	
393
 
381
	/* Is the first field in a jQuery collection disabled as a datepicker?
394
	/* Is the first field in a jQuery collection disabled as a datepicker?
382
	   @param  target    element - the target input field or division or span
395
	   @param  target    element - the target input field or division or span
383
	   @return boolean - true if disabled, false if enabled */
396
	   @return boolean - true if disabled, false if enabled */
384
	_isDisabledDatepicker: function(target) {
397
	_isDisabledDatepicker: function(target) {
385
		if (!target)
398
		if (!target) {
386
			return false;
399
			return false;
-
 
400
		}
387
		for (var i = 0; i < this._disabledInputs.length; i++) {
401
		for (var i = 0; i < this._disabledInputs.length; i++) {
388
			if (this._disabledInputs[i] == target)
402
			if (this._disabledInputs[i] == target)
389
				return true;
403
				return true;
390
		}
404
		}
391
		return false;
405
		return false;
392
	},
406
	},
393
	
407
 
394
	/* Retrieve the instance data for the target control.
408
	/* Retrieve the instance data for the target control.
395
	   @param  target  element - the target input field or division or span
409
	   @param  target  element - the target input field or division or span
396
	   @return  object - the associated instance data
410
	   @return  object - the associated instance data
397
	   @throws  error if a jQuery problem getting data */
411
	   @throws  error if a jQuery problem getting data */
398
	_getInst: function(target) {
412
	_getInst: function(target) {
399
		try {
413
		try {
400
			return $.data(target, PROP_NAME);
414
			return $.data(target, PROP_NAME);
401
		}
415
		}
402
		catch (err) {
416
		catch (err) {
403
			throw 'Missing instance data for this datepicker';
417
			throw 'Missing instance data for this datepicker';
404
		}
418
		}
405
	},
419
	},
406
	
420
 
407
	/* Update the settings for a date picker attached to an input field or division.
421
	/* Update or retrieve the settings for a date picker attached to an input field or division.
408
	   @param  target  element - the target input field or division or span
422
	   @param  target  element - the target input field or division or span
409
	   @param  name    object - the new settings to update or
423
	   @param  name    object - the new settings to update or
-
 
424
	                   string - the name of the setting to change or retrieve,
-
 
425
	                   when retrieving also 'all' for all instance settings or
410
	                   string - the name of the setting to change or
426
	                   'defaults' for all global defaults
-
 
427
	   @param  value   any - the new value for the setting
411
	   @param  value   any - the new value for the setting (omit if above is an object) */
428
	                   (omit if above is an object or to retrieve a value) */
-
 
429
	_optionDatepicker: function(target, name, value) {
-
 
430
		var inst = this._getInst(target);
-
 
431
		if (arguments.length == 2 && typeof name == 'string') {
-
 
432
			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
-
 
433
				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
-
 
434
				this._get(inst, name)) : null));
412
	_optionDatepicker: function(target, name, value) {
435
		}
413
		var settings = name || {};
436
		var settings = name || {};
414
		if (typeof name == 'string') {
437
		if (typeof name == 'string') {
415
			settings = {};
438
			settings = {};
416
			settings[name] = value;
439
			settings[name] = value;
417
		}
440
		}
418
		var inst = this._getInst(target);
-
 
419
		if (inst) {
441
		if (inst) {
420
			if (this._curInst == inst) {
442
			if (this._curInst == inst) {
421
				this._hideDatepicker(null);
443
				this._hideDatepicker();
422
			}
444
			}
-
 
445
			var date = this._getDateDatepicker(target, true);
423
			extendRemove(inst.settings, settings);
446
			extendRemove(inst.settings, settings);
424
			var date = new Date();
447
			this._attachments($(target), inst);
425
			extendRemove(inst, {rangeStart: null, // start of range
-
 
426
				endDay: null, endMonth: null, endYear: null, // end of range
-
 
427
				selectedDay: date.getDate(), selectedMonth: date.getMonth(),
-
 
428
				selectedYear: date.getFullYear(), // starting point
448
			this._autoSize(inst);
429
				currentDay: date.getDate(), currentMonth: date.getMonth(),
449
			this._setDateDatepicker(target, date);
430
				currentYear: date.getFullYear(), // current selection
-
 
431
				drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn
-
 
432
			this._updateDatepicker(inst);
450
			this._updateDatepicker(inst);
433
		}
451
		}
434
	},
452
	},
435
	
453
 
436
	// change method deprecated
454
	// change method deprecated
437
	_changeDatepicker: function(target, name, value) {
455
	_changeDatepicker: function(target, name, value) {
438
		this._optionDatepicker(target, name, value);
456
		this._optionDatepicker(target, name, value);
439
	},
457
	},
440
	
458
 
441
	/* Redraw the date picker attached to an input field or division.
459
	/* Redraw the date picker attached to an input field or division.
442
	   @param  target  element - the target input field or division or span */
460
	   @param  target  element - the target input field or division or span */
443
	_refreshDatepicker: function(target) {
461
	_refreshDatepicker: function(target) {
444
		var inst = this._getInst(target);
462
		var inst = this._getInst(target);
445
		if (inst) {
463
		if (inst) {
446
			this._updateDatepicker(inst);
464
			this._updateDatepicker(inst);
447
		}
465
		}
448
	},
466
	},
449
	
467
 
450
	/* Set the dates for a jQuery selection.
468
	/* Set the dates for a jQuery selection.
451
	   @param  target   element - the target input field or division or span
469
	   @param  target   element - the target input field or division or span
452
	   @param  date     Date - the new date
470
	   @param  date     Date - the new date */
453
	   @param  endDate  Date - the new end date for a range (optional) */
-
 
454
	_setDateDatepicker: function(target, date, endDate) {
471
	_setDateDatepicker: function(target, date) {
455
		var inst = this._getInst(target);
472
		var inst = this._getInst(target);
456
		if (inst) {
473
		if (inst) {
457
			this._setDate(inst, date, endDate);
474
			this._setDate(inst, date);
458
			this._updateDatepicker(inst);
475
			this._updateDatepicker(inst);
459
			this._updateAlternate(inst);
476
			this._updateAlternate(inst);
460
		}
477
		}
461
	},
478
	},
462
	
479
 
463
	/* Get the date(s) for the first entry in a jQuery selection.
480
	/* Get the date(s) for the first entry in a jQuery selection.
464
	   @param  target  element - the target input field or division or span
481
	   @param  target     element - the target input field or division or span
465
	   @return Date - the current date or
482
	   @param  noDefault  boolean - true if no default date is to be used
466
	           Date[2] - the current dates for a range */
483
	   @return Date - the current date */
467
	_getDateDatepicker: function(target) {
484
	_getDateDatepicker: function(target, noDefault) {
468
		var inst = this._getInst(target);
485
		var inst = this._getInst(target);
469
		if (inst && !inst.inline)
486
		if (inst && !inst.inline)
470
			this._setDateFromField(inst); 
487
			this._setDateFromField(inst, noDefault);
471
		return (inst ? this._getDate(inst) : null);
488
		return (inst ? this._getDate(inst) : null);
472
	},
489
	},
473
	
490
 
474
	/* Handle keystrokes. */
491
	/* Handle keystrokes. */
475
	_doKeyDown: function(e) {
492
	_doKeyDown: function(event) {
476
		var inst = $.datepicker._getInst(e.target);
493
		var inst = $.datepicker._getInst(event.target);
477
		var handled = true;
494
		var handled = true;
-
 
495
		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
478
		inst._keyEvent = true;
496
		inst._keyEvent = true;
479
		if ($.datepicker._datepickerShowing)
497
		if ($.datepicker._datepickerShowing)
480
			switch (e.keyCode) {
498
			switch (event.keyCode) {
481
				case 9:  $.datepicker._hideDatepicker(null, '');
499
				case 9: $.datepicker._hideDatepicker();
-
 
500
						handled = false;
482
						break; // hide on tab out
501
						break; // hide on tab out
483
				case 13: var sel = $('td.' + $.datepicker._dayOverClass +
502
				case 13: var sel = $('td.' + $.datepicker._dayOverClass, inst.dpDiv).
484
							', td.' + $.datepicker._currentClass, inst.dpDiv);
503
							add($('td.' + $.datepicker._currentClass, inst.dpDiv));
485
						if (sel[0])
504
						if (sel[0])
486
							$.datepicker._selectDay(e.target, inst.selectedMonth, inst.selectedYear, sel[0]);
505
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
487
						else
506
						else
488
							$.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
507
							$.datepicker._hideDatepicker();
489
						return false; // don't submit the form
508
						return false; // don't submit the form
490
						break; // select the value on enter
509
						break; // select the value on enter
491
				case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
510
				case 27: $.datepicker._hideDatepicker();
492
						break; // hide on escape
511
						break; // hide on escape
493
				case 33: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
512
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
494
							-$.datepicker._get(inst, 'stepBigMonths') :
513
							-$.datepicker._get(inst, 'stepBigMonths') :
495
							-$.datepicker._get(inst, 'stepMonths')), 'M');
514
							-$.datepicker._get(inst, 'stepMonths')), 'M');
496
						break; // previous month/year on page up/+ ctrl
515
						break; // previous month/year on page up/+ ctrl
497
				case 34: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
516
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
498
							+$.datepicker._get(inst, 'stepBigMonths') :
517
							+$.datepicker._get(inst, 'stepBigMonths') :
499
							+$.datepicker._get(inst, 'stepMonths')), 'M');
518
							+$.datepicker._get(inst, 'stepMonths')), 'M');
500
						break; // next month/year on page down/+ ctrl
519
						break; // next month/year on page down/+ ctrl
501
				case 35: if (e.ctrlKey || e.metaKey) $.datepicker._clearDate(e.target);
520
				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
502
						handled = e.ctrlKey || e.metaKey;
521
						handled = event.ctrlKey || event.metaKey;
503
						break; // clear on ctrl or command +end 
522
						break; // clear on ctrl or command +end
504
				case 36: if (e.ctrlKey || e.metaKey) $.datepicker._gotoToday(e.target);
523
				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
505
						handled = e.ctrlKey || e.metaKey;
524
						handled = event.ctrlKey || event.metaKey;
506
						break; // current on ctrl or command +home
525
						break; // current on ctrl or command +home
507
				case 37: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, -1, 'D');
526
				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
508
						handled = e.ctrlKey || e.metaKey;
527
						handled = event.ctrlKey || event.metaKey;
509
						// -1 day on ctrl or command +left
528
						// -1 day on ctrl or command +left
510
						if (e.originalEvent.altKey) $.datepicker._adjustDate(e.target, (e.ctrlKey ?
529
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
511
									-$.datepicker._get(inst, 'stepBigMonths') :
530
									-$.datepicker._get(inst, 'stepBigMonths') :
512
									-$.datepicker._get(inst, 'stepMonths')), 'M');
531
									-$.datepicker._get(inst, 'stepMonths')), 'M');
513
						// next month/year on alt +left on Mac
532
						// next month/year on alt +left on Mac
514
						break; 
533
						break;
515
				case 38: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, -7, 'D');
534
				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
516
						handled = e.ctrlKey || e.metaKey;
535
						handled = event.ctrlKey || event.metaKey;
517
						break; // -1 week on ctrl or command +up
536
						break; // -1 week on ctrl or command +up
518
				case 39: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, +1, 'D');
537
				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
519
						handled = e.ctrlKey || e.metaKey;
538
						handled = event.ctrlKey || event.metaKey;
520
						// +1 day on ctrl or command +right
539
						// +1 day on ctrl or command +right
521
						if (e.originalEvent.altKey) $.datepicker._adjustDate(e.target, (e.ctrlKey ?
540
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
522
									+$.datepicker._get(inst, 'stepBigMonths') :
541
									+$.datepicker._get(inst, 'stepBigMonths') :
523
									+$.datepicker._get(inst, 'stepMonths')), 'M');
542
									+$.datepicker._get(inst, 'stepMonths')), 'M');
524
						// next month/year on alt +right
543
						// next month/year on alt +right
525
						break; 
544
						break;
526
				case 40: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, +7, 'D');
545
				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
527
						handled = e.ctrlKey || e.metaKey;
546
						handled = event.ctrlKey || event.metaKey;
528
						break; // +1 week on ctrl or command +down
547
						break; // +1 week on ctrl or command +down
529
				default: handled = false;
548
				default: handled = false;
530
			}
549
			}
531
		else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
550
		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
532
			$.datepicker._showDatepicker(this);
551
			$.datepicker._showDatepicker(this);
533
		else {
552
		else {
534
			handled = false;
553
			handled = false;
535
		}
554
		}
536
		if (handled) {
555
		if (handled) {
537
			e.preventDefault();
556
			event.preventDefault();
538
			e.stopPropagation();
557
			event.stopPropagation();
539
		}
558
		}
540
	},
559
	},
541
	
560
 
542
	/* Filter entered characters - based on date format. */
561
	/* Filter entered characters - based on date format. */
543
	_doKeyPress: function(e) {
562
	_doKeyPress: function(event) {
544
		var inst = $.datepicker._getInst(e.target);
563
		var inst = $.datepicker._getInst(event.target);
545
		if ($.datepicker._get(inst, 'constrainInput')) {
564
		if ($.datepicker._get(inst, 'constrainInput')) {
546
			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
565
			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
547
			var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
566
			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
548
			return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
567
			return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
549
		}
568
		}
550
	},
569
	},
-
 
570
 
-
 
571
	/* Synchronise manual entry and field/alternate field. */
-
 
572
	_doKeyUp: function(event) {
-
 
573
		var inst = $.datepicker._getInst(event.target);
-
 
574
		if (inst.input.val() != inst.lastVal) {
-
 
575
			try {
-
 
576
				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
-
 
577
					(inst.input ? inst.input.val() : null),
-
 
578
					$.datepicker._getFormatConfig(inst));
-
 
579
				if (date) { // only if valid
-
 
580
					$.datepicker._setDateFromField(inst);
-
 
581
					$.datepicker._updateAlternate(inst);
-
 
582
					$.datepicker._updateDatepicker(inst);
-
 
583
				}
-
 
584
			}
-
 
585
			catch (event) {
-
 
586
				$.datepicker.log(event);
-
 
587
			}
-
 
588
		}
-
 
589
		return true;
-
 
590
	},
551
	
591
 
552
	/* Pop-up the date picker for a given input field.
592
	/* Pop-up the date picker for a given input field.
553
	   @param  input  element - the input field attached to the date picker or
593
	   @param  input  element - the input field attached to the date picker or
554
	                  event - if triggered by focus */
594
	                  event - if triggered by focus */
555
	_showDatepicker: function(input) {
595
	_showDatepicker: function(input) {
556
		input = input.target || input;
596
		input = input.target || input;
557
		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
597
		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
558
			input = $('input', input.parentNode)[0];
598
			input = $('input', input.parentNode)[0];
559
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
599
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
560
			return;
600
			return;
561
		var inst = $.datepicker._getInst(input);
601
		var inst = $.datepicker._getInst(input);
-
 
602
		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
-
 
603
			$.datepicker._curInst.dpDiv.stop(true, true);
-
 
604
		}
562
		var beforeShow = $.datepicker._get(inst, 'beforeShow');
605
		var beforeShow = $.datepicker._get(inst, 'beforeShow');
563
		extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
606
		extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
564
		$.datepicker._hideDatepicker(null, '');
607
		inst.lastVal = null;
565
		$.datepicker._lastInput = input;
608
		$.datepicker._lastInput = input;
566
		$.datepicker._setDateFromField(inst);
609
		$.datepicker._setDateFromField(inst);
567
		if ($.datepicker._inDialog) // hide cursor
610
		if ($.datepicker._inDialog) // hide cursor
568
			input.value = '';
611
			input.value = '';
569
		if (!$.datepicker._pos) { // position below input
612
		if (!$.datepicker._pos) { // position below input
570
			$.datepicker._pos = $.datepicker._findPos(input);
613
			$.datepicker._pos = $.datepicker._findPos(input);
571
			$.datepicker._pos[1] += input.offsetHeight; // add the height
614
			$.datepicker._pos[1] += input.offsetHeight; // add the height
572
		}
615
		}
573
		var isFixed = false;
616
		var isFixed = false;
574
		$(input).parents().each(function() {
617
		$(input).parents().each(function() {
575
			isFixed |= $(this).css('position') == 'fixed';
618
			isFixed |= $(this).css('position') == 'fixed';
576
			return !isFixed;
619
			return !isFixed;
577
		});
620
		});
578
		if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
621
		if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
579
			$.datepicker._pos[0] -= document.documentElement.scrollLeft;
622
			$.datepicker._pos[0] -= document.documentElement.scrollLeft;
580
			$.datepicker._pos[1] -= document.documentElement.scrollTop;
623
			$.datepicker._pos[1] -= document.documentElement.scrollTop;
581
		}
624
		}
582
		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
625
		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
583
		$.datepicker._pos = null;
626
		$.datepicker._pos = null;
584
		inst.rangeStart = null;
-
 
585
		// determine sizing offscreen
627
		// determine sizing offscreen
586
		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
628
		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
587
		$.datepicker._updateDatepicker(inst);
629
		$.datepicker._updateDatepicker(inst);
588
		// fix width for dynamic number of date pickers
630
		// fix width for dynamic number of date pickers
589
		inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] *
-
 
590
			$('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth);
-
 
591
		// and adjust position before showing
631
		// and adjust position before showing
592
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
632
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
593
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
633
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
594
			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
634
			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
595
			left: offset.left + 'px', top: offset.top + 'px'});
635
			left: offset.left + 'px', top: offset.top + 'px'});
596
		if (!inst.inline) {
636
		if (!inst.inline) {
597
			var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
637
			var showAnim = $.datepicker._get(inst, 'showAnim');
598
			var duration = $.datepicker._get(inst, 'duration');
638
			var duration = $.datepicker._get(inst, 'duration');
599
			var postProcess = function() {
639
			var postProcess = function() {
600
				$.datepicker._datepickerShowing = true;
640
				$.datepicker._datepickerShowing = true;
601
				if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
641
				var borders = $.datepicker._getBorders(inst.dpDiv);
602
					$('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
642
				inst.dpDiv.find('iframe.ui-datepicker-cover'). // IE6- only
-
 
643
					css({left: -borders[0], top: -borders[1],
603
						height: inst.dpDiv.height() + 4});
644
						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
604
			};
645
			};
-
 
646
			inst.dpDiv.zIndex($(input).zIndex()+1);
605
			if ($.effects && $.effects[showAnim])
647
			if ($.effects && $.effects[showAnim])
606
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
648
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
607
			else
649
			else
608
				inst.dpDiv[showAnim](duration, postProcess);
650
				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
609
			if (duration == '')
651
			if (!showAnim || !duration)
610
				postProcess();
652
				postProcess();
611
			if (inst.input[0].type != 'hidden')
653
			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
612
				inst.input[0].focus();
654
				inst.input.focus();
613
			$.datepicker._curInst = inst;
655
			$.datepicker._curInst = inst;
614
		}
656
		}
615
	},
657
	},
616
	
658
 
617
	/* Generate the date picker content. */
659
	/* Generate the date picker content. */
618
	_updateDatepicker: function(inst) {
660
	_updateDatepicker: function(inst) {
619
		var dims = {width: inst.dpDiv.width() + 4,
661
		var self = this;
620
			height: inst.dpDiv.height() + 4};
662
		var borders = $.datepicker._getBorders(inst.dpDiv);
621
		inst.dpDiv.empty().append(this._generateHTML(inst)).
663
		inst.dpDiv.empty().append(this._generateHTML(inst))
622
			find('iframe.ui-datepicker-cover').
664
			.find('iframe.ui-datepicker-cover') // IE6- only
-
 
665
				.css({left: -borders[0], top: -borders[1],
623
			css({width: dims.width, height: dims.height});
666
					width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
-
 
667
			.end()
-
 
668
			.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
-
 
669
				.bind('mouseout', function(){
-
 
670
					$(this).removeClass('ui-state-hover');
-
 
671
					if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
-
 
672
					if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
-
 
673
				})
-
 
674
				.bind('mouseover', function(){
-
 
675
					if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
-
 
676
						$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
-
 
677
						$(this).addClass('ui-state-hover');
-
 
678
						if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
-
 
679
						if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
-
 
680
					}
-
 
681
				})
-
 
682
			.end()
-
 
683
			.find('.' + this._dayOverClass + ' a')
-
 
684
				.trigger('mouseover')
-
 
685
			.end();
624
		var numMonths = this._getNumberOfMonths(inst);
686
		var numMonths = this._getNumberOfMonths(inst);
-
 
687
		var cols = numMonths[1];
-
 
688
		var width = 17;
-
 
689
		if (cols > 1)
-
 
690
			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
-
 
691
		else
-
 
692
			inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
625
		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
693
		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
626
			'Class']('ui-datepicker-multi');
694
			'Class']('ui-datepicker-multi');
627
		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
695
		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
628
			'Class']('ui-datepicker-rtl');
696
			'Class']('ui-datepicker-rtl');
629
		if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
697
		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
-
 
698
				inst.input.is(':visible') && !inst.input.is(':disabled'))
630
			$(inst.input[0]).focus();
699
			inst.input.focus();
-
 
700
	},
-
 
701
 
-
 
702
	/* Retrieve the size of left and top borders for an element.
-
 
703
	   @param  elem  (jQuery object) the element of interest
-
 
704
	   @return  (number[2]) the left and top borders */
-
 
705
	_getBorders: function(elem) {
-
 
706
		var convert = function(value) {
-
 
707
			return {thin: 1, medium: 2, thick: 3}[value] || value;
-
 
708
		};
-
 
709
		return [parseFloat(convert(elem.css('border-left-width'))),
-
 
710
			parseFloat(convert(elem.css('border-top-width')))];
631
	},
711
	},
632
	
712
 
633
	/* Check positioning to remain on screen. */
713
	/* Check positioning to remain on screen. */
634
	_checkOffset: function(inst, offset, isFixed) {
714
	_checkOffset: function(inst, offset, isFixed) {
635
		var pos = inst.input ? this._findPos(inst.input[0]) : null;
715
		var dpWidth = inst.dpDiv.outerWidth();
636
		var browserWidth = window.innerWidth || (document.documentElement ?
716
		var dpHeight = inst.dpDiv.outerHeight();
637
			document.documentElement.clientWidth : document.body.clientWidth); 
717
		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
638
		var browserHeight = window.innerHeight || (document.documentElement ?
718
		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
639
			document.documentElement.clientHeight : document.body.clientHeight);
-
 
640
		var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
719
		var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
641
		var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
720
		var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
642
		// reposition date picker horizontally if outside the browser window
-
 
-
 
721
 
643
		if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth)
722
		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
644
			offset.left = Math.max((isFixed ? 0 : scrollX),
-
 
645
				pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() -
723
		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
646
				(isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0));
724
		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
647
		else
725
 
648
			offset.left -= (isFixed ? scrollX : 0);
-
 
649
		// reposition date picker vertically if outside the browser window
726
		// now check if datepicker is showing outside window viewport - move to a better place if so.
650
		if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight)
727
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
651
			offset.top = Math.max((isFixed ? 0 : scrollY),
728
			Math.abs(offset.left + dpWidth - viewWidth) : 0);
652
				pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) -
729
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
653
				(isFixed && $.browser.opera ? document.documentElement.scrollTop : 0));
730
			Math.abs(dpHeight + inputHeight) : 0);
654
		else
731
 
655
			offset.top -= (isFixed ? scrollY : 0);
-
 
656
		return offset;
732
		return offset;
657
	},
733
	},
658
	
734
 
659
	/* Find an object's position on the screen. */
735
	/* Find an object's position on the screen. */
660
	_findPos: function(obj) {
736
	_findPos: function(obj) {
-
 
737
		var inst = this._getInst(obj);
-
 
738
		var isRTL = this._get(inst, 'isRTL');
661
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
739
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
662
            obj = obj.nextSibling;
740
            obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
663
        }
741
        }
664
        var position = $(obj).offset();
742
        var position = $(obj).offset();
665
	    return [position.left, position.top];
743
	    return [position.left, position.top];
666
	},
744
	},
667
	
745
 
668
	/* Hide the date picker from view.
746
	/* Hide the date picker from view.
669
	   @param  input  element - the input field attached to the date picker
747
	   @param  input  element - the input field attached to the date picker */
670
	   @param  duration  string - the duration over which to close the date picker */
-
 
671
	_hideDatepicker: function(input, duration) {
748
	_hideDatepicker: function(input) {
672
		var inst = this._curInst;
749
		var inst = this._curInst;
673
		if (!inst || (input && inst != $.data(input, PROP_NAME)))
750
		if (!inst || (input && inst != $.data(input, PROP_NAME)))
674
			return;
751
			return;
675
		var rangeSelect = this._get(inst, 'rangeSelect');
-
 
676
		if (rangeSelect && inst.stayOpen)
-
 
677
			this._selectDate('#' + inst.id, this._formatDate(inst,
-
 
678
				inst.currentDay, inst.currentMonth, inst.currentYear));
-
 
679
		inst.stayOpen = false;
-
 
680
		if (this._datepickerShowing) {
752
		if (this._datepickerShowing) {
681
			duration = (duration != null ? duration : this._get(inst, 'duration'));
-
 
682
			var showAnim = this._get(inst, 'showAnim');
753
			var showAnim = this._get(inst, 'showAnim');
-
 
754
			var duration = this._get(inst, 'duration');
683
			var postProcess = function() {
755
			var postProcess = function() {
684
				$.datepicker._tidyDialog(inst);
756
				$.datepicker._tidyDialog(inst);
-
 
757
				this._curInst = null;
685
			};
758
			};
686
			if (duration != '' && $.effects && $.effects[showAnim])
759
			if ($.effects && $.effects[showAnim])
687
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
760
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
688
					duration, postProcess);
-
 
689
			else
761
			else
690
				inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
762
				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
691
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
763
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
692
			if (duration == '')
764
			if (!showAnim)
693
				this._tidyDialog(inst);
765
				postProcess();
694
			var onClose = this._get(inst, 'onClose');
766
			var onClose = this._get(inst, 'onClose');
695
			if (onClose)
767
			if (onClose)
696
				onClose.apply((inst.input ? inst.input[0] : null),
768
				onClose.apply((inst.input ? inst.input[0] : null),
697
					[(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
769
					[(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
698
			this._datepickerShowing = false;
770
			this._datepickerShowing = false;
699
			this._lastInput = null;
771
			this._lastInput = null;
700
			inst.settings.prompt = null;
-
 
701
			if (this._inDialog) {
772
			if (this._inDialog) {
702
				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
773
				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
703
				if ($.blockUI) {
774
				if ($.blockUI) {
704
					$.unblockUI();
775
					$.unblockUI();
705
					$('body').append(this.dpDiv);
776
					$('body').append(this.dpDiv);
706
				}
777
				}
707
			}
778
			}
708
			this._inDialog = false;
779
			this._inDialog = false;
709
		}
780
		}
710
		this._curInst = null;
-
 
711
	},
781
	},
712
	
782
 
713
	/* Tidy up after a dialog display. */
783
	/* Tidy up after a dialog display. */
714
	_tidyDialog: function(inst) {
784
	_tidyDialog: function(inst) {
715
		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker');
785
		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
716
		$('.' + this._promptClass, inst.dpDiv).remove();
-
 
717
	},
786
	},
718
	
787
 
719
	/* Close date picker if clicked elsewhere. */
788
	/* Close date picker if clicked elsewhere. */
720
	_checkExternalClick: function(event) {
789
	_checkExternalClick: function(event) {
721
		if (!$.datepicker._curInst)
790
		if (!$.datepicker._curInst)
722
			return;
791
			return;
723
		var $target = $(event.target);
792
		var $target = $(event.target);
-
 
793
		if ($target[0].id != $.datepicker._mainDivId &&
724
		if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
794
				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
725
				!$target.hasClass($.datepicker.markerClassName) &&
795
				!$target.hasClass($.datepicker.markerClassName) &&
726
				!$target.hasClass($.datepicker._triggerClass) &&
796
				!$target.hasClass($.datepicker._triggerClass) &&
727
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
797
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
728
			$.datepicker._hideDatepicker(null, '');
798
			$.datepicker._hideDatepicker();
729
	},
799
	},
730
	
800
 
731
	/* Adjust one of the date sub-fields. */
801
	/* Adjust one of the date sub-fields. */
732
	_adjustDate: function(id, offset, period) {
802
	_adjustDate: function(id, offset, period) {
733
		var target = $(id);
803
		var target = $(id);
734
		var inst = this._getInst(target[0]);
804
		var inst = this._getInst(target[0]);
-
 
805
		if (this._isDisabledDatepicker(target[0])) {
-
 
806
			return;
-
 
807
		}
735
		this._adjustInstDate(inst, offset, period);
808
		this._adjustInstDate(inst, offset +
-
 
809
			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
-
 
810
			period);
736
		this._updateDatepicker(inst);
811
		this._updateDatepicker(inst);
737
	},
812
	},
738
	
813
 
739
	/* Action for current link. */
814
	/* Action for current link. */
740
	_gotoToday: function(id) {
815
	_gotoToday: function(id) {
741
		var target = $(id);
816
		var target = $(id);
742
		var inst = this._getInst(target[0]);
817
		var inst = this._getInst(target[0]);
743
		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
818
		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
744
			inst.selectedDay = inst.currentDay;
819
			inst.selectedDay = inst.currentDay;
745
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
820
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
746
			inst.drawYear = inst.selectedYear = inst.currentYear;
821
			inst.drawYear = inst.selectedYear = inst.currentYear;
747
		}
822
		}
748
		else {
823
		else {
749
		var date = new Date();
824
			var date = new Date();
750
		inst.selectedDay = date.getDate();
825
			inst.selectedDay = date.getDate();
751
		inst.drawMonth = inst.selectedMonth = date.getMonth();
826
			inst.drawMonth = inst.selectedMonth = date.getMonth();
752
		inst.drawYear = inst.selectedYear = date.getFullYear();
827
			inst.drawYear = inst.selectedYear = date.getFullYear();
753
		}
828
		}
754
		this._notifyChange(inst);
829
		this._notifyChange(inst);
755
		this._adjustDate(target);
830
		this._adjustDate(target);
756
	},
831
	},
757
	
832
 
758
	/* Action for selecting a new month/year. */
833
	/* Action for selecting a new month/year. */
759
	_selectMonthYear: function(id, select, period) {
834
	_selectMonthYear: function(id, select, period) {
760
		var target = $(id);
835
		var target = $(id);
761
		var inst = this._getInst(target[0]);
836
		var inst = this._getInst(target[0]);
762
		inst._selectingMonthYear = false;
837
		inst._selectingMonthYear = false;
763
		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
838
		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
764
		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
839
		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
765
			parseInt(select.options[select.selectedIndex].value,10);
840
			parseInt(select.options[select.selectedIndex].value,10);
766
		this._notifyChange(inst);
841
		this._notifyChange(inst);
767
		this._adjustDate(target);
842
		this._adjustDate(target);
768
	},
843
	},
769
	
844
 
770
	/* Restore input focus after not changing month/year. */
845
	/* Restore input focus after not changing month/year. */
771
	_clickMonthYear: function(id) {
846
	_clickMonthYear: function(id) {
772
		var target = $(id);
847
		var target = $(id);
773
		var inst = this._getInst(target[0]);
848
		var inst = this._getInst(target[0]);
774
		if (inst.input && inst._selectingMonthYear && !$.browser.msie)
849
		if (inst.input && inst._selectingMonthYear) {
-
 
850
			setTimeout(function() {
775
			inst.input[0].focus();
851
				inst.input.focus();
-
 
852
			}, 0);
-
 
853
		}
776
		inst._selectingMonthYear = !inst._selectingMonthYear;
854
		inst._selectingMonthYear = !inst._selectingMonthYear;
777
	},
855
	},
778
	
-
 
779
	/* Action for changing the first week day. */
-
 
780
	_changeFirstDay: function(id, day) {
-
 
781
		var target = $(id);
-
 
782
		var inst = this._getInst(target[0]);
-
 
783
		inst.settings.firstDay = day;
-
 
784
		this._updateDatepicker(inst);
-
 
785
	},
-
 
786
	
856
 
787
	/* Action for selecting a day. */
857
	/* Action for selecting a day. */
788
	_selectDay: function(id, month, year, td) {
-
 
789
		if ($(td).hasClass(this._unselectableClass))
-
 
790
			return;
858
	_selectDay: function(id, month, year, td) {
791
		var target = $(id);
-
 
792
		var inst = this._getInst(target[0]);
-
 
793
		var rangeSelect = this._get(inst, 'rangeSelect');
-
 
794
		if (rangeSelect) {
-
 
795
			inst.stayOpen = !inst.stayOpen;
-
 
796
			if (inst.stayOpen) {
859
		var target = $(id);
797
				$('.ui-datepicker td', inst.dpDiv).removeClass(this._currentClass);
-
 
798
				$(td).addClass(this._currentClass);
860
		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
799
			} 
861
			return;
-
 
862
		}
800
		}
863
		var inst = this._getInst(target[0]);
801
		inst.selectedDay = inst.currentDay = $('a', td).html();
864
		inst.selectedDay = inst.currentDay = $('a', td).html();
802
		inst.selectedMonth = inst.currentMonth = month;
865
		inst.selectedMonth = inst.currentMonth = month;
803
		inst.selectedYear = inst.currentYear = year;
866
		inst.selectedYear = inst.currentYear = year;
804
		if (inst.stayOpen) {
-
 
805
			inst.endDay = inst.endMonth = inst.endYear = null;
-
 
806
		}
-
 
807
		else if (rangeSelect) {
-
 
808
			inst.endDay = inst.currentDay;
-
 
809
			inst.endMonth = inst.currentMonth;
-
 
810
			inst.endYear = inst.currentYear;
-
 
811
		}
-
 
812
		this._selectDate(id, this._formatDate(inst,
867
		this._selectDate(id, this._formatDate(inst,
813
			inst.currentDay, inst.currentMonth, inst.currentYear));
868
			inst.currentDay, inst.currentMonth, inst.currentYear));
814
		if (inst.stayOpen) {
-
 
815
			inst.rangeStart = new Date(inst.currentYear, inst.currentMonth, inst.currentDay);
-
 
816
			this._updateDatepicker(inst);
-
 
817
		}
-
 
818
		else if (rangeSelect) {
-
 
819
			inst.selectedDay = inst.currentDay = inst.rangeStart.getDate();
-
 
820
			inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth();
-
 
821
			inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear();
-
 
822
			inst.rangeStart = null;
-
 
823
			if (inst.inline)
-
 
824
				this._updateDatepicker(inst);
-
 
825
		}
-
 
826
	},
869
	},
827
	
870
 
828
	/* Erase the input field and hide the date picker. */
871
	/* Erase the input field and hide the date picker. */
829
	_clearDate: function(id) {
872
	_clearDate: function(id) {
830
		var target = $(id);
873
		var target = $(id);
831
		var inst = this._getInst(target[0]);
874
		var inst = this._getInst(target[0]);
832
		if (this._get(inst, 'mandatory'))
-
 
833
			return;
-
 
834
		inst.stayOpen = false;
-
 
835
		inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
-
 
836
		this._selectDate(target, '');
875
		this._selectDate(target, '');
837
	},
876
	},
838
	
877
 
839
	/* Update the input field with the selected date. */
878
	/* Update the input field with the selected date. */
840
	_selectDate: function(id, dateStr) {
879
	_selectDate: function(id, dateStr) {
841
		var target = $(id);
880
		var target = $(id);
842
		var inst = this._getInst(target[0]);
881
		var inst = this._getInst(target[0]);
843
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
882
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
844
		if (this._get(inst, 'rangeSelect') && dateStr)
-
 
845
			dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) :
-
 
846
				dateStr) + this._get(inst, 'rangeSeparator') + dateStr;
-
 
847
		if (inst.input)
883
		if (inst.input)
848
			inst.input.val(dateStr);
884
			inst.input.val(dateStr);
849
		this._updateAlternate(inst);
885
		this._updateAlternate(inst);
850
		var onSelect = this._get(inst, 'onSelect');
886
		var onSelect = this._get(inst, 'onSelect');
851
		if (onSelect)
887
		if (onSelect)
852
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
888
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
853
		else if (inst.input)
889
		else if (inst.input)
854
			inst.input.trigger('change'); // fire the change event
890
			inst.input.trigger('change'); // fire the change event
855
		if (inst.inline)
891
		if (inst.inline)
856
			this._updateDatepicker(inst);
892
			this._updateDatepicker(inst);
857
		else if (!inst.stayOpen) {
893
		else {
858
			this._hideDatepicker(null, this._get(inst, 'duration'));
894
			this._hideDatepicker();
859
			this._lastInput = inst.input[0];
895
			this._lastInput = inst.input[0];
860
			if (typeof(inst.input[0]) != 'object')
896
			if (typeof(inst.input[0]) != 'object')
861
				inst.input[0].focus(); // restore focus
897
				inst.input.focus(); // restore focus
862
			this._lastInput = null;
898
			this._lastInput = null;
863
		}
899
		}
864
	},
900
	},
865
	
901
 
866
	/* Update any alternate field to synchronise with the main field. */
902
	/* Update any alternate field to synchronise with the main field. */
867
	_updateAlternate: function(inst) {
903
	_updateAlternate: function(inst) {
868
		var altField = this._get(inst, 'altField');
904
		var altField = this._get(inst, 'altField');
869
		if (altField) { // update alternate field too
905
		if (altField) { // update alternate field too
870
			var altFormat = this._get(inst, 'altFormat');
906
			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
871
			var date = this._getDate(inst);
907
			var date = this._getDate(inst);
872
			dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' :
-
 
873
				this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) +
-
 
874
				this._get(inst, 'rangeSeparator') + this.formatDate(
-
 
875
				altFormat, date[1] || date[0], this._getFormatConfig(inst))) :
-
 
876
				this.formatDate(altFormat, date, this._getFormatConfig(inst)));
908
			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
877
			$(altField).each(function() { $(this).val(dateStr); });
909
			$(altField).each(function() { $(this).val(dateStr); });
878
		}
910
		}
879
	},
911
	},
880
	
912
 
881
	/* Set as beforeShowDay function to prevent selection of weekends.
913
	/* Set as beforeShowDay function to prevent selection of weekends.
882
	   @param  date  Date - the date to customise
914
	   @param  date  Date - the date to customise
883
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
915
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
884
	noWeekends: function(date) {
916
	noWeekends: function(date) {
885
		var day = date.getDay();
917
		var day = date.getDay();
886
		return [(day > 0 && day < 6), ''];
918
		return [(day > 0 && day < 6), ''];
887
	},
919
	},
888
	
920
 
889
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
921
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
890
	   @param  date  Date - the date to get the week for
922
	   @param  date  Date - the date to get the week for
891
	   @return  number - the number of the week within the year that contains this date */
923
	   @return  number - the number of the week within the year that contains this date */
892
	iso8601Week: function(date) {
924
	iso8601Week: function(date) {
893
		var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(),
925
		var checkDate = new Date(date.getTime());
894
			(date.getTimezoneOffset() / -60));
-
 
895
		var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
-
 
896
		var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
-
 
897
		firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
926
		// Find Thursday of this week starting on Monday
898
		if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
-
 
899
			checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
927
		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
900
			return $.datepicker.iso8601Week(checkDate);
928
		var time = checkDate.getTime();
901
		} else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
-
 
902
			firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
929
		checkDate.setMonth(0); // Compare with Jan 1
903
			if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
-
 
904
				return 1;
930
		checkDate.setDate(1);
905
			}
-
 
906
		}
-
 
907
		return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
931
		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
908
	},
-
 
909
	
-
 
910
	/* Provide status text for a particular date.
-
 
911
	   @param  date  the date to get the status for
-
 
912
	   @param  inst  the current datepicker instance
-
 
913
	   @return  the status display text for this date */
-
 
914
	dateStatus: function(date, inst) {
-
 
915
		return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'),
-
 
916
			date, $.datepicker._getFormatConfig(inst));
-
 
917
	},
932
	},
918
	
933
 
919
	/* Parse a string value into a date object.
934
	/* Parse a string value into a date object.
920
	   See formatDate below for the possible formats.
935
	   See formatDate below for the possible formats.
921
 
936
 
922
	   @param  format    string - the expected format of the date
937
	   @param  format    string - the expected format of the date
923
	   @param  value     string - the date in the above format
938
	   @param  value     string - the date in the above format
924
	   @param  settings  Object - attributes include:
939
	   @param  settings  Object - attributes include:
925
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
940
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
926
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
941
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
927
	                     dayNames         string[7] - names of the days from Sunday (optional)
942
	                     dayNames         string[7] - names of the days from Sunday (optional)
928
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
943
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
929
	                     monthNames       string[12] - names of the months (optional)
944
	                     monthNames       string[12] - names of the months (optional)
930
	   @return  Date - the extracted date value or null if value is blank */
945
	   @return  Date - the extracted date value or null if value is blank */
931
	parseDate: function (format, value, settings) {
946
	parseDate: function (format, value, settings) {
932
		if (format == null || value == null)
947
		if (format == null || value == null)
933
			throw 'Invalid arguments';
948
			throw 'Invalid arguments';
934
		value = (typeof value == 'object' ? value.toString() : value + '');
949
		value = (typeof value == 'object' ? value.toString() : value + '');
935
		if (value == '')
950
		if (value == '')
936
			return null;
951
			return null;
937
		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
952
		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
938
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
953
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
939
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
954
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
940
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
955
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
941
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
956
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
942
		var year = -1;
957
		var year = -1;
943
		var month = -1;
958
		var month = -1;
944
		var day = -1;
959
		var day = -1;
945
		var doy = -1;
960
		var doy = -1;
946
		var literal = false;
961
		var literal = false;
947
		// Check whether a format character is doubled
962
		// Check whether a format character is doubled
948
		var lookAhead = function(match) {
963
		var lookAhead = function(match) {
949
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
964
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
950
			if (matches)
965
			if (matches)
951
				iFormat++;
966
				iFormat++;
952
			return matches;	
967
			return matches;
953
		};
968
		};
954
		// Extract a number from the string value
969
		// Extract a number from the string value
955
		var getNumber = function(match) {
970
		var getNumber = function(match) {
956
			lookAhead(match);
971
			lookAhead(match);
957
			var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
972
			var size = (match == '@' ? 14 : (match == '!' ? 20 :
958
			var size = origSize;
-
 
959
			var num = 0;
-
 
960
			while (size > 0 && iValue < value.length &&
973
				(match == 'y' ? 4 : (match == 'o' ? 3 : 2))));
961
					value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
974
			var digits = new RegExp('^\\d{1,' + size + '}');
962
				num = num * 10 + parseInt(value.charAt(iValue++),10);
975
			var num = value.substring(iValue).match(digits);
963
				size--;
976
			if (!num)
964
			}
-
 
965
			if (size == origSize)
-
 
966
				throw 'Missing number at position ' + iValue;
977
				throw 'Missing number at position ' + iValue;
-
 
978
			iValue += num[0].length;
967
			return num;
979
			return parseInt(num[0], 10);
968
		};
980
		};
969
		// Extract a name from the string value and convert to an index
981
		// Extract a name from the string value and convert to an index
970
		var getName = function(match, shortNames, longNames) {
982
		var getName = function(match, shortNames, longNames) {
971
			var names = (lookAhead(match) ? longNames : shortNames);
983
			var names = (lookAhead(match) ? longNames : shortNames);
972
			var size = 0;
-
 
973
			for (var j = 0; j < names.length; j++)
984
			for (var i = 0; i < names.length; i++) {
974
				size = Math.max(size, names[j].length);
985
				if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
975
			var name = '';
-
 
976
			var iInit = iValue;
-
 
977
			while (size > 0 && iValue < value.length) {
-
 
978
				name += value.charAt(iValue++);
-
 
979
				for (var i = 0; i < names.length; i++)
-
 
980
					if (name == names[i])
986
					iValue += names[i].length;
981
						return i + 1;
987
					return i + 1;
982
				size--;
-
 
983
			}
988
				}
-
 
989
			}
984
			throw 'Unknown name at position ' + iInit;
990
			throw 'Unknown name at position ' + iValue;
985
		};
991
		};
986
		// Confirm that a literal character matches the string value
992
		// Confirm that a literal character matches the string value
987
		var checkLiteral = function() {
993
		var checkLiteral = function() {
988
			if (value.charAt(iValue) != format.charAt(iFormat))
994
			if (value.charAt(iValue) != format.charAt(iFormat))
989
				throw 'Unexpected literal at position ' + iValue;
995
				throw 'Unexpected literal at position ' + iValue;
990
			iValue++;
996
			iValue++;
991
		};
997
		};
992
		var iValue = 0;
998
		var iValue = 0;
993
		for (var iFormat = 0; iFormat < format.length; iFormat++) {
999
		for (var iFormat = 0; iFormat < format.length; iFormat++) {
994
			if (literal)
1000
			if (literal)
995
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1001
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
996
					literal = false;
1002
					literal = false;
997
				else
1003
				else
998
					checkLiteral();
1004
					checkLiteral();
999
			else
1005
			else
1000
				switch (format.charAt(iFormat)) {
1006
				switch (format.charAt(iFormat)) {
1001
					case 'd':
1007
					case 'd':
1002
						day = getNumber('d');
1008
						day = getNumber('d');
1003
						break;
1009
						break;
1004
					case 'D': 
1010
					case 'D':
1005
						getName('D', dayNamesShort, dayNames);
1011
						getName('D', dayNamesShort, dayNames);
1006
						break;
1012
						break;
1007
					case 'o':
1013
					case 'o':
1008
						doy = getNumber('o');
1014
						doy = getNumber('o');
1009
						break;
1015
						break;
1010
					case 'm': 
1016
					case 'm':
1011
						month = getNumber('m');
1017
						month = getNumber('m');
1012
						break;
1018
						break;
1013
					case 'M':
1019
					case 'M':
1014
						month = getName('M', monthNamesShort, monthNames); 
1020
						month = getName('M', monthNamesShort, monthNames);
1015
						break;
1021
						break;
1016
					case 'y':
1022
					case 'y':
1017
						year = getNumber('y');
1023
						year = getNumber('y');
1018
						break;
1024
						break;
1019
					case '@':
1025
					case '@':
1020
						var date = new Date(getNumber('@'));
1026
						var date = new Date(getNumber('@'));
1021
						year = date.getFullYear();
1027
						year = date.getFullYear();
1022
						month = date.getMonth() + 1;
1028
						month = date.getMonth() + 1;
1023
						day = date.getDate();
1029
						day = date.getDate();
1024
						break;
1030
						break;
-
 
1031
					case '!':
-
 
1032
						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
-
 
1033
						year = date.getFullYear();
-
 
1034
						month = date.getMonth() + 1;
-
 
1035
						day = date.getDate();
-
 
1036
						break;
1025
					case "'":
1037
					case "'":
1026
						if (lookAhead("'"))
1038
						if (lookAhead("'"))
1027
							checkLiteral();
1039
							checkLiteral();
1028
						else
1040
						else
1029
							literal = true;
1041
							literal = true;
1030
						break;
1042
						break;
1031
					default:
1043
					default:
1032
						checkLiteral();
1044
						checkLiteral();
1033
				}
1045
				}
1034
		}
1046
		}
-
 
1047
		if (year == -1)
-
 
1048
			year = new Date().getFullYear();
1035
		if (year < 100)
1049
		else if (year < 100)
1036
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
1050
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
1037
				(year <= shortYearCutoff ? 0 : -100);
1051
				(year <= shortYearCutoff ? 0 : -100);
1038
		if (doy > -1) {
1052
		if (doy > -1) {
1039
			month = 1;
1053
			month = 1;
1040
			day = doy;
1054
			day = doy;
1041
			do {
1055
			do {
1042
				var dim = this._getDaysInMonth(year, month - 1);
1056
				var dim = this._getDaysInMonth(year, month - 1);
1043
				if (day <= dim)
1057
				if (day <= dim)
1044
					break;
1058
					break;
1045
				month++;
1059
				month++;
1046
				day -= dim;
1060
				day -= dim;
1047
			} while (true);
1061
			} while (true);
1048
		}
1062
		}
1049
		var date = new Date(year, month - 1, day);
1063
		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
1050
		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
1064
		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
1051
			throw 'Invalid date'; // E.g. 31/02/*
1065
			throw 'Invalid date'; // E.g. 31/02/*
1052
		return date;
1066
		return date;
1053
	},
1067
	},
1054
	
1068
 
1055
	/* Standard date formats. */
1069
	/* Standard date formats. */
1056
	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
1070
	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
1057
	COOKIE: 'D, dd M yy',
1071
	COOKIE: 'D, dd M yy',
1058
	ISO_8601: 'yy-mm-dd',
1072
	ISO_8601: 'yy-mm-dd',
1059
	RFC_822: 'D, d M y',
1073
	RFC_822: 'D, d M y',
1060
	RFC_850: 'DD, dd-M-y',
1074
	RFC_850: 'DD, dd-M-y',
1061
	RFC_1036: 'D, d M y',
1075
	RFC_1036: 'D, d M y',
1062
	RFC_1123: 'D, d M yy',
1076
	RFC_1123: 'D, d M yy',
1063
	RFC_2822: 'D, d M yy',
1077
	RFC_2822: 'D, d M yy',
1064
	RSS: 'D, d M y', // RFC 822
1078
	RSS: 'D, d M y', // RFC 822
-
 
1079
	TICKS: '!',
1065
	TIMESTAMP: '@',
1080
	TIMESTAMP: '@',
1066
	W3C: 'yy-mm-dd', // ISO 8601
1081
	W3C: 'yy-mm-dd', // ISO 8601
-
 
1082
 
-
 
1083
	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
-
 
1084
		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
1067
	
1085
 
1068
	/* Format a date object into a string value.
1086
	/* Format a date object into a string value.
1069
	   The format can be combinations of the following:
1087
	   The format can be combinations of the following:
1070
	   d  - day of month (no leading zero)
1088
	   d  - day of month (no leading zero)
1071
	   dd - day of month (two digit)
1089
	   dd - day of month (two digit)
1072
	   o  - day of year (no leading zeros)
1090
	   o  - day of year (no leading zeros)
1073
	   oo - day of year (three digit)
1091
	   oo - day of year (three digit)
1074
	   D  - day name short
1092
	   D  - day name short
1075
	   DD - day name long
1093
	   DD - day name long
1076
	   m  - month of year (no leading zero)
1094
	   m  - month of year (no leading zero)
1077
	   mm - month of year (two digit)
1095
	   mm - month of year (two digit)
1078
	   M  - month name short
1096
	   M  - month name short
1079
	   MM - month name long
1097
	   MM - month name long
1080
	   y  - year (two digit)
1098
	   y  - year (two digit)
1081
	   yy - year (four digit)
1099
	   yy - year (four digit)
1082
	   @ - Unix timestamp (ms since 01/01/1970)
1100
	   @ - Unix timestamp (ms since 01/01/1970)
-
 
1101
	   ! - Windows ticks (100ns since 01/01/0001)
1083
	   '...' - literal text
1102
	   '...' - literal text
1084
	   '' - single quote
1103
	   '' - single quote
1085
	
1104
 
1086
	   @param  format    string - the desired format of the date
1105
	   @param  format    string - the desired format of the date
1087
	   @param  date      Date - the date value to format
1106
	   @param  date      Date - the date value to format
1088
	   @param  settings  Object - attributes include:
1107
	   @param  settings  Object - attributes include:
1089
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
1108
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
1090
	                     dayNames         string[7] - names of the days from Sunday (optional)
1109
	                     dayNames         string[7] - names of the days from Sunday (optional)
1091
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
1110
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
1092
	                     monthNames       string[12] - names of the months (optional)
1111
	                     monthNames       string[12] - names of the months (optional)
1093
	   @return  string - the date in the above format */
1112
	   @return  string - the date in the above format */
1094
	formatDate: function (format, date, settings) {
1113
	formatDate: function (format, date, settings) {
1095
		if (!date)
1114
		if (!date)
1096
			return '';
1115
			return '';
1097
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
1116
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
1098
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
1117
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
1099
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
1118
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
1100
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
1119
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
1101
		// Check whether a format character is doubled
1120
		// Check whether a format character is doubled
1102
		var lookAhead = function(match) {
1121
		var lookAhead = function(match) {
1103
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1122
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1104
			if (matches)
1123
			if (matches)
1105
				iFormat++;
1124
				iFormat++;
1106
			return matches;	
1125
			return matches;
1107
		};
1126
		};
1108
		// Format a number, with leading zero if necessary
1127
		// Format a number, with leading zero if necessary
1109
		var formatNumber = function(match, value, len) {
1128
		var formatNumber = function(match, value, len) {
1110
			var num = '' + value;
1129
			var num = '' + value;
1111
			if (lookAhead(match))
1130
			if (lookAhead(match))
1112
				while (num.length < len)
1131
				while (num.length < len)
1113
					num = '0' + num;
1132
					num = '0' + num;
1114
			return num;
1133
			return num;
1115
		};
1134
		};
1116
		// Format a name, short or long as requested
1135
		// Format a name, short or long as requested
1117
		var formatName = function(match, value, shortNames, longNames) {
1136
		var formatName = function(match, value, shortNames, longNames) {
1118
			return (lookAhead(match) ? longNames[value] : shortNames[value]);
1137
			return (lookAhead(match) ? longNames[value] : shortNames[value]);
1119
		};
1138
		};
1120
		var output = '';
1139
		var output = '';
1121
		var literal = false;
1140
		var literal = false;
1122
		if (date)
1141
		if (date)
1123
			for (var iFormat = 0; iFormat < format.length; iFormat++) {
1142
			for (var iFormat = 0; iFormat < format.length; iFormat++) {
1124
				if (literal)
1143
				if (literal)
1125
					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1144
					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1126
						literal = false;
1145
						literal = false;
1127
					else
1146
					else
1128
						output += format.charAt(iFormat);
1147
						output += format.charAt(iFormat);
1129
				else
1148
				else
1130
					switch (format.charAt(iFormat)) {
1149
					switch (format.charAt(iFormat)) {
1131
						case 'd':
1150
						case 'd':
1132
							output += formatNumber('d', date.getDate(), 2);
1151
							output += formatNumber('d', date.getDate(), 2);
1133
							break;
1152
							break;
1134
						case 'D': 
1153
						case 'D':
1135
							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1154
							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1136
							break;
1155
							break;
1137
						case 'o':
1156
						case 'o':
1138
							var doy = date.getDate();
1157
							output += formatNumber('o',
1139
							for (var m = date.getMonth() - 1; m >= 0; m--)
-
 
1140
								doy += this._getDaysInMonth(date.getFullYear(), m);
1158
								(date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
1141
							output += formatNumber('o', doy, 3);
-
 
1142
							break;
1159
							break;
1143
						case 'm': 
1160
						case 'm':
1144
							output += formatNumber('m', date.getMonth() + 1, 2);
1161
							output += formatNumber('m', date.getMonth() + 1, 2);
1145
							break;
1162
							break;
1146
						case 'M':
1163
						case 'M':
1147
							output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 
1164
							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
1148
							break;
1165
							break;
1149
						case 'y':
1166
						case 'y':
1150
							output += (lookAhead('y') ? date.getFullYear() : 
1167
							output += (lookAhead('y') ? date.getFullYear() :
1151
								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
1168
								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
1152
							break;
1169
							break;
1153
						case '@':
1170
						case '@':
1154
							output += date.getTime(); 
1171
							output += date.getTime();
1155
							break;
1172
							break;
-
 
1173
						case '!':
-
 
1174
							output += date.getTime() * 10000 + this._ticksTo1970;
-
 
1175
							break;
1156
						case "'":
1176
						case "'":
1157
							if (lookAhead("'"))
1177
							if (lookAhead("'"))
1158
								output += "'";
1178
								output += "'";
1159
							else
1179
							else
1160
								literal = true;
1180
								literal = true;
1161
							break;
1181
							break;
1162
						default:
1182
						default:
1163
							output += format.charAt(iFormat);
1183
							output += format.charAt(iFormat);
1164
					}
1184
					}
1165
			}
1185
			}
1166
		return output;
1186
		return output;
1167
	},
1187
	},
1168
	
1188
 
1169
	/* Extract all possible characters from the date format. */
1189
	/* Extract all possible characters from the date format. */
1170
	_possibleChars: function (format) {
1190
	_possibleChars: function (format) {
1171
		var chars = '';
1191
		var chars = '';
1172
		var literal = false;
1192
		var literal = false;
-
 
1193
		// Check whether a format character is doubled
-
 
1194
		var lookAhead = function(match) {
-
 
1195
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
-
 
1196
			if (matches)
-
 
1197
				iFormat++;
-
 
1198
			return matches;
-
 
1199
		};
1173
		for (var iFormat = 0; iFormat < format.length; iFormat++)
1200
		for (var iFormat = 0; iFormat < format.length; iFormat++)
1174
			if (literal)
1201
			if (literal)
1175
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1202
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1176
					literal = false;
1203
					literal = false;
1177
				else
1204
				else
1178
					chars += format.charAt(iFormat);
1205
					chars += format.charAt(iFormat);
1179
			else
1206
			else
1180
				switch (format.charAt(iFormat)) {
1207
				switch (format.charAt(iFormat)) {
1181
					case 'd': case 'm': case 'y': case '@':
1208
					case 'd': case 'm': case 'y': case '@':
1182
						chars += '0123456789'; 
1209
						chars += '0123456789';
1183
						break;
1210
						break;
1184
					case 'D': case 'M':
1211
					case 'D': case 'M':
1185
						return null; // Accept anything
1212
						return null; // Accept anything
1186
					case "'":
1213
					case "'":
1187
						if (lookAhead("'"))
1214
						if (lookAhead("'"))
1188
							chars += "'";
1215
							chars += "'";
1189
						else
1216
						else
1190
							literal = true;
1217
							literal = true;
1191
						break;
1218
						break;
1192
					default:
1219
					default:
1193
						chars += format.charAt(iFormat);
1220
						chars += format.charAt(iFormat);
1194
				}
1221
				}
1195
		return chars;
1222
		return chars;
1196
	},
1223
	},
1197
	
1224
 
1198
	/* Get a setting value, defaulting if necessary. */
1225
	/* Get a setting value, defaulting if necessary. */
1199
	_get: function(inst, name) {
1226
	_get: function(inst, name) {
1200
		return inst.settings[name] !== undefined ?
1227
		return inst.settings[name] !== undefined ?
1201
			inst.settings[name] : this._defaults[name];
1228
			inst.settings[name] : this._defaults[name];
1202
	},
1229
	},
1203
	
1230
 
1204
	/* Parse existing date and initialise date picker. */
1231
	/* Parse existing date and initialise date picker. */
1205
	_setDateFromField: function(inst) {
1232
	_setDateFromField: function(inst, noDefault) {
-
 
1233
		if (inst.input.val() == inst.lastVal) {
-
 
1234
			return;
-
 
1235
		}
1206
		var dateFormat = this._get(inst, 'dateFormat');
1236
		var dateFormat = this._get(inst, 'dateFormat');
1207
		var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null; 
1237
		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
1208
		inst.endDay = inst.endMonth = inst.endYear = null;
1238
		var date, defaultDate;
1209
		var date = defaultDate = this._getDefaultDate(inst);
1239
		date = defaultDate = this._getDefaultDate(inst);
1210
		if (dates.length > 0) {
-
 
1211
			var settings = this._getFormatConfig(inst);
1240
		var settings = this._getFormatConfig(inst);
1212
			if (dates.length > 1) {
-
 
1213
				date = this.parseDate(dateFormat, dates[1], settings) || defaultDate;
-
 
1214
				inst.endDay = date.getDate();
-
 
1215
				inst.endMonth = date.getMonth();
-
 
1216
				inst.endYear = date.getFullYear();
-
 
1217
			}
-
 
1218
			try {
1241
		try {
1219
				date = this.parseDate(dateFormat, dates[0], settings) || defaultDate;
1242
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
1220
			} catch (e) {
1243
		} catch (event) {
1221
				this.log(e);
1244
			this.log(event);
1222
				date = defaultDate;
1245
			dates = (noDefault ? '' : dates);
1223
			}
-
 
1224
		}
1246
		}
1225
		inst.selectedDay = date.getDate();
1247
		inst.selectedDay = date.getDate();
1226
		inst.drawMonth = inst.selectedMonth = date.getMonth();
1248
		inst.drawMonth = inst.selectedMonth = date.getMonth();
1227
		inst.drawYear = inst.selectedYear = date.getFullYear();
1249
		inst.drawYear = inst.selectedYear = date.getFullYear();
1228
		inst.currentDay = (dates[0] ? date.getDate() : 0);
1250
		inst.currentDay = (dates ? date.getDate() : 0);
1229
		inst.currentMonth = (dates[0] ? date.getMonth() : 0);
1251
		inst.currentMonth = (dates ? date.getMonth() : 0);
1230
		inst.currentYear = (dates[0] ? date.getFullYear() : 0);
1252
		inst.currentYear = (dates ? date.getFullYear() : 0);
1231
		this._adjustInstDate(inst);
1253
		this._adjustInstDate(inst);
1232
	},
1254
	},
1233
	
1255
 
1234
	/* Retrieve the default date shown on opening. */
1256
	/* Retrieve the default date shown on opening. */
1235
	_getDefaultDate: function(inst) {
1257
	_getDefaultDate: function(inst) {
1236
		var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
-
 
1237
		var minDate = this._getMinMaxDate(inst, 'min', true);
-
 
1238
		var maxDate = this._getMinMaxDate(inst, 'max');
1258
		return this._restrictMinMax(inst,
1239
		date = (minDate && date < minDate ? minDate : date);
1259
			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
1240
		date = (maxDate && date > maxDate ? maxDate : date);
-
 
1241
		return date;
-
 
1242
	},
1260
	},
1243
	
1261
 
1244
	/* A date may be specified as an exact value or a relative one. */
1262
	/* A date may be specified as an exact value or a relative one. */
1245
	_determineDate: function(date, defaultDate) {
1263
	_determineDate: function(inst, date, defaultDate) {
1246
		var offsetNumeric = function(offset) {
1264
		var offsetNumeric = function(offset) {
1247
			var date = new Date();
1265
			var date = new Date();
1248
			date.setUTCDate(date.getUTCDate() + offset);
1266
			date.setDate(date.getDate() + offset);
1249
			return date;
1267
			return date;
1250
		};
1268
		};
1251
		var offsetString = function(offset, getDaysInMonth) {
1269
		var offsetString = function(offset) {
-
 
1270
			try {
-
 
1271
				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
-
 
1272
					offset, $.datepicker._getFormatConfig(inst));
-
 
1273
			}
-
 
1274
			catch (e) {
-
 
1275
				// Ignore
-
 
1276
			}
1252
			var date = new Date();
1277
			var date = (offset.toLowerCase().match(/^c/) ?
-
 
1278
				$.datepicker._getDate(inst) : null) || new Date();
1253
			var year = date.getFullYear();
1279
			var year = date.getFullYear();
1254
			var month = date.getMonth();
1280
			var month = date.getMonth();
1255
			var day = date.getDate();
1281
			var day = date.getDate();
1256
			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
1282
			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
1257
			var matches = pattern.exec(offset);
1283
			var matches = pattern.exec(offset);
1258
			while (matches) {
1284
			while (matches) {
1259
				switch (matches[2] || 'd') {
1285
				switch (matches[2] || 'd') {
1260
					case 'd' : case 'D' :
1286
					case 'd' : case 'D' :
1261
						day += parseInt(matches[1],10); break;
1287
						day += parseInt(matches[1],10); break;
1262
					case 'w' : case 'W' :
1288
					case 'w' : case 'W' :
1263
						day += parseInt(matches[1],10) * 7; break;
1289
						day += parseInt(matches[1],10) * 7; break;
1264
					case 'm' : case 'M' :
1290
					case 'm' : case 'M' :
1265
						month += parseInt(matches[1],10); 
1291
						month += parseInt(matches[1],10);
1266
						day = Math.min(day, getDaysInMonth(year, month));
1292
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1267
						break;
1293
						break;
1268
					case 'y': case 'Y' :
1294
					case 'y': case 'Y' :
1269
						year += parseInt(matches[1],10);
1295
						year += parseInt(matches[1],10);
1270
						day = Math.min(day, getDaysInMonth(year, month));
1296
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1271
						break;
1297
						break;
1272
				}
1298
				}
1273
				matches = pattern.exec(offset);
1299
				matches = pattern.exec(offset);
1274
			}
1300
			}
1275
			return new Date(year, month, day);
1301
			return new Date(year, month, day);
1276
		};
1302
		};
1277
		date = (date == null ? defaultDate :
-
 
1278
			(typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
1303
		date = (date == null ? defaultDate : (typeof date == 'string' ? offsetString(date) :
1279
			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
1304
			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
1280
		date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
1305
		date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
1281
		if (date) {
1306
		if (date) {
1282
			date.setHours(0);
1307
			date.setHours(0);
1283
			date.setMinutes(0);
1308
			date.setMinutes(0);
1284
			date.setSeconds(0);
1309
			date.setSeconds(0);
1285
			date.setMilliseconds(0);
1310
			date.setMilliseconds(0);
1286
		}
1311
		}
-
 
1312
		return this._daylightSavingAdjust(date);
-
 
1313
	},
-
 
1314
 
-
 
1315
	/* Handle switch to/from daylight saving.
-
 
1316
	   Hours may be non-zero on daylight saving cut-over:
-
 
1317
	   > 12 when midnight changeover, but then cannot generate
-
 
1318
	   midnight datetime, so jump to 1AM, otherwise reset.
-
 
1319
	   @param  date  (Date) the date to check
-
 
1320
	   @return  (Date) the corrected date */
-
 
1321
	_daylightSavingAdjust: function(date) {
-
 
1322
		if (!date) return null;
-
 
1323
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
1287
		return date;
1324
		return date;
1288
	},
1325
	},
1289
	
1326
 
1290
	/* Set the date(s) directly. */
1327
	/* Set the date(s) directly. */
1291
	_setDate: function(inst, date, endDate) {
1328
	_setDate: function(inst, date, noChange) {
1292
		var clear = !(date);
1329
		var clear = !(date);
1293
		var origMonth = inst.selectedMonth;
1330
		var origMonth = inst.selectedMonth;
1294
		var origYear = inst.selectedYear;
1331
		var origYear = inst.selectedYear;
1295
		date = this._determineDate(date, new Date());
1332
		date = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
1296
		inst.selectedDay = inst.currentDay = date.getDate();
1333
		inst.selectedDay = inst.currentDay = date.getDate();
1297
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
1334
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
1298
		inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
1335
		inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
1299
		if (this._get(inst, 'rangeSelect')) {
-
 
1300
			if (endDate) {
-
 
1301
				endDate = this._determineDate(endDate, null);
-
 
1302
				inst.endDay = endDate.getDate();
-
 
1303
				inst.endMonth = endDate.getMonth();
-
 
1304
				inst.endYear = endDate.getFullYear();
-
 
1305
			} else {
-
 
1306
				inst.endDay = inst.currentDay;
-
 
1307
				inst.endMonth = inst.currentMonth;
-
 
1308
				inst.endYear = inst.currentYear;
-
 
1309
			}
-
 
1310
		}
-
 
1311
		if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
1336
		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
1312
			this._notifyChange(inst);
1337
			this._notifyChange(inst);
1313
		this._adjustInstDate(inst);
1338
		this._adjustInstDate(inst);
1314
		if (inst.input)
1339
		if (inst.input) {
1315
			inst.input.val(clear ? '' : this._formatDate(inst) +
1340
			inst.input.val(clear ? '' : this._formatDate(inst));
1316
				(!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') +
-
 
1317
				this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear)));
-
 
-
 
1341
		}
1318
	},
1342
	},
1319
	
1343
 
1320
	/* Retrieve the date(s) directly. */
1344
	/* Retrieve the date(s) directly. */
1321
	_getDate: function(inst) {
1345
	_getDate: function(inst) {
1322
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
1346
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
1323
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
-
 
1324
		if (this._get(inst, 'rangeSelect')) {
1347
			this._daylightSavingAdjust(new Date(
1325
			return [inst.rangeStart || startDate,
-
 
1326
				(!inst.endYear ? inst.rangeStart || startDate :
-
 
1327
				new Date(inst.endYear, inst.endMonth, inst.endDay))];
1348
			inst.currentYear, inst.currentMonth, inst.currentDay)));
1328
		} else
-
 
1329
			return startDate;
1349
			return startDate;
1330
	},
1350
	},
1331
	
1351
 
1332
	/* Generate the HTML for the current state of the date picker. */
1352
	/* Generate the HTML for the current state of the date picker. */
1333
	_generateHTML: function(inst) {
1353
	_generateHTML: function(inst) {
1334
		var today = new Date();
1354
		var today = new Date();
1335
		today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
-
 
1336
		var showStatus = this._get(inst, 'showStatus');
1355
		today = this._daylightSavingAdjust(
1337
		var initStatus = this._get(inst, 'initStatus') || '&#xa0;';
1356
			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
1338
		var isRTL = this._get(inst, 'isRTL');
1357
		var isRTL = this._get(inst, 'isRTL');
1339
		// build the date picker HTML
-
 
1340
		var clear = (this._get(inst, 'mandatory') ? '' :
-
 
1341
			'<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' +
-
 
1342
			this._addStatus(showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) + '>' +
-
 
1343
			this._get(inst, 'clearText') + '</a></div>');
-
 
1344
		var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) +
-
 
1345
			'<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
-
 
1346
			this._addStatus(showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) + '>' +
-
 
1347
			this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '')  + '</div>';
-
 
1348
		var prompt = this._get(inst, 'prompt');
-
 
1349
		var closeAtTop = this._get(inst, 'closeAtTop');
1358
		var showButtonPanel = this._get(inst, 'showButtonPanel');
1350
		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1359
		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1351
		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1360
		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1352
		var showBigPrevNext = this._get(inst, 'showBigPrevNext');
-
 
1353
		var numMonths = this._getNumberOfMonths(inst);
1361
		var numMonths = this._getNumberOfMonths(inst);
1354
		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1362
		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1355
		var stepMonths = this._get(inst, 'stepMonths');
1363
		var stepMonths = this._get(inst, 'stepMonths');
1356
		var stepBigMonths = this._get(inst, 'stepBigMonths');
-
 
1357
		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1364
		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1358
		var currentDate = (!inst.currentDay ? new Date(9999, 9, 9) :
1365
		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
1359
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1366
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1360
		var minDate = this._getMinMaxDate(inst, 'min', true);
1367
		var minDate = this._getMinMaxDate(inst, 'min');
1361
		var maxDate = this._getMinMaxDate(inst, 'max');
1368
		var maxDate = this._getMinMaxDate(inst, 'max');
1362
		var drawMonth = inst.drawMonth - showCurrentAtPos;
1369
		var drawMonth = inst.drawMonth - showCurrentAtPos;
1363
		var drawYear = inst.drawYear;
1370
		var drawYear = inst.drawYear;
1364
		if (drawMonth < 0) {
1371
		if (drawMonth < 0) {
1365
			drawMonth += 12;
1372
			drawMonth += 12;
1366
			drawYear--;
1373
			drawYear--;
1367
		}
1374
		}
1368
		if (maxDate) {
1375
		if (maxDate) {
1369
			var maxDraw = new Date(maxDate.getFullYear(),
1376
			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
1370
				maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
1377
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
1371
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1378
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1372
			while (new Date(drawYear, drawMonth, 1) > maxDraw) {
1379
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
1373
				drawMonth--;
1380
				drawMonth--;
1374
				if (drawMonth < 0) {
1381
				if (drawMonth < 0) {
1375
					drawMonth = 11;
1382
					drawMonth = 11;
1376
					drawYear--;
1383
					drawYear--;
1377
				}
1384
				}
1378
			}
1385
			}
1379
		}
1386
		}
1380
		// controls and links
1387
		inst.drawMonth = drawMonth;
-
 
1388
		inst.drawYear = drawYear;
1381
		var prevText = this._get(inst, 'prevText');
1389
		var prevText = this._get(inst, 'prevText');
1382
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(
1390
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
1383
			prevText, new Date(drawYear, drawMonth - stepMonths, 1), this._getFormatConfig(inst)));
1391
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
1384
		var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : '');
-
 
1385
		prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(
-
 
1386
			prevBigText, new Date(drawYear, drawMonth - stepBigMonths, 1), this._getFormatConfig(inst)));
1392
			this._getFormatConfig(inst)));
1387
		var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 
1393
		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1388
			(showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepBigMonths + ', \'M\');"' +
1394
			'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
1389
			this._addStatus(showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) + '>' + prevBigText + '</a>' : '') +
-
 
1390
			'<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
1395
			'.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
1391
			this._addStatus(showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) + '>' + prevText + '</a>' :
1396
			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
1392
			(hideIfNoPrevNext ? '' : '<label>' + prevBigText + '</label><label>' + prevText + '</label>')) + '</div>';
1397
			(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>'));
1393
		var nextText = this._get(inst, 'nextText');
1398
		var nextText = this._get(inst, 'nextText');
1394
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(
1399
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
1395
			nextText, new Date(drawYear, drawMonth + stepMonths, 1), this._getFormatConfig(inst)));
1400
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
1396
		var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : '');
-
 
1397
		nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(
-
 
1398
			nextBigText, new Date(drawYear, drawMonth + stepBigMonths, 1), this._getFormatConfig(inst)));
1401
			this._getFormatConfig(inst)));
1399
		var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1402
		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1400
			'<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
1403
			'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
1401
			this._addStatus(showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) + '>' + nextText + '</a>' +
-
 
1402
			(showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepBigMonths + ', \'M\');"' +
1404
			'.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
1403
			this._addStatus(showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) + '>' + nextBigText + '</a>' : '') :
1405
			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
1404
			(hideIfNoPrevNext ? '' : '<label>' + nextText + '</label><label>' + nextBigText + '</label>')) + '</div>';
1406
			(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>'));
1405
		var currentText = this._get(inst, 'currentText');
1407
		var currentText = this._get(inst, 'currentText');
1406
		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); 
1408
		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
1407
		currentText = (!navigationAsDateFormat ? currentText :
1409
		currentText = (!navigationAsDateFormat ? currentText :
1408
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1410
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1409
		var html = (prompt ? '<div class="' + this._promptClass + '">' + prompt + '</div>' : '') +
1411
		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
1410
			(closeAtTop && !inst.inline ? controls : '') +
1412
			'.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
1411
			'<div class="ui-datepicker-links">' + (isRTL ? next : prev) +
1413
		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
1412
			(this._isInRange(inst, gotoDate) ? '<div class="ui-datepicker-current">' +
1414
			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
1413
			'<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
1415
			'.datepicker._gotoToday(\'#' + inst.id + '\');"' +
1414
			this._addStatus(showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' +
-
 
1415
			currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
1416
			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
1416
		var firstDay = this._get(inst, 'firstDay');
1417
		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
-
 
1418
		firstDay = (isNaN(firstDay) ? 0 : firstDay);
1417
		var changeFirstDay = this._get(inst, 'changeFirstDay');
1419
		var showWeek = this._get(inst, 'showWeek');
1418
		var dayNames = this._get(inst, 'dayNames');
1420
		var dayNames = this._get(inst, 'dayNames');
1419
		var dayNamesShort = this._get(inst, 'dayNamesShort');
1421
		var dayNamesShort = this._get(inst, 'dayNamesShort');
1420
		var dayNamesMin = this._get(inst, 'dayNamesMin');
1422
		var dayNamesMin = this._get(inst, 'dayNamesMin');
1421
		var monthNames = this._get(inst, 'monthNames');
1423
		var monthNames = this._get(inst, 'monthNames');
-
 
1424
		var monthNamesShort = this._get(inst, 'monthNamesShort');
1422
		var beforeShowDay = this._get(inst, 'beforeShowDay');
1425
		var beforeShowDay = this._get(inst, 'beforeShowDay');
1423
		var highlightWeek = this._get(inst, 'highlightWeek');
-
 
1424
		var showOtherMonths = this._get(inst, 'showOtherMonths');
1426
		var showOtherMonths = this._get(inst, 'showOtherMonths');
1425
		var showWeeks = this._get(inst, 'showWeeks');
1427
		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
1426
		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1428
		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1427
		var weekStatus = this._get(inst, 'weekStatus');
-
 
1428
		var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : '');
-
 
1429
		var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
-
 
1430
		var endDate = inst.endDay ? new Date(inst.endYear, inst.endMonth, inst.endDay) : currentDate;
-
 
1431
		var defaultDate = this._getDefaultDate(inst);
1429
		var defaultDate = this._getDefaultDate(inst);
-
 
1430
		var html = '';
1432
		for (var row = 0; row < numMonths[0]; row++)
1431
		for (var row = 0; row < numMonths[0]; row++) {
-
 
1432
			var group = '';
1433
			for (var col = 0; col < numMonths[1]; col++) {
1433
			for (var col = 0; col < numMonths[1]; col++) {
1434
				var selectedDate = new Date(drawYear, drawMonth, inst.selectedDay);
1434
				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
-
 
1435
				var cornerClass = ' ui-corner-all';
-
 
1436
				var calender = '';
-
 
1437
				if (isMultiMonth) {
-
 
1438
					calender += '<div class="ui-datepicker-group';
-
 
1439
					if (numMonths[1] > 1)
-
 
1440
						switch (col) {
-
 
1441
							case 0: calender += ' ui-datepicker-group-first';
-
 
1442
								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
-
 
1443
							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
-
 
1444
								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
-
 
1445
							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
-
 
1446
						}
-
 
1447
					calender += '">';
-
 
1448
				}
1435
				html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' +
1449
				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
-
 
1450
					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
-
 
1451
					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
1436
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1452
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1437
					selectedDate, row > 0 || col > 0, showStatus, initStatus, monthNames) + // draw month headers
1453
					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
1438
					'<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' + 
1454
					'</div><table class="ui-datepicker-calendar"><thead>' +
1439
					'<tr class="ui-datepicker-title-row">' +
1455
					'<tr>';
1440
					(showWeeks ? '<td' + this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
1456
				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
1441
					this._get(inst, 'weekHeader') + '</td>' : '');
-
 
1442
				for (var dow = 0; dow < 7; dow++) { // days of the week
1457
				for (var dow = 0; dow < 7; dow++) { // days of the week
1443
					var day = (dow + firstDay) % 7;
1458
					var day = (dow + firstDay) % 7;
1444
					var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
-
 
1445
						status.replace(/D/, dayNamesShort[day]));
-
 
1446
					html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' +
1459
					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
1447
						(!changeFirstDay ? '<span' :
-
 
1448
						'<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') + 
-
 
1449
						this._addStatus(showStatus, inst.id, dayStatus, initStatus) + ' title="' + dayNames[day] + '">' +
-
 
1450
						dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
1460
						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
1451
				}
1461
				}
1452
				html += '</tr></thead><tbody>';
1462
				calender += thead + '</tr></thead><tbody>';
1453
				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1463
				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1454
				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
1464
				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
1455
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1465
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1456
				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1466
				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1457
				var tzDate = new Date(drawYear, drawMonth, 1 - leadDays);
-
 
1458
				var utcDate = new Date(drawYear, drawMonth, 1 - leadDays);
-
 
1459
				var printDate = utcDate;
-
 
1460
				var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
1467
				var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
-
 
1468
				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
1461
				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1469
				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1462
					html += '<tr class="ui-datepicker-days-row">' +
1470
					calender += '<tr>';
1463
						(showWeeks ? '<td class="ui-datepicker-week-col"' +
1471
					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
1464
						this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
-
 
1465
						calculateWeek(printDate) + '</td>' : '');
1472
						this._get(inst, 'calculateWeek')(printDate) + '</td>');
1466
					for (var dow = 0; dow < 7; dow++) { // create date picker days
1473
					for (var dow = 0; dow < 7; dow++) { // create date picker days
1467
						var daySettings = (beforeShowDay ?
1474
						var daySettings = (beforeShowDay ?
1468
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1475
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1469
						var otherMonth = (printDate.getMonth() != drawMonth);
1476
						var otherMonth = (printDate.getMonth() != drawMonth);
1470
						var unselectable = otherMonth || !daySettings[0] ||
1477
						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
1471
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1478
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1472
						html += '<td class="ui-datepicker-days-cell' +
1479
						tbody += '<td class="' +
1473
							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends
1480
							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
1474
							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
1481
							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
1475
							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) // user pressed key
1482
							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
1476
							 || (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
1483
							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
1477
							 // or defaultDate is current printedDate and defaultDate is selectedDate
1484
							// or defaultDate is current printedDate and defaultDate is selectedDate
1478
							' ' + $.datepicker._dayOverClass : '') + // highlight selected day
1485
							' ' + this._dayOverClass : '') + // highlight selected day
1479
							(unselectable ? ' ' + this._unselectableClass : '') +  // highlight unselectable days
1486
							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
1480
							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1487
							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1481
							(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1488
							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
1482
							' ' + this._currentClass : '') + // highlight selected day
-
 
1483
							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
1489
							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
1484
							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
1490
							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
1485
							(unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'' + this._weekOverClass + '\');"' + // highlight selection week
-
 
1486
							' onmouseout="jQuery(this).parent().removeClass(\'' + this._weekOverClass + '\');"' : '') : // unhighlight selection week
-
 
1487
							' onmouseover="jQuery(this).addClass(\'' + this._dayOverClass + '\')' + // highlight selection
1491
							(unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
1488
							(highlightWeek ? '.parent().addClass(\'' + this._weekOverClass + '\')' : '') + ';' + // highlight selection week
1492
							inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
1489
							(!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
1493
							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
1490
							inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null),
1494
							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
1491
							[printDate, inst]) || initStatus) +'\');') + '"' +
1495
							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
1492
							' onmouseout="jQuery(this).removeClass(\'' + this._dayOverClass + '\')' + // unhighlight selection
-
 
1493
							(highlightWeek ? '.parent().removeClass(\'' + this._weekOverClass + '\')' : '') + ';' + // unhighlight selection week
1496
							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
1494
							(!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
-
 
1495
							inst.id + '\').html(\'' + initStatus + '\');') + '" onclick="jQuery.datepicker._selectDay(\'#' +
-
 
1496
							inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
-
 
1497
							(otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
1497
							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
1498
							(unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
1498
							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
1499
						tzDate.setDate(tzDate.getDate() + 1);
1499
						printDate.setDate(printDate.getDate() + 1);
1500
						utcDate.setUTCDate(utcDate.getUTCDate() + 1);
-
 
1501
						printDate = (tzDate > utcDate ? tzDate : utcDate);
1500
						printDate = this._daylightSavingAdjust(printDate);
1502
					}
1501
					}
1503
					html += '</tr>';
1502
					calender += tbody + '</tr>';
1504
				}
1503
				}
1505
				drawMonth++;
1504
				drawMonth++;
1506
				if (drawMonth > 11) {
1505
				if (drawMonth > 11) {
1507
					drawMonth = 0;
1506
					drawMonth = 0;
1508
					drawYear++;
1507
					drawYear++;
1509
				}
1508
				}
1510
				html += '</tbody></table></div>';
1509
				calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
-
 
1510
							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
-
 
1511
				group += calender;
-
 
1512
			}
-
 
1513
			html += group;
1511
			}
1514
		}
1512
		html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id + 
-
 
1513
			'" class="ui-datepicker-status">' + initStatus + '</div>' : '') +
-
 
1514
			(!closeAtTop && !inst.inline ? controls : '') +
-
 
1515
			'<div style="clear: both;"></div>' + 
-
 
1516
			($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? 
1515
		html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
1517
			'<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : '');
1516
			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
1518
		inst._keyEvent = false;
1517
		inst._keyEvent = false;
1519
		return html;
1518
		return html;
1520
	},
1519
	},
1521
	
1520
 
1522
	/* Generate the month and year header. */
1521
	/* Generate the month and year header. */
1523
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1522
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1524
			selectedDate, secondary, showStatus, initStatus, monthNames) {
1523
			secondary, monthNames, monthNamesShort) {
-
 
1524
		var changeMonth = this._get(inst, 'changeMonth');
1525
		minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
1525
		var changeYear = this._get(inst, 'changeYear');
1526
		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
1526
		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
1527
		var html = '<div class="ui-datepicker-header">';
1527
		var html = '<div class="ui-datepicker-title">';
1528
		var monthHtml = '';
1528
		var monthHtml = '';
1529
		// month selection
1529
		// month selection
1530
		if (secondary || !this._get(inst, 'changeMonth'))
1530
		if (secondary || !changeMonth)
1531
			monthHtml += monthNames[drawMonth] + '&#xa0;';
1531
			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
1532
		else {
1532
		else {
1533
			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1533
			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1534
			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1534
			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1535
			monthHtml += '<select class="ui-datepicker-new-month" ' +
1535
			monthHtml += '<select class="ui-datepicker-month" ' +
1536
				'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
1536
				'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
1537
				'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1537
				'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1538
				this._addStatus(showStatus, inst.id, this._get(inst, 'monthStatus'), initStatus) + '>';
1538
			 	'>';
1539
			for (var month = 0; month < 12; month++) {
1539
			for (var month = 0; month < 12; month++) {
1540
				if ((!inMinYear || month >= minDate.getMonth()) &&
1540
				if ((!inMinYear || month >= minDate.getMonth()) &&
1541
						(!inMaxYear || month <= maxDate.getMonth()))
1541
						(!inMaxYear || month <= maxDate.getMonth()))
1542
					monthHtml += '<option value="' + month + '"' +
1542
					monthHtml += '<option value="' + month + '"' +
1543
						(month == drawMonth ? ' selected="selected"' : '') +
1543
						(month == drawMonth ? ' selected="selected"' : '') +
1544
						'>' + monthNames[month] + '</option>';
1544
						'>' + monthNamesShort[month] + '</option>';
1545
			}
1545
			}
1546
			monthHtml += '</select>';
1546
			monthHtml += '</select>';
1547
		}
1547
		}
1548
		if (!showMonthAfterYear)
1548
		if (!showMonthAfterYear)
1549
			html += monthHtml;
1549
			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
1550
		// year selection
1550
		// year selection
1551
		if (secondary || !this._get(inst, 'changeYear'))
1551
		if (secondary || !changeYear)
1552
			html += drawYear;
1552
			html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
1553
		else {
1553
		else {
1554
			// determine range of years to display
1554
			// determine range of years to display
1555
			var years = this._get(inst, 'yearRange').split(':');
1555
			var years = this._get(inst, 'yearRange').split(':');
1556
			var year = 0;
-
 
1557
			var endYear = 0;
1556
			var thisYear = new Date().getFullYear();
1558
			if (years.length != 2) {
-
 
1559
				year = drawYear - 10;
-
 
1560
				endYear = drawYear + 10;
1557
			var determineYear = function(value) {
1561
			} else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
1558
				var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
1562
				year = endYear = new Date().getFullYear();
1559
					(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
1563
				year += parseInt(years[0], 10);
1560
					parseInt(value, 10)));
1564
				endYear += parseInt(years[1], 10);
1561
				return (isNaN(year) ? thisYear : year);
1565
			} else {
1562
			};
1566
				year = parseInt(years[0], 10);
1563
			var year = determineYear(years[0]);
1567
				endYear = parseInt(years[1], 10);
1564
			var endYear = Math.max(year, determineYear(years[1] || ''));
1568
			}
-
 
1569
			year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1565
			year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1570
			endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1566
			endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1571
			html += '<select class="ui-datepicker-new-year" ' +
1567
			html += '<select class="ui-datepicker-year" ' +
1572
				'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
1568
				'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
1573
				'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1569
				'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1574
				this._addStatus(showStatus, inst.id, this._get(inst, 'yearStatus'), initStatus) + '>';
-
 
-
 
1570
				'>';
1575
			for (; year <= endYear; year++) {
1571
			for (; year <= endYear; year++) {
1576
				html += '<option value="' + year + '"' +
1572
				html += '<option value="' + year + '"' +
1577
					(year == drawYear ? ' selected="selected"' : '') +
1573
					(year == drawYear ? ' selected="selected"' : '') +
1578
					'>' + year + '</option>';
1574
					'>' + year + '</option>';
1579
			}
1575
			}
1580
			html += '</select>';
1576
			html += '</select>';
1581
		}
1577
		}
-
 
1578
		html += this._get(inst, 'yearSuffix');
1582
		if (showMonthAfterYear)
1579
		if (showMonthAfterYear)
1583
			html += monthHtml;
1580
			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
1584
		html += '</div>'; // Close datepicker_header
1581
		html += '</div>'; // Close datepicker_header
1585
		return html;
1582
		return html;
1586
	},
1583
	},
1587
	
-
 
1588
	/* Provide code to set and clear the status panel. */
-
 
1589
	_addStatus: function(showStatus, id, text, initStatus) {
-
 
1590
		return (showStatus ? ' onmouseover="jQuery(\'#ui-datepicker-status-' + id +
-
 
1591
			'\').html(\'' + (text || initStatus) + '\');" ' +
-
 
1592
			'onmouseout="jQuery(\'#ui-datepicker-status-' + id +
-
 
1593
			'\').html(\'' + initStatus + '\');"' : '');
-
 
1594
	},
-
 
1595
	
1584
 
1596
	/* Adjust one of the date sub-fields. */
1585
	/* Adjust one of the date sub-fields. */
1597
	_adjustInstDate: function(inst, offset, period) {
1586
	_adjustInstDate: function(inst, offset, period) {
1598
		var year = inst.drawYear + (period == 'Y' ? offset : 0);
1587
		var year = inst.drawYear + (period == 'Y' ? offset : 0);
1599
		var month = inst.drawMonth + (period == 'M' ? offset : 0);
1588
		var month = inst.drawMonth + (period == 'M' ? offset : 0);
1600
		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
1589
		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
1601
			(period == 'D' ? offset : 0);
1590
			(period == 'D' ? offset : 0);
1602
		var date = new Date(year, month, day);
-
 
1603
		// ensure it is within the bounds set
-
 
1604
		var minDate = this._getMinMaxDate(inst, 'min', true);
-
 
1605
		var maxDate = this._getMinMaxDate(inst, 'max');
1591
		var date = this._restrictMinMax(inst,
1606
		date = (minDate && date < minDate ? minDate : date);
-
 
1607
		date = (maxDate && date > maxDate ? maxDate : date);
1592
			this._daylightSavingAdjust(new Date(year, month, day)));
1608
		inst.selectedDay = date.getDate();
1593
		inst.selectedDay = date.getDate();
1609
		inst.drawMonth = inst.selectedMonth = date.getMonth();
1594
		inst.drawMonth = inst.selectedMonth = date.getMonth();
1610
		inst.drawYear = inst.selectedYear = date.getFullYear();
1595
		inst.drawYear = inst.selectedYear = date.getFullYear();
1611
		if (period == 'M' || period == 'Y')
1596
		if (period == 'M' || period == 'Y')
1612
			this._notifyChange(inst);
1597
			this._notifyChange(inst);
1613
	},
1598
	},
-
 
1599
 
-
 
1600
	/* Ensure a date is within any min/max bounds. */
-
 
1601
	_restrictMinMax: function(inst, date) {
-
 
1602
		var minDate = this._getMinMaxDate(inst, 'min');
-
 
1603
		var maxDate = this._getMinMaxDate(inst, 'max');
-
 
1604
		date = (minDate && date < minDate ? minDate : date);
-
 
1605
		date = (maxDate && date > maxDate ? maxDate : date);
-
 
1606
		return date;
-
 
1607
	},
1614
	
1608
 
1615
	/* Notify change of month/year. */
1609
	/* Notify change of month/year. */
1616
	_notifyChange: function(inst) {
1610
	_notifyChange: function(inst) {
1617
		var onChange = this._get(inst, 'onChangeMonthYear');
1611
		var onChange = this._get(inst, 'onChangeMonthYear');
1618
		if (onChange)
1612
		if (onChange)
1619
			onChange.apply((inst.input ? inst.input[0] : null),
1613
			onChange.apply((inst.input ? inst.input[0] : null),
1620
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
1614
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
1621
	},
1615
	},
1622
	
1616
 
1623
	/* Determine the number of months to show. */
1617
	/* Determine the number of months to show. */
1624
	_getNumberOfMonths: function(inst) {
1618
	_getNumberOfMonths: function(inst) {
1625
		var numMonths = this._get(inst, 'numberOfMonths');
1619
		var numMonths = this._get(inst, 'numberOfMonths');
1626
		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1620
		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1627
	},
1621
	},
1628
	
1622
 
1629
	/* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
1623
	/* Determine the current maximum date - ensure no time components are set. */
1630
	_getMinMaxDate: function(inst, minMax, checkRange) {
1624
	_getMinMaxDate: function(inst, minMax) {
1631
		var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
-
 
1632
		if (date) {
-
 
1633
			date.setHours(0);
-
 
1634
			date.setMinutes(0);
-
 
1635
			date.setSeconds(0);
-
 
1636
			date.setMilliseconds(0);
-
 
1637
		}
-
 
1638
		return (!checkRange || !inst.rangeStart ? date :
-
 
1639
			(!date || inst.rangeStart > date ? inst.rangeStart : date));
1625
		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
1640
	},
1626
	},
1641
	
1627
 
1642
	/* Find the number of days in a given month. */
1628
	/* Find the number of days in a given month. */
1643
	_getDaysInMonth: function(year, month) {
1629
	_getDaysInMonth: function(year, month) {
1644
		return 32 - new Date(year, month, 32).getDate();
1630
		return 32 - new Date(year, month, 32).getDate();
1645
	},
1631
	},
1646
	
1632
 
1647
	/* Find the day of the week of the first of a month. */
1633
	/* Find the day of the week of the first of a month. */
1648
	_getFirstDayOfMonth: function(year, month) {
1634
	_getFirstDayOfMonth: function(year, month) {
1649
		return new Date(year, month, 1).getDay();
1635
		return new Date(year, month, 1).getDay();
1650
	},
1636
	},
1651
	
1637
 
1652
	/* Determines if we should allow a "next/prev" month display change. */
1638
	/* Determines if we should allow a "next/prev" month display change. */
1653
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
1639
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
1654
		var numMonths = this._getNumberOfMonths(inst);
1640
		var numMonths = this._getNumberOfMonths(inst);
-
 
1641
		var date = this._daylightSavingAdjust(new Date(curYear,
1655
		var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
1642
			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
1656
		if (offset < 0)
1643
		if (offset < 0)
1657
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1644
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1658
		return this._isInRange(inst, date);
1645
		return this._isInRange(inst, date);
1659
	},
1646
	},
1660
	
1647
 
1661
	/* Is the given date in the accepted range? */
1648
	/* Is the given date in the accepted range? */
1662
	_isInRange: function(inst, date) {
1649
	_isInRange: function(inst, date) {
1663
		// during range selection, use minimum of selected date and range start
-
 
1664
		var newMinDate = (!inst.rangeStart ? null :
-
 
1665
			new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay));
-
 
1666
		newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
-
 
1667
		var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
1650
		var minDate = this._getMinMaxDate(inst, 'min');
1668
		var maxDate = this._getMinMaxDate(inst, 'max');
1651
		var maxDate = this._getMinMaxDate(inst, 'max');
1669
		return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
1652
		return ((!minDate || date.getTime() >= minDate.getTime()) &&
-
 
1653
			(!maxDate || date.getTime() <= maxDate.getTime()));
1670
	},
1654
	},
1671
	
1655
 
1672
	/* Provide the configuration settings for formatting/parsing. */
1656
	/* Provide the configuration settings for formatting/parsing. */
1673
	_getFormatConfig: function(inst) {
1657
	_getFormatConfig: function(inst) {
1674
		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
1658
		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
1675
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1659
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1676
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1660
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1677
		return {shortYearCutoff: shortYearCutoff,
1661
		return {shortYearCutoff: shortYearCutoff,
1678
			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
1662
			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
1679
			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
1663
			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
1680
	},
1664
	},
1681
	
1665
 
1682
	/* Format the given date for display. */
1666
	/* Format the given date for display. */
1683
	_formatDate: function(inst, day, month, year) {
1667
	_formatDate: function(inst, day, month, year) {
1684
		if (!day) {
1668
		if (!day) {
1685
			inst.currentDay = inst.selectedDay;
1669
			inst.currentDay = inst.selectedDay;
1686
			inst.currentMonth = inst.selectedMonth;
1670
			inst.currentMonth = inst.selectedMonth;
1687
			inst.currentYear = inst.selectedYear;
1671
			inst.currentYear = inst.selectedYear;
1688
		}
1672
		}
1689
		var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
1673
		var date = (day ? (typeof day == 'object' ? day :
-
 
1674
			this._daylightSavingAdjust(new Date(year, month, day))) :
1690
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1675
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1691
		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
1676
		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
1692
	}
1677
	}
1693
});
1678
});
1694
 
1679
 
1695
/* jQuery extend now ignores nulls! */
1680
/* jQuery extend now ignores nulls! */
1696
function extendRemove(target, props) {
1681
function extendRemove(target, props) {
1697
	$.extend(target, props);
1682
	$.extend(target, props);
1698
	for (var name in props)
1683
	for (var name in props)
1699
		if (props[name] == null || props[name] == undefined)
1684
		if (props[name] == null || props[name] == undefined)
1700
			target[name] = props[name];
1685
			target[name] = props[name];
1701
	return target;
1686
	return target;
1702
};
1687
};
1703
 
1688
 
1704
/* Determine whether an object is an array. */
1689
/* Determine whether an object is an array. */
1705
function isArray(a) {
1690
function isArray(a) {
1706
	return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
1691
	return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
1707
		(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
1692
		(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
1708
};
1693
};
1709
 
1694
 
1710
/* Invoke the datepicker functionality.
1695
/* Invoke the datepicker functionality.
1711
   @param  options  string - a command, optionally followed by additional parameters or
1696
   @param  options  string - a command, optionally followed by additional parameters or
1712
                    Object - settings for attaching new datepicker functionality
1697
                    Object - settings for attaching new datepicker functionality
1713
   @return  jQuery object */
1698
   @return  jQuery object */
1714
$.fn.datepicker = function(options){
1699
$.fn.datepicker = function(options){
1715
	
1700
 
1716
	/* Initialise the date picker. */
1701
	/* Initialise the date picker. */
1717
	if (!$.datepicker.initialized) {
1702
	if (!$.datepicker.initialized) {
1718
		$(document.body).append($.datepicker.dpDiv).
1703
		$(document).mousedown($.datepicker._checkExternalClick).
1719
			mousedown($.datepicker._checkExternalClick);
1704
			find('body').append($.datepicker.dpDiv);
1720
		$.datepicker.initialized = true;
1705
		$.datepicker.initialized = true;
1721
	}
1706
	}
1722
	
1707
 
1723
	var otherArgs = Array.prototype.slice.call(arguments, 1);
1708
	var otherArgs = Array.prototype.slice.call(arguments, 1);
1724
	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
1709
	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
-
 
1710
		return $.datepicker['_' + options + 'Datepicker'].
-
 
1711
			apply($.datepicker, [this[0]].concat(otherArgs));
-
 
1712
	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
1725
		return $.datepicker['_' + options + 'Datepicker'].
1713
		return $.datepicker['_' + options + 'Datepicker'].
1726
			apply($.datepicker, [this[0]].concat(otherArgs));
1714
			apply($.datepicker, [this[0]].concat(otherArgs));
1727
	return this.each(function() {
1715
	return this.each(function() {
1728
		typeof options == 'string' ?
1716
		typeof options == 'string' ?
1729
			$.datepicker['_' + options + 'Datepicker'].
1717
			$.datepicker['_' + options + 'Datepicker'].
1730
				apply($.datepicker, [this].concat(otherArgs)) :
1718
				apply($.datepicker, [this].concat(otherArgs)) :
1731
			$.datepicker._attachDatepicker(this, options);
1719
			$.datepicker._attachDatepicker(this, options);
1732
	});
1720
	});
1733
};
1721
};
1734
 
1722
 
1735
$.datepicker = new Datepicker(); // singleton instance
1723
$.datepicker = new Datepicker(); // singleton instance
1736
$.datepicker.initialized = false;
1724
$.datepicker.initialized = false;
1737
$.datepicker.uuid = new Date().getTime();
1725
$.datepicker.uuid = new Date().getTime();
1738
$.datepicker.version = "@VERSION";
1726
$.datepicker.version = "1.8.6";
-
 
1727
 
-
 
1728
// Workaround for #4055
-
 
1729
// Add another global to avoid noConflict issues with inline event handlers
-
 
1730
window['DP_jQuery_' + dpuuid] = $;
1739
 
1731
 
1740
})(jQuery);
1732
})(jQuery);