Added: 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery/jquery.datepicker.js
URL: 
http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery/jquery.datepicker.js?rev=707811&view=auto
==============================================================================
--- 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery/jquery.datepicker.js
 (added)
+++ 
archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/js/jquery/jquery.datepicker.js
 Fri Oct 24 19:47:21 2008
@@ -0,0 +1,1056 @@
+/**
+ * Copyright (c) 2007 Kelvin Luck (http://www.kelvinluck.com/)
+ * Dual licensed under the MIT 
(http://www.opensource.org/licenses/mit-license.php) 
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z kelvin.luck $
+ **/
+
+(function($){
+    
+       $.fn.extend({
+/**
+ * Render a calendar table into any matched elements.
+ * 
+ * @param Object s (optional) Customize your calendars.
+ * @option Number month The month to render (NOTE that months are zero based). 
Default is today's month.
+ * @option Number year The year to render. Default is today's year.
+ * @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.
+ * @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.
+ * @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.
+ * @type jQuery
+ * @name renderCalendar
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('#calendar-me').renderCalendar({month:0, year:2007});
+ * @desc Renders a calendar displaying January 2007 into the element with an 
id of calendar-me.
+ *
+ * @example
+ * var testCallback = function($td, thisDate, month, year)
+ * {
+ * if ($td.is('.current-month') && thisDate.getDay() == 4) {
+ *             var d = thisDate.getDate();
+ *             $td.bind(
+ *                     'click',
+ *                     function()
+ *                     {
+ *                             alert('You clicked on ' + d + '/' + 
(Number(month)+1) + '/' + year);
+ *                     }
+ *             ).addClass('thursday');
+ *     } else if (thisDate.getDay() == 5) {
+ *             $td.html('Friday the ' + $td.html() + 'th');
+ *     }
+ * }
+ * $('#calendar-me').renderCalendar({month:0, year:2007, 
renderCallback:testCallback});
+ * 
+ * @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.
+ **/
+               renderCalendar  :   function(s)
+               {
+                       var dc = function(a)
+                       {
+                               return document.createElement(a);
+                       };
+                       
+                       s = $.extend(
+                               {
+                                       month                   : null,
+                                       year                    : null,
+                                       renderCallback  : null,
+                                       showHeader              : 
$.dpConst.SHOW_HEADER_SHORT,
+                                       dpController    : null,
+                                       hoverClass              : 'dp-hover'
+                               }
+                               , s
+                       );
+                       
+                       if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
+                               var headRow = $(dc('tr'));
+                               for (var i=Date.firstDayOfWeek; 
i<Date.firstDayOfWeek+7; i++) {
+                                       var weekday = i%7;
+                                       var day = Date.dayNames[weekday];
+                                       headRow.append(
+                                               
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)
+                                       );
+                               }
+                       };
+                       
+                       var calendarTable = $(dc('table'))
+                                                                       .attr(
+                                                                               
{
+                                                                               
        'cellspacing':2,
+                                                                               
        'className':'jCalendar'
+                                                                               
}
+                                                                       )
+                                                                       .append(
+                                                                               
(s.showHeader != $.dpConst.SHOW_HEADER_NONE ? 
+                                                                               
        $(dc('thead'))
+                                                                               
                .append(headRow)
+                                                                               
        :
+                                                                               
        dc('thead')
+                                                                               
)
+                                                                       );
+                       var tbody = $(dc('tbody'));
+                       
+                       var today = (new Date()).zeroTime();
+                       
+                       var month = s.month == undefined ? today.getMonth() : 
s.month;
+                       var year = s.year || today.getFullYear();
+                       
+                       var currentDate = new Date(year, month, 1);
+                       
+                       
+                       var firstDayOffset = Date.firstDayOfWeek - 
currentDate.getDay() + 1;
+                       if (firstDayOffset > 1) firstDayOffset -= 7;
+                       var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + 
currentDate.getDaysInMonth() ) /7);
+                       currentDate.addDays(firstDayOffset-1);
+                       
+                       var doHover = function()
+                       {
+                               if (s.hoverClass) {
+                                       $(this).addClass(s.hoverClass);
+                               }
+                       };
+                       var unHover = function()
+                       {
+                               if (s.hoverClass) {
+                                       $(this).removeClass(s.hoverClass);
+                               }
+                       };
+                       
+                       var w = 0;
+                       while (w++<weeksToDraw) {
+                               var r = jQuery(dc('tr'));
+                               for (var i=0; i<7; i++) {
+                                       var thisMonth = currentDate.getMonth() 
== month;
+                                       var d = $(dc('td'))
+                                                               
.text(currentDate.getDate() + '')
+                                                               
.attr('className', (thisMonth ? 'current-month ' : 'other-month ') +
+                                                                               
                        (currentDate.isWeekend() ? 'weekend ' : 'weekday ') +
+                                                                               
                        (thisMonth && currentDate.getTime() == today.getTime() 
? 'today ' : '')
+                                                               )
+                                                               .hover(doHover, 
unHover)
+                                                       ;
+                                       if (s.renderCallback) {
+                                               s.renderCallback(d, 
currentDate, month, year);
+                                       }
+                                       r.append(d);
+                                       currentDate.addDays(1);
+                               }
+                               tbody.append(r);
+                       }
+                       calendarTable.append(tbody);
+                       
+                       return this.each(
+                               function()
+                               {
+                                       $(this).empty().append(calendarTable);
+                               }
+                       );
+               },
+/**
+ * Create a datePicker associated with each of the matched elements.
+ *
+ * The matched element will receive a few custom events with the following 
signatures:
+ *
+ * dateSelected(event, date, $td, status)
+ * 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)
+ * 
+ * dpClosed(event, selected)
+ * Triggered when the date picker is closed. event is a reference to the event 
and selected is an Array containing Date objects.
+ *
+ * dpMonthChanged(event, displayedMonth, displayedYear)
+ * 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.
+ *
+ * dpDisplayed(event, $datePickerDiv)
+ * 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.
+ *
+ * @param Object s (optional) Customize your date pickers.
+ * @option Number month The month to render when the date picker is opened 
(NOTE that months are zero based). Default is today's month.
+ * @option Number year The year to render when the date picker is opened. 
Default is today's year.
+ * @option String startDate The first date date can be selected.
+ * @option String endDate The last date that can be selected.
+ * @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)
+ * @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.
+ * @option Boolean showYearNavigation Whether to display buttons which allow 
the user to navigate through the months a year at a time. Default is true.
+ * @option Boolean closeOnSelect Whether to close the date picker when a date 
is selected. Default is true.
+ * @option Boolean displayClose Whether to create a "Close" button within the 
date picker popup. Default is false.
+ * @option Boolean selectMultiple Whether a user should be able to select 
multiple dates with this date picker. Default is false.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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; 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.
+ * @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.
+ * @type jQuery
+ * @name datePicker
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('input.date-picker').datePicker();
+ * @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).
+ *
+ * @example demo/index.html
+ * @desc See the projects homepage for many more complex examples...
+ **/
+               datePicker : function(s)
+               {                       
+                       if (!$.event._dpCache) $.event._dpCache = [];
+                       
+                       // initialise the date picker controller with the 
relevant settings...
+                       s = $.extend(
+                               {
+                                       month                           : 
undefined,
+                                       year                            : 
undefined,
+                                       startDate                       : 
undefined,
+                                       endDate                         : 
undefined,
+                                       inline                          : false,
+                                       renderCallback          : [],
+                                       createButton            : true,
+                                       showYearNavigation      : true,
+                                       closeOnSelect           : true,
+                                       displayClose            : false,
+                                       selectMultiple          : false,
+                                       clickInput                      : false,
+                                       verticalPosition        : 
$.dpConst.POS_TOP,
+                                       horizontalPosition      : 
$.dpConst.POS_LEFT,
+                                       verticalOffset          : 0,
+                                       horizontalOffset        : 0,
+                                       hoverClass                      : 
'dp-hover'
+                               }
+                               , s
+                       );
+                       
+                       return this.each(
+                               function()
+                               {
+                                       var $this = $(this);
+                                       var alreadyExists = true;
+                                       
+                                       if (!this._dpId) {
+                                               this._dpId = $.event.guid++;
+                                               $.event._dpCache[this._dpId] = 
new DatePicker(this);
+                                               alreadyExists = false;
+                                       }
+                                       
+                                       if (s.inline) {
+                                               s.createButton = false;
+                                               s.displayClose = false;
+                                               s.closeOnSelect = false;
+                                               $this.empty();
+                                       }
+                                       
+                                       var controller = 
$.event._dpCache[this._dpId];
+                                       
+                                       controller.init(s);
+                                       
+                                       if (!alreadyExists && s.createButton) {
+                                               // create it!
+                                               controller.button = $('<a 
href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '">' + 
$.dpText.TEXT_CHOOSE_DATE + '</a>')
+                                                               .bind(
+                                                                       'click',
+                                                                       
function()
+                                                                       {
+                                                                               
$this.dpDisplay(this);
+                                                                               
this.blur();
+                                                                               
return false;
+                                                                       }
+                                                               );
+                                               $this.after(controller.button);
+                                       }
+                                       
+                                       if (!alreadyExists && 
$this.is(':text')) {
+                                               $this
+                                                       .bind(
+                                                               'dateSelected',
+                                                               function(e, 
selectedDate, $td)
+                                                               {
+                                                                       
this.value = selectedDate.asString();
+                                                               }
+                                                       ).bind(
+                                                               'change',
+                                                               function()
+                                                               {
+                                                                       var d = 
Date.fromString(this.value);
+                                                                       if (d) {
+                                                                               
controller.setSelected(d, true, true);
+                                                                       }
+                                                               }
+                                                       );
+                                               if (s.clickInput) {
+                                                       $this.bind(
+                                                               'click',
+                                                               function()
+                                                               {
+                                                                       
$this.dpDisplay();
+                                                               }
+                                                       );
+                                               }
+                                               var d = 
Date.fromString(this.value);
+                                               if (this.value != '' && d) {
+                                                       
controller.setSelected(d, true, true);
+                                               }
+                                       }
+                                       
+                                       $this.addClass('dp-applied');
+                                       
+                               }
+                       )
+               },
+/**
+ * Disables or enables this date picker
+ *
+ * @param Boolean s Whether to disable (true) or enable (false) this datePicker
+ * @type jQuery
+ * @name dpSetDisabled
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * $('.date-picker').dpSetDisabled(true);
+ * @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.
+ **/
+               dpSetDisabled : function(s)
+               {
+                       return _w.call(this, 'setDisabled', s);
+               },
+/**
+ * Updates the first selectable date for any date pickers on any matched 
elements.
+ *
+ * @param String d A string representing the first selectable date (formatted 
according to Date.format).
+ * @type jQuery
+ * @name dpSetStartDate
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * $('.date-picker').dpSetStartDate('01/01/2000');
+ * @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.
+ **/
+               dpSetStartDate : function(d)
+               {
+                       return _w.call(this, 'setStartDate', d);
+               },
+/**
+ * Updates the last selectable date for any date pickers on any matched 
elements.
+ *
+ * @param String d A string representing the last selectable date (formatted 
according to Date.format).
+ * @type jQuery
+ * @name dpSetEndDate
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * $('.date-picker').dpSetEndDate('01/01/2010');
+ * @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.
+ **/
+               dpSetEndDate : function(d)
+               {
+                       return _w.call(this, 'setEndDate', d);
+               },
+/**
+ * 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.
+ *
+ * @type Array
+ * @name dpGetSelected
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * alert($('.date-picker').dpGetSelected());
+ * @desc Will alert an empty array (as nothing is selected yet)
+ **/
+               dpGetSelected : function()
+               {
+                       var c = _getController(this[0]);
+                       if (c) {
+                               return c.getSelected();
+                       }
+                       return null;
+               },
+/**
+ * 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.
+ *
+ * @param String d A string representing the date you want to select 
(formatted according to Date.format).
+ * @param Boolean v Whether you want to select (true) or deselect (false) this 
date. Optional - default = true.
+ * @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.
+ * @type jQuery
+ * @name dpSetSelected
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * $('.date-picker').dpSetSelected('01/01/2010');
+ * @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.
+ **/
+               dpSetSelected : function(d, v, m)
+               {
+                       if (v == undefined) v=true;
+                       if (m == undefined) m=true;
+                       return _w.call(this, 'setSelected', Date.fromString(d), 
v, m);
+               },
+/**
+ * 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.
+ *
+ * @param Number m The month you want the date picker to display. Optional - 
defaults to the currently displayed month.
+ * @param Number y The year you want the date picker to display. Optional - 
defaults to the currently displayed year.
+ * @type jQuery
+ * @name dpSetDisplayedMonth
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-picker').datePicker();
+ * $('.date-picker').dpSetDisplayedMonth(10, 2008);
+ * @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.
+ **/
+               dpSetDisplayedMonth : function(m, y)
+               {
+                       return _w.call(this, 'setDisplayedMonth', Number(m), 
Number(y));
+               },
+/**
+ * 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.
+ *
+ * @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.
+ * @type jQuery
+ * @name dpDisplay
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('#date-picker').datePicker();
+ * $('#date-picker').dpDisplay();
+ * @desc Creates a date picker associated with the element with an id of 
date-picker and then causes it to pop up.
+ **/
+               dpDisplay : function(e)
+               {
+                       return _w.call(this, 'display', e);
+               },
+/**
+ * Sets a function or array of functions that is called when each TD of the 
date picker popup is rendered to the page
+ *
+ * @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; 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.
+ * @type jQuery
+ * @name dpSetRenderCallback
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('#date-picker').datePicker();
+ * $('#date-picker').dpSetRenderCallback(function($td, thisDate, month, year)
+ * {
+ *     // do stuff as each td is rendered dependant on the date in the td and 
the displayed month and year
+ * });
+ * @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.
+ **/
+               dpSetRenderCallback : function(a)
+               {
+                       return _w.call(this, 'setRenderCallback', a);
+               },
+/**
+ * Sets the position that the datePicker will pop up (relative to it's 
associated element)
+ *
+ * @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
+ * @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
+ * @type jQuery
+ * @name dpSetPosition
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('#date-picker').datePicker();
+ * $('#date-picker').dpSetPosition($.dpConst.POS_BOTTOM, $.dpConst.POS_RIGHT);
+ * @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.
+ **/
+               dpSetPosition : function(v, h)
+               {
+                       return _w.call(this, 'setPosition', v, h);
+               },
+/**
+ * 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)
+ *
+ * @param Number v The vertical offset of the created date picker.
+ * @param Number h The horizontal offset of the created date picker.
+ * @type jQuery
+ * @name dpSetOffset
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('#date-picker').datePicker();
+ * $('#date-picker').dpSetOffset(-20, 200);
+ * @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.
+ **/
+               dpSetOffset : function(v, h)
+               {
+                       return _w.call(this, 'setOffset', v, h);
+               },
+/**
+ * Closes the open date picker associated with this element.
+ *
+ * @type jQuery
+ * @name dpClose
+ * @cat plugins/datePicker
+ * @author Kelvin Luck (http://www.kelvinluck.com/)
+ *
+ * @example $('.date-pick')
+ *             .datePicker()
+ *             .bind(
+ *                     'focus',
+ *                     function()
+ *                     {
+ *                             $(this).dpDisplay();
+ *                     }
+ *             ).bind(
+ *                     'blur',
+ *                     function()
+ *                     {
+ *                             $(this).dpClose();
+ *                     }
+ *             );
+ * @desc Creates a date picker and makes it appear when the relevant element 
is focused and disappear when it is blurred.
+ **/
+               dpClose : function()
+               {
+                       return _w.call(this, '_closeCalendar', false, this[0]);
+               },
+               // private function called on unload to clean up any expandos 
etc and prevent memory links...
+               _dpDestroy : function()
+               {
+                       // TODO - implement this?
+               }
+       });
+       
+       // private internal function to cut down on the amount of code needed 
where we forward
+       // dp* methods on the jQuery object on to the relevant DatePicker 
controllers...
+       var _w = function(f, a1, a2, a3)
+       {
+               return this.each(
+                       function()
+                       {
+                               var c = _getController(this);
+                               if (c) {
+                                       c[f](a1, a2, a3);
+                               }
+                       }
+               );
+       };
+       
+       function DatePicker(ele)
+       {
+               this.ele = ele;
+               
+               // initial values...
+               this.displayedMonth             =       null;
+               this.displayedYear              =       null;
+               this.startDate                  =       null;
+               this.endDate                    =       null;
+               this.showYearNavigation =       null;
+               this.closeOnSelect              =       null;
+               this.displayClose               =       null;
+               this.selectMultiple             =       null;
+               this.verticalPosition   =       null;
+               this.horizontalPosition =       null;
+               this.verticalOffset             =       null;
+               this.horizontalOffset   =       null;
+               this.button                             =       null;
+               this.renderCallback             =       [];
+               this.selectedDates              =       {};
+               this.inline                             =       null;
+               this.context                    =       '#dp-popup';
+       };
+       $.extend(
+               DatePicker.prototype,
+               {       
+                       init : function(s)
+                       {
+                               this.setStartDate(s.startDate);
+                               this.setEndDate(s.endDate);
+                               this.setDisplayedMonth(Number(s.month), 
Number(s.year));
+                               this.setRenderCallback(s.renderCallback);
+                               this.showYearNavigation = s.showYearNavigation;
+                               this.closeOnSelect = s.closeOnSelect;
+                               this.displayClose = s.displayClose;
+                               this.selectMultiple = s.selectMultiple;
+                               this.verticalPosition = s.verticalPosition;
+                               this.horizontalPosition = s.horizontalPosition;
+                               this.hoverClass = s.hoverClass;
+                               this.setOffset(s.verticalOffset, 
s.horizontalOffset);
+                               this.inline = s.inline;
+                               if (this.inline) {
+                                       this.context = this.ele;
+                                       this.display();
+                               }
+                       },
+                       setStartDate : function(d)
+                       {
+                               if (d) {
+                                       this.startDate = Date.fromString(d);
+                               }
+                               if (!this.startDate) {
+                                       this.startDate = (new 
Date()).zeroTime();
+                               }
+                               this.setDisplayedMonth(this.displayedMonth, 
this.displayedYear);
+                       },
+                       setEndDate : function(d)
+                       {
+                               if (d) {
+                                       this.endDate = Date.fromString(d);
+                               }
+                               if (!this.endDate) {
+                                       this.endDate = (new 
Date('12/31/2999')); // using the JS Date.parse function which expects 
mm/dd/yyyy
+                               }
+                               if (this.endDate.getTime() < 
this.startDate.getTime()) {
+                                       this.endDate = this.startDate;
+                               }
+                               this.setDisplayedMonth(this.displayedMonth, 
this.displayedYear);
+                       },
+                       setPosition : function(v, h)
+                       {
+                               this.verticalPosition = v;
+                               this.horizontalPosition = h;
+                       },
+                       setOffset : function(v, h)
+                       {
+                               this.verticalOffset = parseInt(v) || 0;
+                               this.horizontalOffset = parseInt(h) || 0;
+                       },
+                       setDisabled : function(s)
+                       {
+                               $e = $(this.ele);
+                               $e[s ? 'addClass' : 
'removeClass']('dp-disabled');
+                               if (this.button) {
+                                       $but = $(this.button);
+                                       $but[s ? 'addClass' : 
'removeClass']('dp-disabled');
+                                       $but.attr('title', s ? '' : 
$.dpText.TEXT_CHOOSE_DATE);
+                               }
+                               if ($e.is(':text')) {
+                                       $e.attr('disabled', s ? 'disabled' : 
'');
+                               }
+                       },
+                       setDisplayedMonth : function(m, y)
+                       {
+                               if (this.startDate == undefined || this.endDate 
== undefined) {
+                                       return;
+                               }
+                               var s = new Date(this.startDate.getTime());
+                               s.setDate(1);
+                               var e = new Date(this.endDate.getTime());
+                               e.setDate(1);
+                               
+                               var t;
+                               if ((!m && !y) || (isNaN(m) && isNaN(y))) {
+                                       // no month or year passed - default to 
current month
+                                       t = new Date().zeroTime();
+                                       t.setDate(1);
+                               } else if (isNaN(m)) {
+                                       // just year passed in - presume we 
want the displayedMonth
+                                       t = new Date(y, this.displayedMonth, 1);
+                               } else if (isNaN(y)) {
+                                       // just month passed in - presume we 
want the displayedYear
+                                       t = new Date(this.displayedYear, m, 1);
+                               } else {
+                                       // year and month passed in - that's 
the date we want!
+                                       t = new Date(y, m, 1)
+                               }
+                               
+                               // check if the desired date is within the 
range of our defined startDate and endDate
+                               if (t.getTime() < s.getTime()) {
+                                       t = s;
+                               } else if (t.getTime() > e.getTime()) {
+                                       t = e;
+                               }
+                               this.displayedMonth = t.getMonth();
+                               this.displayedYear = t.getFullYear();
+                       },
+                       setSelected : function(d, v, moveToMonth)
+                       {
+                               if (this.selectMultiple == false) {
+                                       this.selectedDates = {};
+                                       $('td.selected', 
this.context).removeClass('selected');
+                               }
+                               if (moveToMonth) {
+                                       this.setDisplayedMonth(d.getMonth(), 
d.getFullYear());
+                               }
+                               this.selectedDates[d.toString()] = v;
+                       },
+                       isSelected : function(d)
+                       {
+                               return this.selectedDates[d.toString()];
+                       },
+                       getSelected : function()
+                       {
+                               var r = [];
+                               for(s in this.selectedDates) {
+                                       if (this.selectedDates[s] == true) {
+                                               r.push(Date.parse(s));
+                                       }
+                               }
+                               return r;
+                       },
+                       display : function(eleAlignTo)
+                       {
+                               if ($(this.ele).is('.dp-disabled')) return;
+                               
+                               eleAlignTo = eleAlignTo || this.ele;
+                               var c = this;
+                               var $ele = $(eleAlignTo);
+                               var eleOffset = $ele.offset();
+                               
+                               var $createIn;
+                               var attrs;
+                               var attrsCalendarHolder;
+                               var cssRules;
+                               
+                               if (c.inline) {
+                                       $createIn = $(this.ele);
+                                       attrs = {
+                                               'id'            :       
'calendar-' + this.ele._dpId,
+                                               'className'     :       
'dp-popup dp-popup-inline'
+                                       };
+                                       cssRules = {
+                                       };
+                               } else {
+                                       $createIn = $('body');
+                                       attrs = {
+                                               'id'            :       
'dp-popup',
+                                               'className'     :       
'dp-popup'
+                                       };
+                                       cssRules = {
+                                               'top'   :       eleOffset.top + 
c.verticalOffset,
+                                               'left'  :       eleOffset.left 
+ c.horizontalOffset
+                                       };
+                                       
+                                       var _checkMouse = function(e)
+                                       {
+                                               var el = e.target;
+                                               var cal = $('#dp-popup')[0];
+                                               
+                                               while (true){
+                                                       if (el == cal) {
+                                                               return true;
+                                                       } else if (el == 
document) {
+                                                               
c._closeCalendar();
+                                                               return false;
+                                                       } else {
+                                                               el = 
$(el).parent()[0];
+                                                       }
+                                               }
+                                       };
+                                       this._checkMouse = _checkMouse;
+                               
+                                       this._closeCalendar(true);
+                               }
+                               
+                               
+                               $createIn
+                                       .append(
+                                               $('<div></div>')
+                                                       .attr(attrs)
+                                                       .css(cssRules)
+                                                       .append(
+                                                               $('<h2></h2>'),
+                                                               $('<div 
class="dp-nav-prev"></div>')
+                                                                       .append(
+                                                                               
$('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + 
'">&lt;&lt;</a>')
+                                                                               
        .bind(
+                                                                               
                'click',
+                                                                               
                function()
+                                                                               
                {
+                                                                               
                        return c._displayNewMonth.call(c, this, 0, -1);
+                                                                               
                }
+                                                                               
        ),
+                                                                               
$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + 
'">&lt;</a>')
+                                                                               
        .bind(
+                                                                               
                'click',
+                                                                               
                function()
+                                                                               
                {
+                                                                               
                        return c._displayNewMonth.call(c, this, -1, 0);
+                                                                               
                }
+                                                                               
        )
+                                                                       ),
+                                                               $('<div 
class="dp-nav-next"></div>')
+                                                                       .append(
+                                                                               
$('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + 
'">&gt;&gt;</a>')
+                                                                               
        .bind(
+                                                                               
                'click',
+                                                                               
                function()
+                                                                               
                {
+                                                                               
                        return c._displayNewMonth.call(c, this, 0, 1);
+                                                                               
                }
+                                                                               
        ),
+                                                                               
$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + 
'">&gt;</a>')
+                                                                               
        .bind(
+                                                                               
                'click',
+                                                                               
                function()
+                                                                               
                {
+                                                                               
                        return c._displayNewMonth.call(c, this, 1, 0);
+                                                                               
                }
+                                                                               
        )
+                                                                       ),
+                                                               $('<div></div>')
+                                                                       
.attr('className', 'dp-calendar')
+                                                       )
+                                                       .bgIframe()
+                                               );
+                                       
+                               var $pop = this.inline ? $('.dp-popup', 
this.context) : $('#dp-popup');
+                               
+                               if (this.showYearNavigation == false) {
+                                       $('.dp-nav-prev-year, 
.dp-nav-next-year', c.context).css('display', 'none');
+                               }
+                               if (this.displayClose) {
+                                       $pop.append(
+                                               $('<a href="#" id="dp-close">' 
+ $.dpText.TEXT_CLOSE + '</a>')
+                                                       .bind(
+                                                               'click',
+                                                               function()
+                                                               {
+                                                                       
c._closeCalendar();
+                                                                       return 
false;
+                                                               }
+                                                       )
+                                       );
+                               }
+                               c._renderCalendar();
+                               
+                               $(this.ele).trigger('dpDisplayed', $pop);
+                               
+                               if (!c.inline) {
+                                       if (this.verticalPosition == 
$.dpConst.POS_BOTTOM) {
+                                               $pop.css('top', eleOffset.top + 
$ele.height() - $pop.height() + c.verticalOffset);
+                                       }
+                                       if (this.horizontalPosition == 
$.dpConst.POS_RIGHT) {
+                                               $pop.css('left', eleOffset.left 
+ $ele.width() - $pop.width() + c.horizontalOffset);
+                                       }
+                                       $(document).bind('mousedown', 
this._checkMouse);
+                               }
+                       },
+                       setRenderCallback : function(a)
+                       {
+                               if (a && typeof(a) == 'function') {
+                                       a = [a];
+                               }
+                               this.renderCallback = 
this.renderCallback.concat(a);
+                       },
+                       cellRender : function ($td, thisDate, month, year) {
+                               var c = this.dpController;
+                               var d = new Date(thisDate.getTime());
+                               
+                               // add our click handlers to deal with it when 
the days are clicked...
+                               
+                               $td.bind(
+                                       'click',
+                                       function()
+                                       {
+                                               var $this = $(this);
+                                               if (!$this.is('.disabled')) {
+                                                       c.setSelected(d, 
!$this.is('.selected') || !c.selectMultiple);
+                                                       var s = c.isSelected(d);
+                                                       
$(c.ele).trigger('dateSelected', [d, $td, s]);
+                                                       
$(c.ele).trigger('change');
+                                                       if (c.closeOnSelect) {
+                                                               
c._closeCalendar();
+                                                       } else {
+                                                               $this[s ? 
'addClass' : 'removeClass']('selected');
+                                                       }
+                                               }
+                                       }
+                               );
+                               
+                               if (c.isSelected(d)) {
+                                       $td.addClass('selected');
+                               }
+                               
+                               // call any extra renderCallbacks that were 
passed in
+                               for (var i=0; i<c.renderCallback.length; i++) {
+                                       c.renderCallback[i].apply(this, 
arguments);
+                               }
+                               
+                               
+                       },
+                       // ele is the clicked button - only proceed if it 
doesn't have the class disabled...
+                       // m and y are -1, 0 or 1 depending which direction we 
want to go in...
+                       _displayNewMonth : function(ele, m, y) 
+                       {
+                               if (!$(ele).is('.disabled')) {
+                                       
this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y);
+                                       this._clearCalendar();
+                                       this._renderCalendar();
+                                       $(this.ele).trigger('dpMonthChanged', 
[this.displayedMonth, this.displayedYear]);
+                               }
+                               ele.blur();
+                               return false;
+                       },
+                       _renderCalendar : function()
+                       {
+                               // set the title...
+                               $('h2', 
this.context).html(Date.monthNames[this.displayedMonth] + ' ' + 
this.displayedYear);
+                               
+                               // render the calendar...
+                               $('.dp-calendar', this.context).renderCalendar(
+                                       {
+                                               month                   : 
this.displayedMonth,
+                                               year                    : 
this.displayedYear,
+                                               renderCallback  : 
this.cellRender,
+                                               dpController    : this,
+                                               hoverClass              : 
this.hoverClass
+                                       }
+                               );
+                               
+                               // update the status of the control buttons and 
disable dates before startDate or after endDate...
+                               // 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?
+                               if (this.displayedYear == 
this.startDate.getFullYear() && this.displayedMonth == 
this.startDate.getMonth()) {
+                                       $('.dp-nav-prev-year', 
this.context).addClass('disabled');
+                                       $('.dp-nav-prev-month', 
this.context).addClass('disabled');
+                                       $('.dp-calendar td.other-month', 
this.context).each(
+                                               function()
+                                               {
+                                                       var $this = $(this);
+                                                       if 
(Number($this.text()) > 20) {
+                                                               
$this.addClass('disabled');
+                                                       }
+                                               }
+                                       );
+                                       var d = this.startDate.getDate();
+                                       $('.dp-calendar td.current-month', 
this.context).each(
+                                               function()
+                                               {
+                                                       var $this = $(this);
+                                                       if 
(Number($this.text()) < d) {
+                                                               
$this.addClass('disabled');
+                                                       }
+                                               }
+                                       );
+                               } else {
+                                       $('.dp-nav-prev-year', 
this.context).removeClass('disabled');
+                                       $('.dp-nav-prev-month', 
this.context).removeClass('disabled');
+                                       var d = this.startDate.getDate();
+                                       if (d > 20) {
+                                               // check if the startDate is 
last month as we might need to add some disabled classes...
+                                               var sd = new 
Date(this.startDate.getTime());
+                                               sd.addMonths(1);
+                                               if (this.displayedYear == 
sd.getFullYear() && this.displayedMonth == sd.getMonth()) {
+                                                       $('dp-calendar 
td.other-month', this.context).each(
+                                                               function()
+                                                               {
+                                                                       var 
$this = $(this);
+                                                                       if 
(Number($this.text()) < d) {
+                                                                               
$this.addClass('disabled');
+                                                                       }
+                                                               }
+                                                       );
+                                               }
+                                       }
+                               }
+                               if (this.displayedYear == 
this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {
+                                       $('.dp-nav-next-year', 
this.context).addClass('disabled');
+                                       $('.dp-nav-next-month', 
this.context).addClass('disabled');
+                                       $('.dp-calendar td.other-month', 
this.context).each(
+                                               function()
+                                               {
+                                                       var $this = $(this);
+                                                       if 
(Number($this.text()) < 14) {
+                                                               
$this.addClass('disabled');
+                                                       }
+                                               }
+                                       );
+                                       var d = this.endDate.getDate();
+                                       $('.dp-calendar td.current-month', 
this.context).each(
+                                               function()
+                                               {
+                                                       var $this = $(this);
+                                                       if 
(Number($this.text()) > d) {
+                                                               
$this.addClass('disabled');
+                                                       }
+                                               }
+                                       );
+                               } else {
+                                       $('.dp-nav-next-year', 
this.context).removeClass('disabled');
+                                       $('.dp-nav-next-month', 
this.context).removeClass('disabled');
+                                       var d = this.endDate.getDate();
+                                       if (d < 13) {
+                                               // check if the endDate is next 
month as we might need to add some disabled classes...
+                                               var ed = new 
Date(this.endDate.getTime());
+                                               ed.addMonths(-1);
+                                               if (this.displayedYear == 
ed.getFullYear() && this.displayedMonth == ed.getMonth()) {
+                                                       $('.dp-calendar 
td.other-month', this.context).each(
+                                                               function()
+                                                               {
+                                                                       var 
$this = $(this);
+                                                                       if 
(Number($this.text()) > d) {
+                                                                               
$this.addClass('disabled');
+                                                                       }
+                                                               }
+                                                       );
+                                               }
+                                       }
+                               }
+                       },
+                       _closeCalendar : function(programatic, ele)
+                       {
+                               if (!ele || ele == this.ele)
+                               {
+                                       $(document).unbind('mousedown', 
this._checkMouse);
+                                       this._clearCalendar();
+                                       $('#dp-popup a').unbind();
+                                       $('#dp-popup').empty().remove();
+                                       if (!programatic) {
+                                               $(this.ele).trigger('dpClosed', 
[this.getSelected()]);
+                                       }
+                               }
+                       },
+                       // empties the current dp-calendar div and makes sure 
that all events are unbound
+                       // and expandos removed to avoid memory leaks...
+                       _clearCalendar : function()
+                       {
+                               // TODO.
+                               $('.dp-calendar td', this.context).unbind();
+                               $('.dp-calendar', this.context).empty();
+                       }
+               }
+       );
+       
+       // static constants
+       $.dpConst = {
+               SHOW_HEADER_NONE        :       0,
+               SHOW_HEADER_SHORT       :       1,
+               SHOW_HEADER_LONG        :       2,
+               POS_TOP                         :       0,
+               POS_BOTTOM                      :       1,
+               POS_LEFT                        :       0,
+               POS_RIGHT                       :       1
+       };
+       // localisable text
+       $.dpText = {
+               TEXT_PREV_YEAR          :       'Previous year',
+               TEXT_PREV_MONTH         :       'Previous month',
+               TEXT_NEXT_YEAR          :       'Next year',
+               TEXT_NEXT_MONTH         :       'Next month',
+               TEXT_CLOSE                      :       'Close',
+               TEXT_CHOOSE_DATE        :       'Choose date'
+       };
+       // version
+       $.dpVersion = '$Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z 
kelvin.luck $';
+
+       function _getController(ele)
+       {
+               if (ele._dpId) return $.event._dpCache[ele._dpId];
+               return false;
+       };
+       
+       // make it so that no error is thrown if bgIframe plugin isn't included 
(allows you to use conditional
+       // comments to only include bgIframe where it is needed in IE without 
breaking this plugin).
+       if ($.fn.bgIframe == undefined) {
+               $.fn.bgIframe = function() {return this; };
+       };
+
+
+       // clean-up
+       $(window)
+               .bind('unload', function() {
+                       var els = $.event._dpCache || [];
+                       for (var i in els) {
+                               $(els[i].ele)._dpDestroy();
+                       }
+               });
+               
+       
+})(jQuery);


Reply via email to