PageSourceSearch

https://georgianhousehotel.com/bedrooms/jquery.datepicker.js

js georgianhousehotel.com collected 2026-10-07 19:51:07 UTC 36,564 bytes, 1,056 lines download raw bytes

1/**
2 * Copyright (c) 2008 Kelvin Luck (http://www.kelvinluck.com/)
3 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
4 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
5 *
6 * $Id: jquery.datePicker.js 5 2008-12-02 23:43:08Z kelvin.luck $
7 **/
8
9(function($){
10    
11	$.fn.extend({
12/**
13 * Render a calendar table into any matched elements.
14 * 
15 * @param Object s (optional) Customize your calendars.
16 * @option Number month The month to render (NOTE that months are zero based). Default is today's month.
17 * @option Number year The year to render. Default is today's year.
18 * @option Function renderCallback A reference to a function that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Default is no callback.
19 * @option Number showHeader Whether or not to show the header row, possible values are: $.dpConst.SHOW_HEADER_NONE (no header), $.dpConst.SHOW_HEADER_SHORT (first letter of each day) and $.dpConst.SHOW_HEADER_LONG (full name of each day). Default is $.dpConst.SHOW_HEADER_SHORT.
20 * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class.
21 * @type jQuery
22 * @name renderCalendar
23 * @cat plugins/datePicker
24 * @author Kelvin Luck (http://www.kelvinluck.com/)
25 *
26 * @example $('#calendar-me').renderCalendar({month:0, year:2007});
27 * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me.
28 *
29 * @example
30 * var testCallback = function($td, thisDate, month, year)
31 * {
32 * if ($td.is('.current-month') && thisDate.getDay() == 4) {
33 *		var d = thisDate.getDate();
34 *		$td.bind(
35 *			'click',
36 *			function()
37 *			{
38 *				alert('You clicked on ' + d + '/' + (Number(month)+1) + '/' + year);
39 *			}
40 *		).addClass('thursday');
41 *	} else if (thisDate.getDay() == 5) {
42 *		$td.html('Friday the ' + $td.html() + 'th');
43 *	}
44 * }
45 * $('#calendar-me').renderCalendar({month:0, year:2007, renderCallback:testCallback});
46 * 
47 * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. Every Thursday in the current month has a class of "thursday" applied to it, is clickable and shows an alert when clicked. Every Friday on the calendar has the number inside replaced with text.
48 **/
49		renderCalendar  :   function(s)
50		{
51			var dc = function(a)
52			{
53				return document.createElement(a);
54			};
55			
56			s = $.extend(
57				{
58					month			: null,
59					year			: null,
60					renderCallback	: null,
61					showHeader		: $.dpConst.SHOW_HEADER_SHORT,
62					dpController	: null,
63					hoverClass		: 'dp-hover'
64				}
65				, s
66			);
67			
68			if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
69				var headRow = $(dc('tr'));
70				for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {
71					var weekday = i%7;
72					var day = Date.dayNames[weekday];
73					headRow.append(
74						jQuery(dc('th')).attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)
75					);
76				}
77			};
78			
79			var calendarTable = $(dc('table'))
80									.attr(
81										{
82											'cellspacing':2,
83											'className':'jCalendar'
84										}
85									)
86									.append(
87										(s.showHeader != $.dpConst.SHOW_HEADER_NONE ? 
88											$(dc('thead'))
89												.append(headRow)
90											:
91											dc('thead')
92										)
93									);
94			var tbody = $(dc('tbody'));
95			
96			var today = (new Date()).zeroTime();
97			
98			var month = s.month == undefined ? today.getMonth() : s.month;
99			var year = s.year || today.getFullYear();
100			
101			var currentDate = new Date(year, month, 1);
102			
103			
104			var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;
105			if (firstDayOffset > 1) firstDayOffset -= 7;
106			var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);
107			currentDate.addDays(firstDayOffset-1);
108			
109			var doHover = function()
110			{
111				if (s.hoverClass) {
112					$(this).addClass(s.hoverClass);
113				}
114			};
115			var unHover = function()
116			{
117				if (s.hoverClass) {
118					$(this).removeClass(s.hoverClass);
119				}
120			};
121			
122			var w = 0;
123			while (w++<weeksToDraw) {
124				var r = jQuery(dc('tr'));
125				for (var i=0; i<7; i++) {
126					var thisMonth = currentDate.getMonth() == month;
127					var d = $(dc('td'))
128								.text(currentDate.getDate() + '')
129								.attr('className', (thisMonth ? 'current-month ' : 'other-month ') +
130													(currentDate.isWeekend() ? 'weekend ' : 'weekday ') +
131													(thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')
132								)
133								.hover(doHover, unHover)
134							;
135					if (s.renderCallback) {
136						s.renderCallback(d, currentDate, month, year);
137					}
138					r.append(d);
139					currentDate.addDays(1);
140				}
141				tbody.append(r);
142			}
143			calendarTable.append(tbody);
144			
145			return this.each(
146				function()
147				{
148					$(this).empty().append(calendarTable);
149				}
150			);
151		},
152/**
153 * Create a datePicker associated with each of the matched elements.
154 *
155 * The matched element will receive a few custom events with the following signatures:
156 *
157 * dateSelected(event, date, $td, status)
158 * Triggered when a date is selected. event is a reference to the event, date is the Date selected, $td is a jquery object wrapped around the TD that was clicked on and status is whether the date was selected (true) or deselected (false)
159 * 
160 * dpClosed(event, selected)
161 * Triggered when the date picker is closed. event is a reference to the event and selected is an Array containing Date objects.
162 *
163 * dpMonthChanged(event, displayedMonth, displayedYear)
164 * Triggered when the month of the popped up calendar is changed. event is a reference to the event, displayedMonth is the number of the month now displayed (zero based) and displayedYear is the year of the month.
165 *
166 * dpDisplayed(event, $datePickerDiv)
167 * Triggered when the date picker is created. $datePickerDiv is the div containing the date picker. Use this event to add custom content/ listeners to the popped up date picker.
168 *
169 * @param Object s (optional) Customize your date pickers.
170 * @option Number month The month to render when the date picker is opened (NOTE that months are zero based). Default is today's month.
171 * @option Number year The year to render when the date picker is opened. Default is today's year.
172 * @option String startDate The first date date can be selected.
173 * @option String endDate The last date that can be selected.
174 * @option Boolean inline Whether to create the datePicker as inline (e.g. always on the page) or as a model popup. Default is false (== modal popup)
175 * @option Boolean createButton Whether to create a .dp-choose-date anchor directly after the matched element which when clicked will trigger the showing of the date picker. Default is true.
176 * @option Boolean showYearNavigation Whether to display buttons which allow the user to navigate through the months a year at a time. Default is true.
177 * @option Boolean closeOnSelect Whether to close the date picker when a date is selected. Default is true.
178 * @option Boolean displayClose Whether to create a "Close" button within the date picker popup. Default is false.
179 * @option Boolean selectMultiple Whether a user should be able to select multiple dates with this date picker. Default is false.
180 * @option Boolean clickInput If the matched element is an input type="text" and this option is true then clicking on the input will cause the date picker to appear.
181 * @option Number verticalPosition The vertical alignment of the popped up date picker to the matched element. One of $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM. Default is $.dpConst.POS_TOP.
182 * @option Number horizontalPosition The horizontal alignment of the popped up date picker to the matched element. One of $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT.
183 * @option Number verticalOffset The number of pixels offset from the defined verticalPosition of this date picker that it should pop up in. Default in 0.
184 * @option Number horizontalOffset The number of pixels offset from the defined horizontalPosition of this date picker that it should pop up in. Default in 0.
185 * @option (Function|Array) renderCallback A reference to a function (or an array of seperate functions) that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Each callback function will receive four arguments;
185 a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. Default is no callback.
186 * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class.
187 * @type jQuery
188 * @name datePicker
189 * @cat plugins/datePicker
190 * @author Kelvin Luck (http://www.kelvinluck.com/)
191 *
192 * @example $('input.date-picker').datePicker();
193 * @desc Creates a date picker button next to all matched input elements. When the button is clicked on the value of the selected date will be placed in the corresponding input (formatted according to Date.format).
194 *
195 * @example demo/index.html
196 * @desc See the projects homepage for many more complex examples...
197 **/
198		datePicker : function(s)
199		{			
200			if (!$.event._dpCache) $.event._dpCache = [];
201			
202			// initialise the date picker controller with the relevant settings...
203			s = $.extend(
204				{
205					month				: undefined,
206					year				: undefined,
207					startDate			: undefined,
208					endDate				: undefined,
209					inline				: false,
210					renderCallback		: [],
211					createButton		: true,
212					showYearNavigation	: true,
213					closeOnSelect		: true,
214					displayClose		: false,
215					selectMultiple		: false,
216					clickInput			: false,
217					verticalPosition	: $.dpConst.POS_TOP,
218					horizontalPosition	: $.dpConst.POS_LEFT,
219					verticalOffset		: 0,
220					horizontalOffset	: 0,
221					hoverClass			: 'dp-hover'
222				}
223				, s
224			);
225			
226			return this.each(
227				function()
228				{
229					var $this = $(this);
230					var alreadyExists = true;
231					
232					if (!this._dpId) {
233						this._dpId = $.event.guid++;
234						$.event._dpCache[this._dpId] = new DatePicker(this);
235						alreadyExists = false;
236					}
237					
238					if (s.inline) {
239						s.createButton = false;
240						s.displayClose = false;
241						s.closeOnSelect = false;
242						$this.empty();
243					}
244					
245					var controller = $.event._dpCache[this._dpId];
246					
247					controller.init(s);
248					
249					if (!alreadyExists && s.createButton) {
250						// create it!
251						controller.button = $('<a href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '">' + $.dpText.TEXT_CHOOSE_DATE + '</a>')
252								.bind(
253									'click',
254									function()
255									{
256										$this.dpDisplay(this);
257										this.blur();
258										return false;
259									}
260								);
261						$this.after(controller.button);
262					}
263					
264					if (!alreadyExists && $this.is(':text')) {
265						$this
266							.bind(
267								'dateSelected',
268								function(e, selectedDate, $td)
269								{
270									this.value = selectedDate.asString();
271								}
272							).bind(
273								'change',
274								function()
275								{
276									var d = Date.fromString(this.value);
277									if (d) {
278										controller.setSelected(d, true, true);
279									}
280								}
281							);
282						if (s.clickInput) {
283							$this.bind(
284								'click',
285								function()
286								{
287									$this.dpDisplay();
288								}
289							);
290						}
291						var d = Date.fromString(this.value);
292						if (this.value != '' && d) {
293							controller.setSelected(d, true, true);
294						}
295					}
296					
297					$this.addClass('dp-applied');
298					
299				}
300			)
301		},
302/**
303 * Disables or enables this date picker
304 *
305 * @param Boolean s Whether to disable (true) or enable (false) this datePicker
306 * @type jQuery
307 * @name dpSetDisabled
308 * @cat plugins/datePicker
309 * @author Kelvin Luck (http://www.kelvinluck.com/)
310 *
311 * @example $('.date-picker').datePicker();
312 * $('.date-picker').dpSetDisabled(true);
313 * @desc Prevents this date picker from displaying and adds a class of dp-disabled to it (and it's associated button if it has one) for styling purposes. If the matched element is an input field then it will also set the disabled attribute to stop people directly editing the field.
314 **/
315		dpSetDisabled : function(s)
316		{
317			return _w.call(this, 'setDisabled', s);
318		},
319/**
320 * Updates the first selectable date for any date pickers on any matched elements.
321 *
322 * @param String d A string representing the first selectable date (formatted according to Date.format).
323 * @type jQuery
324 * @name dpSetStartDate
325 * @cat plugins/datePicker
326 * @author Kelvin Luck (http://www.kelvinluck.com/)
327 *
328 * @example $('.date-picker').datePicker();
329 * $('.date-picker').dpSetStartDate('01/01/2000');
330 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the first selectable date for each of these to the first day of the millenium.
331 **/
332		dpSetStartDate : function(d)
333		{
334			return _w.call(this, 'setStartDate', d);
335		},
336/**
337 * Updates the last selectable date for any date pickers on any matched elements.
338 *
339 * @param String d A string representing the last selectable date (formatted according to Date.format).
340 * @type jQuery
341 * @name dpSetEndDate
342 * @cat plugins/datePicker
343 * @author Kelvin Luck (http://www.kelvinluck.com/)
344 *
345 * @example $('.date-picker').datePicker();
346 * $('.date-picker').dpSetEndDate('01/01/2010');
347 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the last selectable date for each of these to the first Janurary 2010.
348 **/
349		dpSetEndDate : function(d)
350		{
351			return _w.call(this, 'setEndDate', d);
352		},
353/**
354 * Gets a list of Dates currently selected by this datePicker. This will be an empty array if no dates are currently selected or NULL if there is no datePicker associated with the matched element.
355 *
356 * @type Array
357 * @name dpGetSelected
358 * @cat plugins/datePicker
359 * @author Kelvin Luck (http://www.kelvinluck.com/)
360 *
361 * @example $('.date-picker').datePicker();
362 * alert($('.date-picker').dpGetSelected());
363 * @desc Will alert an empty array (as nothing is selected yet)
364 **/
365		dpGetSelected : function()
366		{
367			var c = _getController(this[0]);
368			if (c) {
369				return c.getSelected();
370			}
371			return null;
372		},
373/**
374 * Selects or deselects a date on any matched element's date pickers. Deselcting is only useful on date pickers where selectMultiple==true. Selecting will only work if the passed date is within the startDate and endDate boundries for a given date picker.
375 *
376 * @param String d A string representing the date you want to select (formatted according to Date.format).
377 * @param Boolean v Whether you want to select (true) or deselect (false) this date. Optional - default = true.
378 * @param Boolean m Whether you want the date picker to open up on the month of this date when it is next opened. Optional - default = true.
379 * @type jQuery
380 * @name dpSetSelected
381 * @cat plugins/datePicker
382 * @author Kelvin Luck (http://www.kelvinluck.com/)
383 *
384 * @example $('.date-picker').datePicker();
385 * $('.date-picker').dpSetSelected('01/01/2010');
386 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010.
387 **/
388		dpSetSelected : function(d, v, m)
389		{
390			if (v == undefined) v=true;
391			if (m == undefined) m=true;
392			return _w.call(this, 'setSelected', Date.fromString(d), v, m);
393		},
394/**
395 * Sets the month that will be displayed when the date picker is next opened. If the passed month is before startDate then the month containing startDate will be displayed instead. If the passed month is after endDate then the month containing the endDate will be displayed instead.
396 *
397 * @param Number m The month you want the date picker to display. Optional - defaults to the currently displayed month.
398 * @param Number y The year you want the date picker to display. Optional - defaults to the currently displayed year.
399 * @type jQuery
400 * @name dpSetDisplayedMonth
401 * @cat plugins/datePicker
402 * @author Kelvin Luck (http://www.kelvinluck.com/)
403 *
404 * @example $('.date-picker').datePicker();
405 * $('.date-picker').dpSetDisplayedMonth(10, 2008);
406 * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010.
407 **/
408		dpSetDisplayedMonth : function(m, y)
409		{
410			return _w.call(this, 'setDisplayedMonth', Number(m), Number(y));
411		},
412/**
413 * Displays the date picker associated with the matched elements. Since only one date picker can be displayed at once then the date picker associated with the last matched element will be the one that is displayed.
414 *
415 * @param HTMLElement e An element that you want the date picker to pop up relative in position to. Optional - default behaviour is to pop up next to the element associated with this date picker.
416 * @type jQuery
417 * @name dpDisplay
418 * @cat plugins/datePicker
419 * @author Kelvin Luck (http://www.kelvinluck.com/)
420 *
421 * @example $('#date-picker').datePicker();
422 * $('#date-picker').dpDisplay();
423 * @desc Creates a date picker associated with the element with an id of date-picker and then causes it to pop up.
424 **/
425		dpDisplay : function(e)
426		{
427			return _w.call(this, 'display', e);
428		},
429/**
430 * Sets a function or array of functions that is called when each TD of the date picker popup is rendered to the page
431 *
432 * @param (Function|Array) a A function or an array of functions that are called when each td is rendered. Each function will receive four arguments;
432 a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year.
433 * @type jQuery
434 * @name dpSetRenderCallback
435 * @cat plugins/datePicker
436 * @author Kelvin Luck (http://www.kelvinluck.com/)
437 *
438 * @example $('#date-picker').datePicker();
439 * $('#date-picker').dpSetRenderCallback(function($td, thisDate, month, year)
440 * {
441 * 	// do stuff as each td is rendered dependant on the date in the td and the displayed month and year
442 * });
443 * @desc Creates a date picker associated with the element with an id of date-picker and then creates a function which is called as each td is rendered when this date picker is displayed.
444 **/
445		dpSetRenderCallback : function(a)
446		{
447			return _w.call(this, 'setRenderCallback', a);
448		},
449/**
450 * Sets the position that the datePicker will pop up (relative to it's associated element)
451 *
452 * @param Number v The vertical alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM
453 * @param Number h The horizontal alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT
454 * @type jQuery
455 * @name dpSetPosition
456 * @cat plugins/datePicker
457 * @author Kelvin Luck (http://www.kelvinluck.com/)
458 *
459 * @example $('#date-picker').datePicker();
460 * $('#date-picker').dpSetPosition($.dpConst.POS_BOTTOM, $.dpConst.POS_RIGHT);
461 * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be bottom and right aligned to the #date-picker element.
462 **/
463		dpSetPosition : function(v, h)
464		{
465			return _w.call(this, 'setPosition', v, h);
466		},
467/**
468 * Sets the offset that the popped up date picker will have from it's default position relative to it's associated element (as set by dpSetPosition)
469 *
470 * @param Number v The vertical offset of the created date picker.
471 * @param Number h The horizontal offset of the created date picker.
472 * @type jQuery
473 * @name dpSetOffset
474 * @cat plugins/datePicker
475 * @author Kelvin Luck (http://www.kelvinluck.com/)
476 *
477 * @example $('#date-picker').datePicker();
478 * $('#date-picker').dpSetOffset(-20, 200);
479 * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be 20 pixels above and 200 pixels to the right of it's default position.
480 **/
481		dpSetOffset : function(v, h)
482		{
483			return _w.call(this, 'setOffset', v, h);
484		},
485/**
486 * Closes the open date picker associated with this element.
487 *
488 * @type jQuery
489 * @name dpClose
490 * @cat plugins/datePicker
491 * @author Kelvin Luck (http://www.kelvinluck.com/)
492 *
493 * @example $('.date-pick')
494 *		.datePicker()
495 *		.bind(
496 *			'focus',
497 *			function()
498 *			{
499 *				$(this).dpDisplay();
500 *			}
501 *		).bind(
502 *			'blur',
503 *			function()
504 *			{
505 *				$(this).dpClose();
506 *			}
507 *		);
508 * @desc Creates a date picker and makes it appear when the relevant element is focused and disappear when it is blurred.
509 **/
510		dpClose : function()
511		{
512			return _w.call(this, '_closeCalendar', false, this[0]);
513		},
514		// private function called on unload to clean up any expandos etc and prevent memory links...
515		_dpDestroy : function()
516		{
517			// TODO - implement this?
518		}
519	});
520	
521	// private internal function to cut down on the amount of code needed where we forward
522	// dp* methods on the jQuery object on to the relevant DatePicker controllers...
523	var _w = function(f, a1, a2, a3)
524	{
525		return this.each(
526			function()
527			{
528				var c = _getController(this);
529				if (c) {
530					c[f](a1, a2, a3);
531				}
532			}
533		);
534	};
535	
536	function DatePicker(ele)
537	{
538		this.ele = ele;
539		
540		// initial values...
541		this.displayedMonth		=	null;
542		this.displayedYear		=	null;
543		this.startDate			=	null;
544		this.endDate			=	null;
545		this.showYearNavigation	=	null;
546		this.closeOnSelect		=	null;
547		this.displayClose		=	null;
548		this.selectMultiple		=	null;
549		this.verticalPosition	=	null;
550		this.horizontalPosition	=	null;
551		this.verticalOffset		=	null;
552		this.horizontalOffset	=	null;
553		this.button				=	null;
554		this.renderCallback		=	[];
555		this.selectedDates		=	{};
556		this.inline				=	null;
557		this.context			=	'#dp-popup';
558	};
559	$.extend(
560		DatePicker.prototype,
561		{	
562			init : function(s)
563			{
564				this.setStartDate(s.startDate);
565				this.setEndDate(s.endDate);
566				this.setDisplayedMonth(Number(s.month), Number(s.year));
567				this.setRenderCallback(s.renderCallback);
568				this.showYearNavigation = s.showYearNavigation;
569				this.closeOnSelect = s.closeOnSelect;
570				this.displayClose = s.displayClose;
571				this.selectMultiple = s.selectMultiple;
572				this.verticalPosition = s.verticalPosition;
573				this.horizontalPosition = s.horizontalPosition;
574				this.hoverClass = s.hoverClass;
575				this.setOffset(s.verticalOffset, s.horizontalOffset);
576				this.inline = s.inline;
577				if (this.inline) {
578					this.context = this.ele;
579					this.display();
580				}
581			},
582			setStartDate : function(d)
583			{
584				if (d) {
585					this.startDate = Date.fromString(d);
586				}
587				if (!this.startDate) {
588					this.startDate = (new Date()).zeroTime();
589				}
590				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
591			},
592			setEndDate : function(d)
593			{
594				if (d) {
595					this.endDate = Date.fromString(d);
596				}
597				if (!this.endDate) {
598					this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy
599				}
600				if (this.endDate.getTime() < this.startDate.getTime()) {
601					this.endDate = this.startDate;
602				}
603				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
604			},
605			setPosition : function(v, h)
606			{
607				this.verticalPosition = v;
608				this.horizontalPosition = h;
609			},
610			setOffset : function(v, h)
611			{
612				this.verticalOffset = parseInt(v) || 0;
613				this.horizontalOffset = parseInt(h) || 0;
614			},
615			setDisabled : function(s)
616			{
617				$e = $(this.ele);
618				$e[s ? 'addClass' : 'removeClass']('dp-disabled');
619				if (this.button) {
620					$but = $(this.button);
621					$but[s ? 'addClass' : 'removeClass']('dp-disabled');
622					$but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);
623				}
624				if ($e.is(':text')) {
625					$e.attr('disabled', s ? 'disabled' : '');
626				}
627			},
628			setDisplayedMonth : function(m, y)
629			{
630				if (this.startDate == undefined || this.endDate == undefined) {
631					return;
632				}
633				var s = new Date(this.startDate.getTime());
634				s.setDate(1);
635				var e = new Date(this.endDate.getTime());
636				e.setDate(1);
637				
638				var t;
639				if ((!m && !y) || (isNaN(m) && isNaN(y))) {
640					// no month or year passed - default to current month
641					t = new Date().zeroTime();
642					t.setDate(1);
643				} else if (isNaN(m)) {
644					// just year passed in - presume we want the displayedMonth
645					t = new Date(y, this.displayedMonth, 1);
646				} else if (isNaN(y)) {
647					// just month passed in - presume we want the displayedYear
648					t = new Date(this.displayedYear, m, 1);
649				} else {
650					// year and month passed in - that's the date we want!
651					t = new Date(y, m, 1)
652				}
653				
654				// check if the desired date is within the range of our defined startDate and endDate
655				if (t.getTime() < s.getTime()) {
656					t = s;
657				} else if (t.getTime() > e.getTime()) {
658					t = e;
659				}
660				this.displayedMonth = t.getMonth();
661				this.displayedYear = t.getFullYear();
662			},
663			setSelected : function(d, v, moveToMonth)
664			{
665				if (this.selectMultiple == false) {
666					this.selectedDates = {};
667					$('td.selected', this.context).removeClass('selected');
668				}
669				if (moveToMonth) {
670					this.setDisplayedMonth(d.getMonth(), d.getFullYear());
671				}
672				this.selectedDates[d.toString()] = v;
673			},
674			isSelected : function(d)
675			{
676				return this.selectedDates[d.toString()];
677			},
678			getSelected : function()
679			{
680				var r = [];
681				for(s in this.selectedDates) {
682					if (this.selectedDates[s] == true) {
683						r.push(Date.parse(s));
684					}
685				}
686				return r;
687			},
688			display : function(eleAlignTo)
689			{
690				if ($(this.ele).is('.dp-disabled')) return;
691				
692				eleAlignTo = eleAlignTo || this.ele;
693				var c = this;
694				var $ele = $(eleAlignTo);
695				var eleOffset = $ele.offset();
696				
697				var $createIn;
698				var attrs;
699				var attrsCalendarHolder;
700				var cssRules;
701				
702				if (c.inline) {
703					$createIn = $(this.ele);
704					attrs = {
705						'id'		:	'calendar-' + this.ele._dpId,
706						'className'	:	'dp-popup dp-popup-inline'
707					};
708					cssRules = {
709					};
710				} else {
711					$createIn = $('body');
712					attrs = {
713						'id'		:	'dp-popup',
714						'className'	:	'dp-popup'
715					};
716					cssRules = {
717						'top'	:	eleOffset.top + c.verticalOffset,
718						'left'	:	eleOffset.left + c.horizontalOffset
719					};
720					
721					var _checkMouse = function(e)
722					{
723						var el = e.target;
724						var cal = $('#dp-popup')[0];
725						
726						while (true){
727							if (el == cal) {
728								return true;
729							} else if (el == document) {
730								c._closeCalendar();
731								return false;
732							} else {
733								el = $(el).parent()[0];
734							}
735						}
736					};
737					this._checkMouse = _checkMouse;
738				
739					this._closeCalendar(true);
740				}
741				
742				
743				$createIn
744					.append(
745						$('<div></div>')
746							.attr(attrs)
747							.css(cssRules)
748							.append(
749								$('<h2></h2>'),
750								$('<div class="dp-nav-prev"></div>')
751									.append(
752										$('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '"><<</a>')
753											.bind(
754												'click',
755												function()
756												{
757													return c._displayNewMonth.call(c, this, 0, -1);
758												}
759											),
760										$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '"><</a>')
761											.bind(
762												'click',
763												function()
764												{
765													return c._displayNewMonth.call(c, this, -1, 0);
766												}
767											)
768									),
769								$('<div class="dp-nav-next"></div>')
770									.append(
771										$('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '">>></a>')
772											.bind(
773												'click',
774												function()
775												{
776													return c._displayNewMonth.call(c, this, 0, 1);
777												}
778											),
779										$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '">></a>')
780											.bind(
781												'click',
782												function()
783												{
784													return c._displayNewMonth.call(c, this, 1, 0);
785												}
786											)
787									),
788								$('<div></div>')
789									.attr('className', 'dp-calendar')
790							)
791							.bgIframe()
792						);
793					
794				var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');
795				
796				if (this.showYearNavigation == false) {
797					$('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');
798				}
799				if (this.displayClose) {
800					$pop.append(
801						$('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')
802							.bind(
803								'click',
804								function()
805								{
806									c._closeCalendar();
807									return false;
808								}
809							)
810					);
811				}
812				c._renderCalendar();
813				
814				$(this.ele).trigger('dpDisplayed', $pop);
815				
816				if (!c.inline) {
817					if (this.verticalPosition == $.dpConst.POS_BOTTOM) {
818						$pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);
819					}
820					if (this.horizontalPosition == $.dpConst.POS_RIGHT) {
821						$pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);
822					}
823					$(document).bind('mousedown', this._checkMouse);
824				}
825			},
826			setRenderCallback : function(a)
827			{
828				if (a && typeof(a) == 'function') {
829					a = [a];
830				}
831				this.renderCallback = this.renderCallback.concat(a);
832			},
833			cellRender : function ($td, thisDate, month, year) {
834				var c = this.dpController;
835				var d = new Date(thisDate.getTime());
836				
837				// add our click handlers to deal with it when the days are clicked...
838				
839				$td.bind(
840					'click',
841					function()
842					{
843						var $this = $(this);
844						if (!$this.is('.disabled')) {
845							c.setSelected(d, !$this.is('.selected') || !c.selectMultiple);
846							var s = c.isSelected(d);
847							$(c.ele).trigger('dateSelected', [d, $td, s]);
848							$(c.ele).trigger('change');
849							if (c.closeOnSelect) {
850								c._closeCalendar();
851							} else {
852								$this[s ? 'addClass' : 'removeClass']('selected');
853							}
854						}
855					}
856				);
857				
858				if (c.isSelected(d)) {
859					$td.addClass('selected');
860				}
861				
862				// call any extra renderCallbacks that were passed in
863				for (var i=0; i<c.renderCallback.length; i++) {
864					c.renderCallback[i].apply(this, arguments);
865				}
866				
867				
868			},
869			// ele is the clicked button - only proceed if it doesn't have the class disabled...
870			// m and y are -1, 0 or 1 depending which direction we want to go in...
871			_displayNewMonth : function(ele, m, y) 
872			{
873				if (!$(ele).is('.disabled')) {
874					this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y);
875					this._clearCalendar();
876					this._renderCalendar();
877					$(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);
878				}
879				ele.blur();
880				return false;
881			},
882			_renderCalendar : function()
883			{
884				// set the title...
885				$('h2', this.context).html(Date.monthNames[this.displayedMonth] + ' ' + this.displayedYear);
886				
887				// render the calendar...
888				$('.dp-calendar', this.context).renderCalendar(
889					{
890						month			: this.displayedMonth,
891						year			: this.displayedYear,
892						renderCallback	: this.cellRender,
893						dpController	: this,
894						hoverClass		: this.hoverClass
895					}
896				);
897				
898				// update the status of the control buttons and disable dates before startDate or after endDate...
899				// TODO: When should the year buttons be disabled? When you can't go forward a whole year from where you are or is that annoying?
900				if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {
901					$('.dp-nav-prev-year', this.context).addClass('disabled');
902					$('.dp-nav-prev-month', this.context).addClass('disabled');
903					$('.dp-calendar td.other-month', this.context).each(
904						function()
905						{
906							var $this = $(this);
907							if (Number($this.text()) > 20) {
908								$this.addClass('disabled');
909							}
910						}
911					);
912					var d = this.startDate.getDate();
913					$('.dp-calendar td.current-month', this.context).each(
914						function()
915						{
916							var $this = $(this);
917							if (Number($this.text()) < d) {
918								$this.addClass('disabled');
919							}
920						}
921					);
922				} else {
923					$('.dp-nav-prev-year', this.context).removeClass('disabled');
924					$('.dp-nav-prev-month', this.context).removeClass('disabled');
925					var d = this.startDate.getDate();
926					if (d > 20) {
927						// check if the startDate is last month as we might need to add some disabled classes...
928						var sd = new Date(this.startDate.getTime());
929						sd.addMonths(1);
930						if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {
931							$('dp-calendar td.other-month', this.context).each(
932								function()
933								{
934									var $this = $(this);
935									if (Number($this.text()) < d) {
936										$this.addClass('disabled');
937									}
938								}
939							);
940						}
941					}
942				}
943				if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {
944					$('.dp-nav-next-year', this.context).addClass('disabled');
945					$('.dp-nav-next-month', this.context).addClass('disabled');
946					$('.dp-calendar td.other-month', this.context).each(
947						function()
948						{
949							var $this = $(this);
950							if (Number($this.text()) < 14) {
951								$this.addClass('disabled');
952							}
953						}
954					);
955					var d = this.endDate.getDate();
956					$('.dp-calendar td.current-month', this.context).each(
957						function()
958						{
959							var $this = $(this);
960							if (Number($this.text()) > d) {
961								$this.addClass('disabled');
962							}
963						}
964					);
965				} else {
966					$('.dp-nav-next-year', this.context).removeClass('disabled');
967					$('.dp-nav-next-month', this.context).removeClass('disabled');
968					var d = this.endDate.getDate();
969					if (d < 13) {
970						// check if the endDate is next month as we might need to add some disabled classes...
971						var ed = new Date(this.endDate.getTime());
972						ed.addMonths(-1);
973						if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {
974							$('.dp-calendar td.other-month', this.context).each(
975								function()
976								{
977									var $this = $(this);
978									if (Number($this.text()) > d) {
979										$this.addClass('disabled');
980									}
981								}
982							);
983						}
984					}
985				}
986			},
987			_closeCalendar : function(programatic, ele)
988			{
989				if (!ele || ele == this.ele)
990				{
991					$(document).unbind('mousedown', this._checkMouse);
992					this._clearCalendar();
993					$('#dp-popup a').unbind();
994					$('#dp-popup').empty().remove();
995					if (!programatic) {
996						$(this.ele).trigger('dpClosed', [this.getSelected()]);
997					}
998				}
999			},
1000			// empties the current dp-calendar div and makes sure that all events are unbound
1001			// and expandos removed to avoid memory leaks...
1002			_clearCalendar : function()
1003			{
1004				// TODO.
1005				$('.dp-calendar td', this.context).unbind();
1006				$('.dp-calendar', this.context).empty();
1007			}
1008		}
1009	);
1010	
1011	// static constants
1012	$.dpConst = {
1013		SHOW_HEADER_NONE	:	0,
1014		SHOW_HEADER_SHORT	:	1,
1015		SHOW_HEADER_LONG	:	2,
1016		POS_TOP				:	0,
1017		POS_BOTTOM			:	1,
1018		POS_LEFT			:	0,
1019		POS_RIGHT			:	1
1020	};
1021	// localisable text
1022	$.dpText = {
1023		TEXT_PREV_YEAR		:	'Previous year',
1024		TEXT_PREV_MONTH		:	'Previous month',
1025		TEXT_NEXT_YEAR		:	'Next year',
1026		TEXT_NEXT_MONTH		:	'Next month',
1027		TEXT_CLOSE			:	'Close',
1028		TEXT_CHOOSE_DATE	:	'Choose date'
1029	};
1030	// version
1031	$.dpVersion = '$Id: jquery.datePicker.js 5 2008-12-02 23:43:08Z kelvin.luck $';
1032
1033	function _getController(ele)
1034	{
1035		if (ele._dpId) return $.event._dpCache[ele._dpId];
1036		return false;
1037	};
1038	
1039	// make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional
1040	// comments to only include bgIframe where it is needed in IE without breaking this plugin).
1041	if ($.fn.bgIframe == undefined) {
1042		$.fn.bgIframe = function() {return this; };
1043	};
1044
1045
1046	// clean-up
1047	$(window)
1048		.bind('unload', function() {
1049			var els = $.event._dpCache || [];
1050			for (var i in els) {
1051				$(els[i].ele)._dpDestroy();
1052			}
1053		});
1054		
1055	
1056})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.