From: Elan Ruusamäe Date: Mon, 20 Oct 2008 20:19:13 +0000 (+0000) Subject: - applied in svn X-Git-Tag: auto/ac/eventum-2_2-1~14 X-Git-Url: http://git.pld-linux.org/?p=packages%2Feventum.git;a=commitdiff_plain;h=6a5f9239af08853c6a144a0b60c4553345ede0d7 - applied in svn Changed files: eventum-jquery.patch -> 1.3 --- diff --git a/eventum-jquery.patch b/eventum-jquery.patch deleted file mode 100644 index 640b23b..0000000 --- a/eventum-jquery.patch +++ /dev/null @@ -1,2616 +0,0 @@ -Index: js/jquery/ui.datepicker.js -=================================================================== ---- js/jquery/ui.datepicker.js (revision 3749) -+++ js/jquery/ui.datepicker.js (working copy) -@@ -1,26 +1,40 @@ --/* jQuery UI Date Picker v3.3 - previously jQuery Calendar -- Written by Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au). -+/* -+ * jQuery UI Datepicker -+ * -+ * Copyright (c) 2006, 2007, 2008 Marc Grabanski -+ * Dual licensed under the MIT (MIT-LICENSE.txt) -+ * and GPL (GPL-LICENSE.txt) licenses. -+ * -+ * http://docs.jquery.com/UI/Datepicker -+ * -+ * Depends: -+ * ui.core.js -+ * -+ * Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au). -+ */ -+ -+(function($) { // hide the namespace - -- Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datepicker) -- Dual licensed under the MIT (MIT-LICENSE.txt) -- and GPL (GPL-LICENSE.txt) licenses. -- Date: 09-03-2007 */ -+var PROP_NAME = 'datepicker'; - - /* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. -- Settings for (groups of) date pickers are maintained in an instance object -- (DatepickerInstance), allowing multiple different settings on the same page. */ -- --(function($) { // hide the namespace -+ Settings for (groups of) date pickers are maintained in an instance object, -+ allowing multiple different settings on the same page. */ - - function Datepicker() { - this.debug = false; // Change this to true to start debugging -- this._nextId = 0; // Next ID for a date picker instance -- this._inst = []; // List of instances indexed by ID - this._curInst = null; // The current instance in use - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not -+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division -+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class -+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class -+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class -+ this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class -+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class -+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[''] = { // Default regional settings - clearText: 'Clear', // Display text for clear link -@@ -54,6 +68,7 @@ - showOn: 'focus', // 'focus' for popup on focus, - // 'button' for trigger button, or 'both' for either - showAnim: 'show', // Name of jQuery animation for popup -+ showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: '', // Display text following the input box, e.g. showing the format -@@ -65,11 +80,14 @@ - mandatory: false, // True to hide the Clear link, false to include it - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them -+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links -+ gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: true, // True if month can be selected directly, false if only prev/next - changeYear: true, // True if year can be selected directly, false if only prev/next - yearRange: '-10:+10', // Range of years to display in drop-down, - // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) - changeFirstDay: true, // True to click on day name to change, false to remain as set -+ highlightWeek: false, // True to highlight the selected week - showOtherMonths: false, // True to show dates in other months, false to leave blank - showWeeks: false, // True to show week of the year, false to omit - calculateWeek: this.iso8601Week, // How to calculate the week of the year, -@@ -82,20 +100,24 @@ - // takes date and instance as parameters, returns display text - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit -- speed: 'medium', // Speed of display/closure -+ duration: 'normal', // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with -- // [0] = true if selectable, false if not, -- // [1] = custom CSS class name(s) or '', e.g. $.datepicker.noWeekends -+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', -+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected -+ onChangeMonthYear: null, // Define a callback function when the month or year is changed -+ onClose: null, // Define a callback function when the datepicker is closed - numberOfMonths: 1, // Number of months to show at a time - stepMonths: 1, // Number of months to step back/forward - rangeSelect: false, // Allows for selecting a date range on one date picker -- rangeSeparator: ' - ' // Text between two dates in a range -+ rangeSeparator: ' - ', // Text between two dates in a range -+ altField: '', // Selector for an alternate field to store selected dates into -+ altFormat: '' // The date format to use for the alternate field - }; - $.extend(this._defaults, this.regional['']); -- this._datepickerDiv = $('
'); -+ this.dpDiv = $(''); - } - - $.extend(Datepicker.prototype, { -@@ -104,23 +126,10 @@ - - /* Debug logging (if enabled). */ - log: function () { -- if (this.debug) { -+ if (this.debug) - console.log.apply('', arguments); -- } - }, - -- /* Register a new date picker instance - with custom settings. */ -- _register: function(inst) { -- var id = this._nextId++; -- this._inst[id] = inst; -- return id; -- }, -- -- /* Retrieve a particular date picker instance based on its ID. */ -- _getInst: function(id) { -- return this._inst[id] || id; -- }, -- - /* Override the default settings for all instances of the date picker. - @param settings object - the new settings to use as defaults (anonymous object) - @return the manager object */ -@@ -129,132 +138,109 @@ - return this; - }, - -- /* Handle keystrokes. */ -- _doKeyDown: function(e) { -- var inst = $.datepicker._getInst(this._calId); -- if ($.datepicker._datepickerShowing) { -- switch (e.keyCode) { -- case 9: $.datepicker.hideDatepicker(''); -- break; // hide on tab out -- case 13: $.datepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear, -- $('td.datepicker_daysCellOver', inst._datepickerDiv)[0]); -- return false; // don't submit the form -- break; // select the value on enter -- case 27: $.datepicker.hideDatepicker(inst._get('speed')); -- break; // hide on escape -- case 33: $.datepicker._adjustDate(inst, -- (e.ctrlKey ? -1 : -inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M')); -- break; // previous month/year on page up/+ ctrl -- case 34: $.datepicker._adjustDate(inst, -- (e.ctrlKey ? +1 : +inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M')); -- break; // next month/year on page down/+ ctrl -- case 35: if (e.ctrlKey) $.datepicker._clearDate(inst); -- break; // clear on ctrl+end -- case 36: if (e.ctrlKey) $.datepicker._gotoToday(inst); -- break; // current on ctrl+home -- case 37: if (e.ctrlKey) $.datepicker._adjustDate(inst, -1, 'D'); -- break; // -1 day on ctrl+left -- case 38: if (e.ctrlKey) $.datepicker._adjustDate(inst, -7, 'D'); -- break; // -1 week on ctrl+up -- case 39: if (e.ctrlKey) $.datepicker._adjustDate(inst, +1, 'D'); -- break; // +1 day on ctrl+right -- case 40: if (e.ctrlKey) $.datepicker._adjustDate(inst, +7, 'D'); -- break; // +1 week on ctrl+down -+ /* Attach the date picker to a jQuery selection. -+ @param target element - the target input field or division or span -+ @param settings object - the new settings to use for this date picker instance (anonymous) */ -+ _attachDatepicker: function(target, settings) { -+ // check for settings on the control itself - in namespace 'date:' -+ var inlineSettings = null; -+ for (attrName in this._defaults) { -+ var attrValue = target.getAttribute('date:' + attrName); -+ if (attrValue) { -+ inlineSettings = inlineSettings || {}; -+ try { -+ inlineSettings[attrName] = eval(attrValue); -+ } catch (err) { -+ inlineSettings[attrName] = attrValue; -+ } - } - } -- else if (e.keyCode == 36 && e.ctrlKey) { // display the date picker on ctrl+home -- $.datepicker.showFor(this); -+ var nodeName = target.nodeName.toLowerCase(); -+ var inline = (nodeName == 'div' || nodeName == 'span'); -+ if (!target.id) -+ target.id = 'dp' + new Date().getTime(); -+ var inst = this._newInst($(target), inline); -+ inst.settings = $.extend({}, settings || {}, inlineSettings || {}); -+ if (nodeName == 'input') { -+ this._connectDatepicker(target, inst); -+ } else if (inline) { -+ this._inlineDatepicker(target, inst); - } - }, - -- /* Filter entered characters - based on date format. */ -- _doKeyPress: function(e) { -- var inst = $.datepicker._getInst(this._calId); -- var chars = $.datepicker._possibleChars(inst._get('dateFormat')); -- var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode); -- return (chr < ' ' || !chars || chars.indexOf(chr) > -1); -+ /* Create a new instance object. */ -+ _newInst: function(target, inline) { -+ return {id: target[0].id, input: target, // associated target -+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection -+ drawMonth: 0, drawYear: 0, // month being drawn -+ inline: inline, // is datepicker inline or not -+ dpDiv: (!inline ? this.dpDiv : // presentation div -+ $('
'))}; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); -- if (this._hasClass(input, this.markerClassName)) { -+ if (input.hasClass(this.markerClassName)) - return; -- } -- var appendText = inst._get('appendText'); -- var isRTL = inst._get('isRTL'); -- if (appendText) { -- if (isRTL) { -- input.before('' + appendText + ''); -- } -- else { -- input.after('' + appendText + ''); -- } -- } -- var showOn = inst._get('showOn'); -- if (showOn == 'focus' || showOn == 'both') { // pop-up date picker when in the marked field -- input.focus(this.showFor); -- } -+ var appendText = this._get(inst, 'appendText'); -+ var isRTL = this._get(inst, 'isRTL'); -+ if (appendText) -+ input[isRTL ? 'before' : 'after']('' + appendText + ''); -+ var showOn = this._get(inst, 'showOn'); -+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field -+ input.focus(this._showDatepicker); - if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked -- var buttonText = inst._get('buttonText'); -- var buttonImage = inst._get('buttonImage'); -- var buttonImageOnly = inst._get('buttonImageOnly'); -- var trigger = $(buttonImageOnly ? '' + buttonText + '' : -- ''); -- input.wrap(''); -- if (isRTL) { -- input.before(trigger); -- } -- else { -- input.after(trigger); -- } -- trigger.click(this.showFor); -+ var buttonText = this._get(inst, 'buttonText'); -+ var buttonImage = this._get(inst, 'buttonImage'); -+ var trigger = $(this._get(inst, 'buttonImageOnly') ? -+ $('').addClass(this._triggerClass). -+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) : -+ $('').addClass(this._triggerClass). -+ html(buttonImage == '' ? buttonText : $('').attr( -+ { src:buttonImage, alt:buttonText, title:buttonText }))); -+ input[isRTL ? 'before' : 'after'](trigger); -+ trigger.click(function() { -+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) -+ $.datepicker._hideDatepicker(); -+ else -+ $.datepicker._showDatepicker(target); -+ return false; -+ }); - } -- input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress); -- input.bind("setData.datepicker", function(event, key, value){ -- inst._settings[key] = value; -- }).bind("getData.datepicker", function(event, key){ -- return inst._get(key); -- }); -- input[0]._calId = inst._id; -+ input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress). -+ bind("setData.datepicker", function(event, key, value) { -+ inst.settings[key] = value; -+ }).bind("getData.datepicker", function(event, key) { -+ return this._get(inst, key); -+ }); -+ $.data(target, PROP_NAME, inst); - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var input = $(target); -- if (this._hasClass(input, this.markerClassName)) { -+ if (input.hasClass(this.markerClassName)) - return; -- } -- input.addClass(this.markerClassName).append(inst._datepickerDiv); -- input.bind("setData.datepicker", function(event, key, value){ -- inst._settings[key] = value; -- }).bind("getData.datepicker", function(event, key){ -- return inst._get(key); -- }); -- input[0]._calId = inst._id; -+ input.addClass(this.markerClassName).append(inst.dpDiv). -+ bind("setData.datepicker", function(event, key, value){ -+ inst.settings[key] = value; -+ }).bind("getData.datepicker", function(event, key){ -+ return this._get(inst, key); -+ }); -+ $.data(target, PROP_NAME, inst); -+ this._setDate(inst, this._getDefaultDate(inst)); - this._updateDatepicker(inst); -- /* @todo: fix _inlineShow automatic resizing -- - Endless loop bug in IE6. -- - inst._datepickerDiv.resize doesn't ever fire in firefox. */ -- // inst._datepickerDiv.resize(function() { $.datepicker._inlineShow(inst); }); - }, - - /* Tidy up after displaying the date picker. */ - _inlineShow: function(inst) { -- var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers -- inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0]).width()); -+ var numMonths = this._getNumberOfMonths(inst); // fix width for dynamic number of date pickers -+ inst.dpDiv.width(numMonths[1] * $('.ui-datepicker', inst.dpDiv[0]).width()); - }, - -- /* Does this element have a particular class? */ -- _hasClass: function(element, className) { -- var classes = element.attr('class'); -- return (classes && classes.indexOf(className) > -1); -- }, -- - /* Pop-up the date picker in a "dialog" box. -+ @param input element - ignored - @param dateText string - the initial date to display (in the current format) - @param onSelect function - the function(dateText) to call when a date is selected - @param settings object - update the dialog date picker instance's settings (anonymous object) -@@ -262,24 +248,25 @@ - event - with x/y coordinates or - leave empty for default (screen centre) - @return the manager object */ -- dialogDatepicker: function(dateText, onSelect, settings, pos) { -+ _dialogDatepicker: function(input, dateText, onSelect, settings, pos) { - var inst = this._dialogInst; // internal instance - if (!inst) { -- inst = this._dialogInst = new DatepickerInstance({}, false); -- this._dialogInput = $(''); -+ var id = 'dp' + new Date().getTime(); -+ this._dialogInput = $(''); - this._dialogInput.keydown(this._doKeyDown); - $('body').append(this._dialogInput); -- this._dialogInput[0]._calId = inst._id; -+ inst = this._dialogInst = this._newInst(this._dialogInput, false); -+ inst.settings = {}; -+ $.data(this._dialogInput[0], PROP_NAME, inst); - } -- extendRemove(inst._settings, settings || {}); -+ extendRemove(inst.settings, settings || {}); - this._dialogInput.val(dateText); - - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); - if (!this._pos) { -- var browserWidth = window.innerWidth || document.documentElement.clientWidth || -- document.body.clientWidth; -- var browserHeight = window.innerHeight || document.documentElement.clientHeight || -- document.body.clientHeight; -+ var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; -+ var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; - var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - var scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below -@@ -288,43 +275,176 @@ - - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); -- inst._settings.onSelect = onSelect; -+ inst.settings.onSelect = onSelect; - this._inDialog = true; -- this._datepickerDiv.addClass('datepicker_dialog'); -- this.showFor(this._dialogInput[0]); -- if ($.blockUI) { -- $.blockUI(this._datepickerDiv); -- } -+ this.dpDiv.addClass(this._dialogClass); -+ this._showDatepicker(this._dialogInput[0]); -+ if ($.blockUI) -+ $.blockUI(this.dpDiv); -+ $.data(this._dialogInput[0], PROP_NAME, inst); - return this; - }, - -- /* Pop-up the date picker for a given input field. -- @param control element - the input field attached to the date picker or -- string - the ID or other jQuery selector of the input field or -- object - jQuery object for input field -- @return the manager object */ -- showFor: function(control) { -- control = (control.jquery ? control[0] : -- (typeof control == 'string' ? $(control)[0] : control)); -- var input = (control.nodeName && control.nodeName.toLowerCase() == 'input' ? control : this); -- if (input.nodeName.toLowerCase() != 'input') { // find from button/image trigger -- input = $('input', input.parentNode)[0]; -+ /* Detach a datepicker from its control. -+ @param target element - the target input field or division or span */ -+ _destroyDatepicker: function(target) { -+ var nodeName = target.nodeName.toLowerCase(); -+ var $target = $(target); -+ $.removeData(target, PROP_NAME); -+ if (nodeName == 'input') { -+ $target.siblings('.' + this._appendClass).remove().end(). -+ siblings('.' + this._triggerClass).remove().end(). -+ removeClass(this.markerClassName). -+ unbind('focus', this._showDatepicker). -+ unbind('keydown', this._doKeyDown). -+ unbind('keypress', this._doKeyPress); -+ } else if (nodeName == 'div' || nodeName == 'span') -+ $target.removeClass(this.markerClassName).empty(); -+ }, -+ -+ /* Enable the date picker to a jQuery selection. -+ @param target element - the target input field or division or span */ -+ _enableDatepicker: function(target) { -+ target.disabled = false; -+ $(target).siblings('button.' + this._triggerClass).each(function() { this.disabled = false; }).end(). -+ siblings('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''}); -+ this._disabledInputs = $.map(this._disabledInputs, -+ function(value) { return (value == target ? null : value); }); // delete entry -+ }, -+ -+ /* Disable the date picker to a jQuery selection. -+ @param target element - the target input field or division or span */ -+ _disableDatepicker: function(target) { -+ target.disabled = true; -+ $(target).siblings('button.' + this._triggerClass).each(function() { this.disabled = true; }).end(). -+ siblings('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'}); -+ this._disabledInputs = $.map(this._disabledInputs, -+ function(value) { return (value == target ? null : value); }); // delete entry -+ this._disabledInputs[this._disabledInputs.length] = target; -+ }, -+ -+ /* Is the first field in a jQuery collection disabled as a datepicker? -+ @param target element - the target input field or division or span -+ @return boolean - true if disabled, false if enabled */ -+ _isDisabledDatepicker: function(target) { -+ if (!target) -+ return false; -+ for (var i = 0; i < this._disabledInputs.length; i++) { -+ if (this._disabledInputs[i] == target) -+ return true; - } -- if ($.datepicker._lastInput == input) { // already here -- return; -+ return false; -+ }, -+ -+ /* Update the settings for a date picker attached to an input field or division. -+ @param target element - the target input field or division or span -+ @param name object - the new settings to update or -+ string - the name of the setting to change or -+ @param value any - the new value for the setting (omit if above is an object) */ -+ _changeDatepicker: function(target, name, value) { -+ var settings = name || {}; -+ if (typeof name == 'string') { -+ settings = {}; -+ settings[name] = value; - } -- if ($(input).isDisabledDatepicker()) { -- return; -+ if (inst = $.data(target, PROP_NAME)) { -+ extendRemove(inst.settings, settings); -+ this._updateDatepicker(inst); - } -- var inst = $.datepicker._getInst(input._calId); -- var beforeShow = inst._get('beforeShow'); -- extendRemove(inst._settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); -- $.datepicker.hideDatepicker(''); -+ }, -+ -+ /* Set the dates for a jQuery selection. -+ @param target element - the target input field or division or span -+ @param date Date - the new date -+ @param endDate Date - the new end date for a range (optional) */ -+ _setDateDatepicker: function(target, date, endDate) { -+ var inst = $.data(target, PROP_NAME); -+ if (inst) { -+ this._setDate(inst, date, endDate); -+ this._updateDatepicker(inst); -+ } -+ }, -+ -+ /* Get the date(s) for the first entry in a jQuery selection. -+ @param target element - the target input field or division or span -+ @return Date - the current date or -+ Date[2] - the current dates for a range */ -+ _getDateDatepicker: function(target) { -+ var inst = $.data(target, PROP_NAME); -+ if (inst) -+ this._setDateFromField(inst); -+ return (inst ? this._getDate(inst) : null); -+ }, -+ -+ /* Handle keystrokes. */ -+ _doKeyDown: function(e) { -+ var inst = $.data(e.target, PROP_NAME); -+ var handled = true; -+ if ($.datepicker._datepickerShowing) -+ switch (e.keyCode) { -+ case 9: $.datepicker._hideDatepicker(null, ''); -+ break; // hide on tab out -+ case 13: $.datepicker._selectDay(e.target, inst.selectedMonth, inst.selectedYear, -+ $('td.ui-datepicker-days-cell-over', inst.dpDiv)[0]); -+ return false; // don't submit the form -+ break; // select the value on enter -+ case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); -+ break; // hide on escape -+ case 33: $.datepicker._adjustDate(e.target, (e.ctrlKey ? -1 : -+ -$.datepicker._get(inst, 'stepMonths')), (e.ctrlKey ? 'Y' : 'M')); -+ break; // previous month/year on page up/+ ctrl -+ case 34: $.datepicker._adjustDate(e.target, (e.ctrlKey ? +1 : -+ +$.datepicker._get(inst, 'stepMonths')), (e.ctrlKey ? 'Y' : 'M')); -+ break; // next month/year on page down/+ ctrl -+ case 35: if (e.ctrlKey) $.datepicker._clearDate(e.target); -+ break; // clear on ctrl+end -+ case 36: if (e.ctrlKey) $.datepicker._gotoToday(e.target); -+ break; // current on ctrl+home -+ case 37: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -1, 'D'); -+ break; // -1 day on ctrl+left -+ case 38: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -7, 'D'); -+ break; // -1 week on ctrl+up -+ case 39: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +1, 'D'); -+ break; // +1 day on ctrl+right -+ case 40: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +7, 'D'); -+ break; // +1 week on ctrl+down -+ default: handled = false; -+ } -+ else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home -+ $.datepicker._showDatepicker(this); -+ else -+ handled = false; -+ if (handled) { -+ e.preventDefault(); -+ e.stopPropagation(); -+ } -+ }, -+ -+ /* Filter entered characters - based on date format. */ -+ _doKeyPress: function(e) { -+ var inst = $.data(e.target, PROP_NAME); -+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); -+ var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode); -+ return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); -+ }, -+ -+ /* Pop-up the date picker for a given input field. -+ @param input element - the input field attached to the date picker or -+ event - if triggered by focus */ -+ _showDatepicker: function(input) { -+ input = input.target || input; -+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger -+ input = $('input', input.parentNode)[0]; -+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here -+ return; -+ var inst = $.data(input, PROP_NAME); -+ var beforeShow = $.datepicker._get(inst, 'beforeShow'); -+ extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); -+ $.datepicker._hideDatepicker(null, ''); - $.datepicker._lastInput = input; -- inst._setDateFromField(input); -- if ($.datepicker._inDialog) { // hide cursor -+ $.datepicker._setDateFromField(inst); -+ if ($.datepicker._inDialog) // hide cursor - input.value = ''; -- } - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height -@@ -332,150 +452,134 @@ - var isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css('position') == 'fixed'; -+ return !isFixed; - }); - if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled - $.datepicker._pos[0] -= document.documentElement.scrollLeft; - $.datepicker._pos[1] -= document.documentElement.scrollTop; - } -- inst._datepickerDiv.css('position', ($.datepicker._inDialog && $.blockUI ? -- 'static' : (isFixed ? 'fixed' : 'absolute'))). -- css('left', $.datepicker._pos[0] + 'px').css('top', $.datepicker._pos[1] + 'px'); -+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; - $.datepicker._pos = null; -- $.datepicker._showDatepicker(inst); -- return this; -- }, -- -- /* Construct and display the date picker. */ -- _showDatepicker: function(id) { -- var inst = this._getInst(id); -- inst._rangeStart = null; -- this._updateDatepicker(inst); -- if (!inst._inline) { -- var speed = inst._get('speed'); -+ inst.rangeStart = null; -+ // determine sizing offscreen -+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); -+ $.datepicker._updateDatepicker(inst); -+ // fix width for dynamic number of date pickers -+ inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] * -+ $('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth); -+ // and adjust position before showing -+ offset = $.datepicker._checkOffset(inst, offset, isFixed); -+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? -+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', -+ left: offset.left + 'px', top: offset.top + 'px'}); -+ if (!inst.inline) { -+ var showAnim = $.datepicker._get(inst, 'showAnim') || 'show'; -+ var duration = $.datepicker._get(inst, 'duration'); - var postProcess = function() { - $.datepicker._datepickerShowing = true; -- $.datepicker._afterShow(inst); -+ if ($.browser.msie && parseInt($.browser.version) < 7) // fix IE < 7 select problems -+ $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4, -+ height: inst.dpDiv.height() + 4}); - }; -- var showAnim = inst._get('showAnim') || 'show'; -- inst._datepickerDiv[showAnim](speed, postProcess); -- if (speed == '') { -+ if ($.effects && $.effects[showAnim]) -+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); -+ else -+ inst.dpDiv[showAnim](duration, postProcess); -+ if (duration == '') - postProcess(); -- } -- if (inst._input[0].type != 'hidden') { -- inst._input[0].focus(); -- } -- this._curInst = inst; -+ if (inst.input[0].type != 'hidden') -+ inst.input[0].focus(); -+ $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function(inst) { -- inst._datepickerDiv.empty().append(inst._generateDatepicker()); -- var numMonths = inst._getNumberOfMonths(); -- if (numMonths[0] != 1 || numMonths[1] != 1) { -- inst._datepickerDiv.addClass('datepicker_multi'); -- } -- else { -- inst._datepickerDiv.removeClass('datepicker_multi'); -- } -- if (inst._get('isRTL')) { -- inst._datepickerDiv.addClass('datepicker_rtl'); -- } -- else { -- inst._datepickerDiv.removeClass('datepicker_rtl'); -- } -- if (inst._input && inst._input[0].type != 'hidden') { -- inst._input[0].focus(); -- } -+ var dims = {width: inst.dpDiv.width() + 4, -+ height: inst.dpDiv.height() + 4}; -+ inst.dpDiv.empty().append(this._generateDatepicker(inst)). -+ find('iframe.ui-datepicker-cover'). -+ css({width: dims.width, height: dims.height}); -+ var numMonths = this._getNumberOfMonths(inst); -+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + -+ 'Class']('ui-datepicker-multi'); -+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + -+ 'Class']('ui-datepicker-rtl'); -+ if (inst.input && inst.input[0].type != 'hidden') -+ $(inst.input[0]).focus(); - }, - -- /* Tidy up after displaying the date picker. */ -- _afterShow: function(inst) { -- var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers -- inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0]).width()); -- if ($.browser.msie && parseInt($.browser.version) < 7) { // fix IE < 7 select problems -- $('#datepicker_cover').css({width: inst._datepickerDiv.width() + 4, -- height: inst._datepickerDiv.height() + 4}); -- } -- // re-position on screen if necessary -- var isFixed = inst._datepickerDiv.css('position') == 'fixed'; -- var pos = inst._input ? $.datepicker._findPos(inst._input[0]) : null; -- var browserWidth = window.innerWidth || document.documentElement.clientWidth || -- document.body.clientWidth; -- var browserHeight = window.innerHeight || document.documentElement.clientHeight || -- document.body.clientHeight; -- var scrollX = (isFixed ? 0 : document.documentElement.scrollLeft || document.body.scrollLeft); -- var scrollY = (isFixed ? 0 : document.documentElement.scrollTop || document.body.scrollTop); -+ /* Check positioning to remain on screen. */ -+ _checkOffset: function(inst, offset, isFixed) { -+ var pos = inst.input ? this._findPos(inst.input[0]) : null; -+ var browserWidth = window.innerWidth || document.documentElement.clientWidth; -+ var browserHeight = window.innerHeight || document.documentElement.clientHeight; -+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; -+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop; - // reposition date picker horizontally if outside the browser window -- if ((inst._datepickerDiv.offset().left + inst._datepickerDiv.width() - -- (isFixed && $.browser.msie ? document.documentElement.scrollLeft : 0)) > -- (browserWidth + scrollX)) { -- inst._datepickerDiv.css('left', Math.max(scrollX, -- pos[0] + (inst._input ? $(inst._input[0]).width() : null) - inst._datepickerDiv.width() - -- (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)) + 'px'); -- } -+ if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth) -+ offset.left = Math.max((isFixed ? 0 : scrollX), -+ pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() - -+ (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)); -+ else -+ offset.left -= (isFixed ? scrollX : 0); - // reposition date picker vertically if outside the browser window -- if ((inst._datepickerDiv.offset().top + inst._datepickerDiv.height() - -- (isFixed && $.browser.msie ? document.documentElement.scrollTop : 0)) > -- (browserHeight + scrollY) ) { -- inst._datepickerDiv.css('top', Math.max(scrollY, -- pos[1] - (this._inDialog ? 0 : inst._datepickerDiv.height()) - -- (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + 'px'); -- } -+ if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight) -+ offset.top = Math.max((isFixed ? 0 : scrollY), -+ pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) - -+ (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)); -+ else -+ offset.top -= (isFixed ? scrollY : 0); -+ return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function(obj) { -- while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { -- obj = obj.nextSibling; -- } -- var curleft = curtop = 0; -- if (obj && obj.offsetParent) { -- curleft = obj.offsetLeft; -- curtop = obj.offsetTop; -- while (obj = obj.offsetParent) { -- var origcurleft = curleft; -- curleft += obj.offsetLeft; -- if (curleft < 0) { -- curleft = origcurleft; -- } -- curtop += obj.offsetTop; -- } -- } -- return [curleft,curtop]; -+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { -+ obj = obj.nextSibling; -+ } -+ var position = $(obj).offset(); -+ return [position.left, position.top]; - }, - - /* Hide the date picker from view. -- @param speed string - the speed at which to close the date picker -- @return void */ -- hideDatepicker: function(speed) { -+ @param input element - the input field attached to the date picker -+ @param duration string - the duration over which to close the date picker */ -+ _hideDatepicker: function(input, duration) { - var inst = this._curInst; -- if (!inst) { -+ if (!inst) - return; -- } -- var rangeSelect = inst._get('rangeSelect'); -- if (rangeSelect && this._stayOpen) { -- this._selectDate(inst, inst._formatDate( -- inst._currentDay, inst._currentMonth, inst._currentYear)); -- } -+ var rangeSelect = this._get(inst, 'rangeSelect'); -+ if (rangeSelect && this._stayOpen) -+ this._selectDate('#' + inst.id, this._formatDate(inst, -+ inst.currentDay, inst.currentMonth, inst.currentYear)); - this._stayOpen = false; - if (this._datepickerShowing) { -- speed = (speed != null ? speed : inst._get('speed')); -- inst._datepickerDiv.hide(speed, function() { -+ duration = (duration != null ? duration : this._get(inst, 'duration')); -+ var showAnim = this._get(inst, 'showAnim'); -+ var postProcess = function() { - $.datepicker._tidyDialog(inst); -- }); -- if (speed == '') { -+ }; -+ if (duration != '' && $.effects && $.effects[showAnim]) -+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), -+ duration, postProcess); -+ else -+ inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' : -+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess); -+ if (duration == '') - this._tidyDialog(inst); -- } -+ var onClose = this._get(inst, 'onClose'); -+ if (onClose) -+ onClose.apply((inst.input ? inst.input[0] : null), -+ [this._getDate(inst), inst]); // trigger custom callback - this._datepickerShowing = false; - this._lastInput = null; -- inst._settings.prompt = null; -+ inst.settings.prompt = null; - if (this._inDialog) { -- this._dialogInput.css('position', 'absolute'). -- css('left', '0px').css('top', '-100px'); -+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); - if ($.blockUI) { - $.unblockUI(); -- $('body').append(this._datepickerDiv); -+ $('body').append(this.dpDiv); - } - } - this._inDialog = false; -@@ -485,143 +589,168 @@ - - /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { -- inst._datepickerDiv.removeClass('datepicker_dialog') -- .unbind(".datepicker"); -- $('.datepicker_prompt', inst._datepickerDiv).remove(); -+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker'); -+ $('.' + this._promptClass, inst.dpDiv).remove(); - }, - - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { -- if (!$.datepicker._curInst) { -+ if (!$.datepicker._curInst) - return; -- } -- var target = $(event.target); -- if ((target.parents("#datepicker_div").length == 0) && -- (target.attr('class') != 'datepicker_trigger') && -- $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) { -- $.datepicker.hideDatepicker(''); -- } -+ var $target = $(event.target); -+ if (($target.parents('#' + $.datepicker._mainDivId).length == 0) && -+ !$target.hasClass($.datepicker.markerClassName) && -+ !$target.hasClass($.datepicker._triggerClass) && -+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) -+ $.datepicker._hideDatepicker(null, ''); - }, - - /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { -- var inst = this._getInst(id); -- inst._adjustDate(offset, period); -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ this._adjustInstDate(inst, offset, period); - this._updateDatepicker(inst); - }, - - /* Action for current link. */ - _gotoToday: function(id) { -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) { -+ inst.selectedDay = inst.currentDay; -+ inst.drawMonth = inst.selectedMonth = inst.currentMonth; -+ inst.drawYear = inst.selectedYear = inst.currentYear; -+ } -+ else { - var date = new Date(); -- var inst = this._getInst(id); -- inst._selectedDay = date.getDate(); -- inst._selectedMonth = date.getMonth(); -- inst._selectedYear = date.getFullYear(); -- this._adjustDate(inst); -+ inst.selectedDay = date.getDate(); -+ inst.drawMonth = inst.selectedMonth = date.getMonth(); -+ inst.drawYear = inst.selectedYear = date.getFullYear(); -+ } -+ this._adjustDate(target); -+ this._notifyChange(inst); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { -- var inst = this._getInst(id); -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); - inst._selectingMonthYear = false; -- inst[period == 'M' ? '_selectedMonth' : '_selectedYear'] = -+ inst[period == 'M' ? 'drawMonth' : 'drawYear'] = - select.options[select.selectedIndex].value - 0; -- this._adjustDate(inst); -+ this._adjustDate(target); -+ this._notifyChange(inst); - }, - - /* Restore input focus after not changing month/year. */ - _clickMonthYear: function(id) { -- var inst = this._getInst(id); -- if (inst._input && inst._selectingMonthYear && !$.browser.msie) { -- inst._input[0].focus(); -- } -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ if (inst.input && inst._selectingMonthYear && !$.browser.msie) -+ inst.input[0].focus(); - inst._selectingMonthYear = !inst._selectingMonthYear; - }, - - /* Action for changing the first week day. */ - _changeFirstDay: function(id, day) { -- var inst = this._getInst(id); -- inst._settings.firstDay = day; -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ inst.settings.firstDay = day; - this._updateDatepicker(inst); - }, - - /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { -- if (this._hasClass($(td), 'datepicker_unselectable')) { -+ if ($(td).hasClass(this._unselectableClass)) - return; -- } -- var inst = this._getInst(id); -- var rangeSelect = inst._get('rangeSelect'); -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ var rangeSelect = this._get(inst, 'rangeSelect'); - if (rangeSelect) { -- if (!this._stayOpen) { -- $('.datepicker td').removeClass('datepicker_currentDay'); -- $(td).addClass('datepicker_currentDay'); -- } - this._stayOpen = !this._stayOpen; -+ if (this._stayOpen) { -+ $('.ui-datepicker td').removeClass(this._currentClass); -+ $(td).addClass(this._currentClass); -+ } - } -- inst._currentDay = $('a', td).html(); -- inst._currentMonth = month; -- inst._currentYear = year; -- this._selectDate(id, inst._formatDate( -- inst._currentDay, inst._currentMonth, inst._currentYear)); -+ inst.selectedDay = inst.currentDay = $('a', td).html(); -+ inst.selectedMonth = inst.currentMonth = month; -+ inst.selectedYear = inst.currentYear = year; - if (this._stayOpen) { -- inst._endDay = inst._endMonth = inst._endYear = null; -- inst._rangeStart = new Date(inst._currentYear, inst._currentMonth, inst._currentDay); -+ inst.endDay = inst.endMonth = inst.endYear = null; -+ } -+ else if (rangeSelect) { -+ inst.endDay = inst.currentDay; -+ inst.endMonth = inst.currentMonth; -+ inst.endYear = inst.currentYear; -+ } -+ this._selectDate(id, this._formatDate(inst, -+ inst.currentDay, inst.currentMonth, inst.currentYear)); -+ if (this._stayOpen) { -+ inst.rangeStart = new Date(inst.currentYear, inst.currentMonth, inst.currentDay); - this._updateDatepicker(inst); - } - else if (rangeSelect) { -- inst._endDay = inst._currentDay; -- inst._endMonth = inst._currentMonth; -- inst._endYear = inst._currentYear; -- inst._selectedDay = inst._currentDay = inst._rangeStart.getDate(); -- inst._selectedMonth = inst._currentMonth = inst._rangeStart.getMonth(); -- inst._selectedYear = inst._currentYear = inst._rangeStart.getFullYear(); -- inst._rangeStart = null; -- if (inst._inline) { -+ inst.selectedDay = inst.currentDay = inst.rangeStart.getDate(); -+ inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth(); -+ inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear(); -+ inst.rangeStart = null; -+ if (inst.inline) - this._updateDatepicker(inst); -- } - } - }, - - /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { -- var inst = this._getInst(id); -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ if (this._get(inst, 'mandatory')) -+ return; - this._stayOpen = false; -- inst._endDay = inst._endMonth = inst._endYear = inst._rangeStart = null; -- this._selectDate(inst, ''); -+ inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null; -+ this._selectDate(target, ''); - }, - - /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { -- var inst = this._getInst(id); -- dateStr = (dateStr != null ? dateStr : inst._formatDate()); -- if (inst._rangeStart) { -- dateStr = inst._formatDate(inst._rangeStart) + inst._get('rangeSeparator') + dateStr; -- } -- if (inst._input) { -- inst._input.val(dateStr); -- } -- var onSelect = inst._get('onSelect'); -- if (onSelect) { -- onSelect.apply((inst._input ? inst._input[0] : null), [dateStr, inst]); // trigger custom callback -- } -- else { -- if (inst._input) { -- inst._input.trigger('change'); // fire the change event -- } -- } -- if (inst._inline) { -+ var target = $(id); -+ var inst = $.data(target[0], PROP_NAME); -+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); -+ if (this._get(inst, 'rangeSelect') && dateStr) -+ dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) : -+ dateStr) + this._get(inst, 'rangeSeparator') + dateStr; -+ if (inst.input) -+ inst.input.val(dateStr); -+ this._updateAlternate(inst); -+ var onSelect = this._get(inst, 'onSelect'); -+ if (onSelect) -+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback -+ else if (inst.input) -+ inst.input.trigger('change'); // fire the change event -+ if (inst.inline) - this._updateDatepicker(inst); -+ else if (!this._stayOpen) { -+ this._hideDatepicker(null, this._get(inst, 'duration')); -+ this._lastInput = inst.input[0]; -+ if (typeof(inst.input[0]) != 'object') -+ inst.input[0].focus(); // restore focus -+ this._lastInput = null; - } -- else { -- if (!this._stayOpen) { -- this.hideDatepicker(inst._get('speed')); -- this._lastInput = inst._input[0]; -- if (typeof(inst._input[0]) != 'object') { -- inst._input[0].focus(); // restore focus -- } -- this._lastInput = null; -- } -+ }, -+ -+ /* Update any alternate field to synchronise with the main field. */ -+ _updateAlternate: function(inst) { -+ var altField = this._get(inst, 'altField'); -+ if (altField) { // update alternate field too -+ var altFormat = this._get(inst, 'altFormat'); -+ var date = this._getDate(inst); -+ dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' : -+ this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) + -+ this._get(inst, 'rangeSeparator') + this.formatDate( -+ altFormat, date[1] || date[0], this._getFormatConfig(inst))) : -+ this.formatDate(altFormat, date, this._getFormatConfig(inst))); -+ $(altField).each(function() { $(this).val(dateStr); }); - } - }, - -@@ -637,15 +766,14 @@ - @param date Date - the date to get the week for - @return number - the number of the week within the year that contains this date */ - iso8601Week: function(date) { -- var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); -+ var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60)); - var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan - var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7 - firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday - if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary - checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year - return $.datepicker.iso8601Week(checkDate); -- } -- else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year -+ } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year - firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7; - if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary - checkDate.setDate(checkDate.getDate() + 3); // Generate for next year -@@ -660,42 +788,28 @@ - @param inst the current datepicker instance - @return the status display text for this date */ - dateStatus: function(date, inst) { -- return $.datepicker.formatDate(inst._get('dateStatus'), date, inst._getFormatConfig()); -+ return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'), -+ date, $.datepicker._getFormatConfig(inst)); - }, - - /* Parse a string value into a date object. -- The format can be combinations of the following: -- d - day of month (no leading zero) -- dd - day of month (two digit) -- D - day name short -- DD - day name long -- m - month of year (no leading zero) -- mm - month of year (two digit) -- M - month name short -- MM - month name long -- y - year (two digit) -- yy - year (four digit) -- '...' - literal text -- '' - single quote -+ See formatDate below for the possible formats. - -- @param format String - the expected format of the date -- @param value String - the date in the above format -+ @param format string - the expected format of the date -+ @param value string - the date in the above format - @param settings Object - attributes include: -- shortYearCutoff Number - the cutoff year for determining the century (optional) -- dayNamesShort String[7] - abbreviated names of the days from Sunday (optional) -- dayNames String[7] - names of the days from Sunday (optional) -- monthNamesShort String[12] - abbreviated names of the months (optional) -- monthNames String[12] - names of the months (optional) -+ shortYearCutoff number - the cutoff year for determining the century (optional) -+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) -+ dayNames string[7] - names of the days from Sunday (optional) -+ monthNamesShort string[12] - abbreviated names of the months (optional) -+ monthNames string[12] - names of the months (optional) - @return Date - the extracted date value or null if value is blank */ - parseDate: function (format, value, settings) { -- if (format == null || value == null) { -+ if (format == null || value == null) - throw 'Invalid arguments'; -- } --// format = dateFormats[format] || format; - value = (typeof value == 'object' ? value.toString() : value + ''); -- if (value == '') { -+ if (value == '') - return null; -- } - var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; -@@ -708,64 +822,56 @@ - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); -- if (matches) { -+ if (matches) - iFormat++; -- } - return matches; - }; - // Extract a number from the string value - var getNumber = function(match) { - lookAhead(match); -- var size = (match == 'y' ? 4 : 2); -+ var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : 2)); -+ var size = origSize; - var num = 0; - while (size > 0 && iValue < value.length && - value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { - num = num * 10 + (value.charAt(iValue++) - 0); - size--; - } -- if (size == (match == 'y' ? 4 : 2)) { -+ if (size == origSize) - throw 'Missing number at position ' + iValue; -- } - return num; - }; - // Extract a name from the string value and convert to an index - var getName = function(match, shortNames, longNames) { - var names = (lookAhead(match) ? longNames : shortNames); - var size = 0; -- for (var j = 0; j < names.length; j++) { -+ for (var j = 0; j < names.length; j++) - size = Math.max(size, names[j].length); -- } - var name = ''; - var iInit = iValue; - while (size > 0 && iValue < value.length) { - name += value.charAt(iValue++); -- for (var i = 0; i < names.length; i++) { -- if (name == names[i]) { -+ for (var i = 0; i < names.length; i++) -+ if (name == names[i]) - return i + 1; -- } -- } - size--; - } - throw 'Unknown name at position ' + iInit; - }; - // Confirm that a literal character matches the string value - var checkLiteral = function() { -- if (value.charAt(iValue) != format.charAt(iFormat)) { -+ if (value.charAt(iValue) != format.charAt(iFormat)) - throw 'Unexpected literal at position ' + iValue; -- } - iValue++; - }; - var iValue = 0; - for (var iFormat = 0; iFormat < format.length; iFormat++) { -- if (literal) { -- if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) { -+ if (literal) -+ if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; -- } -- else { -+ else - checkLiteral(); -- } -- } -- else { -+ else - switch (format.charAt(iFormat)) { - case 'd': - day = getNumber('d'); -@@ -782,30 +888,44 @@ - case 'y': - year = getNumber('y'); - break; -- case '\'': -- if (lookAhead('\'')) { -+ case '@': -+ var date = new Date(getNumber('@')); -+ year = date.getFullYear(); -+ month = date.getMonth() + 1; -+ day = date.getDate(); -+ break; -+ case "'": -+ if (lookAhead("'")) - checkLiteral(); -- } -- else { -+ else - literal = true; -- } - break; - default: - checkLiteral(); - } -- } - } -- if (year < 100) { -+ if (year < 100) - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); -- } - var date = new Date(year, month - 1, day); -- if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) { -+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) - throw 'Invalid date'; // E.g. 31/02/* -- } - return date; - }, - -+ /* Standard date formats. */ -+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) -+ COOKIE: 'D, dd M yy', -+ ISO_8601: 'yy-mm-dd', -+ RFC_822: 'D, d M y', -+ RFC_850: 'DD, dd-M-y', -+ RFC_1036: 'D, d M y', -+ RFC_1123: 'D, d M yy', -+ RFC_2822: 'D, d M yy', -+ RSS: 'D, d M y', // RFC 822 -+ TIMESTAMP: '@', -+ W3C: 'yy-mm-dd', // ISO 8601 -+ - /* Format a date object into a string value. - The format can be combinations of the following: - d - day of month (no leading zero) -@@ -818,22 +938,21 @@ - MM - month name long - y - year (two digit) - yy - year (four digit) -+ @ - Unix timestamp (ms since 01/01/1970) - '...' - literal text - '' - single quote - -- @param format String - the desired format of the date -+ @param format string - the desired format of the date - @param date Date - the date value to format - @param settings Object - attributes include: -- dayNamesShort String[7] - abbreviated names of the days from Sunday (optional) -- dayNames String[7] - names of the days from Sunday (optional) -- monthNamesShort String[12] - abbreviated names of the months (optional) -- monthNames String[12] - names of the months (optional) -- @return String - the date in the above format */ -+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) -+ dayNames string[7] - names of the days from Sunday (optional) -+ monthNamesShort string[12] - abbreviated names of the months (optional) -+ monthNames string[12] - names of the months (optional) -+ @return string - the date in the above format */ - formatDate: function (format, date, settings) { -- if (!date) { -+ if (!date) - return ''; -- } --// format = dateFormats[format] || format; - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; -@@ -841,9 +960,8 @@ - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); -- if (matches) { -+ if (matches) - iFormat++; -- } - return matches; - }; - // Format a number, with leading zero if necessary -@@ -856,17 +974,14 @@ - }; - var output = ''; - var literal = false; -- if (date) { -+ if (date) - for (var iFormat = 0; iFormat < format.length; iFormat++) { -- if (literal) { -- if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) { -+ if (literal) -+ if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; -- } -- else { -+ else - output += format.charAt(iFormat); -- } -- } -- else { -+ else - switch (format.charAt(iFormat)) { - case 'd': - output += formatNumber('d', date.getDate()); -@@ -884,136 +999,112 @@ - output += (lookAhead('y') ? date.getFullYear() : - (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); - break; -- case '\'': -- if (lookAhead('\'')) { -- output += '\''; -- } -- else { -+ case '@': -+ output += date.getTime(); -+ break; -+ case "'": -+ if (lookAhead("'")) -+ output += "'"; -+ else - literal = true; -- } - break; - default: - output += format.charAt(iFormat); - } -- } - } -- } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { --// format = dateFormats[format] || format; - var chars = ''; - var literal = false; -- for (var iFormat = 0; iFormat < format.length; iFormat++) { -- if (literal) { -- if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) { -+ for (var iFormat = 0; iFormat < format.length; iFormat++) -+ if (literal) -+ if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; -- } -- else { -+ else - chars += format.charAt(iFormat); -- } -- } -- else { -+ else - switch (format.charAt(iFormat)) { -- case 'd': -- case 'm': -- case 'y': -+ case 'd': case 'm': case 'y': case '@': - chars += '0123456789'; - break; -- case 'D': -- case 'M': -+ case 'D': case 'M': - return null; // Accept anything -- case '\'': -- if (lookAhead('\'')) { -- chars += '\''; -- } -- else { -+ case "'": -+ if (lookAhead("'")) -+ chars += "'"; -+ else - literal = true; -- } - break; - default: - chars += format.charAt(iFormat); - } -- } -- } - return chars; -- } --}); -+ }, - --/* Individualised settings for date picker functionality applied to one or more related inputs. -- Instances are managed and manipulated through the Datepicker manager. */ --function DatepickerInstance(settings, inline) { -- this._id = $.datepicker._register(this); -- this._selectedDay = 0; -- this._selectedMonth = 0; // 0-11 -- this._selectedYear = 0; // 4-digit year -- this._input = null; // The attached input field -- this._inline = inline; // True if showing inline, false if used in a popup -- this._datepickerDiv = (!inline ? $.datepicker._datepickerDiv : -- $('
')); -- // customise the date picker object - uses manager defaults if not overridden -- this._settings = extendRemove({}, settings || {}); // clone -- if (inline) { -- this._setDate(this._getDefaultDate()); -- } --} -- --$.extend(DatepickerInstance.prototype, { - /* Get a setting value, defaulting if necessary. */ -- _get: function(name) { -- return (this._settings[name] != null ? this._settings[name] : $.datepicker._defaults[name]); -+ _get: function(inst, name) { -+ return inst.settings[name] !== undefined ? -+ inst.settings[name] : this._defaults[name]; - }, - - /* Parse existing date and initialise date picker. */ -- _setDateFromField: function(input) { -- this._input = $(input); -- var dateFormat = this._get('dateFormat'); -- var dates = this._input ? this._input.val().split(this._get('rangeSeparator')) : null; -- this._endDay = this._endMonth = this._endYear = null; -- var date = defaultDate = this._getDefaultDate(); -+ _setDateFromField: function(inst) { -+ var dateFormat = this._get(inst, 'dateFormat'); -+ var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null; -+ inst.endDay = inst.endMonth = inst.endYear = null; -+ var date = defaultDate = this._getDefaultDate(inst); - if (dates.length > 0) { -- var settings = this._getFormatConfig(); -+ var settings = this._getFormatConfig(inst); - if (dates.length > 1) { -- date = $.datepicker.parseDate(dateFormat, dates[1], settings) || defaultDate; -- this._endDay = date.getDate(); -- this._endMonth = date.getMonth(); -- this._endYear = date.getFullYear(); -+ date = this.parseDate(dateFormat, dates[1], settings) || defaultDate; -+ inst.endDay = date.getDate(); -+ inst.endMonth = date.getMonth(); -+ inst.endYear = date.getFullYear(); - } - try { -- date = $.datepicker.parseDate(dateFormat, dates[0], settings) || defaultDate; -- } -- catch (e) { -- $.datepicker.log(e); -+ date = this.parseDate(dateFormat, dates[0], settings) || defaultDate; -+ } catch (e) { -+ this.log(e); - date = defaultDate; - } - } -- this._selectedDay = this._currentDay = date.getDate(); -- this._selectedMonth = this._currentMonth = date.getMonth(); -- this._selectedYear = this._currentYear = date.getFullYear(); -- this._adjustDate(); -+ inst.selectedDay = date.getDate(); -+ inst.drawMonth = inst.selectedMonth = date.getMonth(); -+ inst.drawYear = inst.selectedYear = date.getFullYear(); -+ inst.currentDay = (dates[0] ? date.getDate() : 0); -+ inst.currentMonth = (dates[0] ? date.getMonth() : 0); -+ inst.currentYear = (dates[0] ? date.getFullYear() : 0); -+ this._adjustInstDate(inst); - }, - - /* Retrieve the default date shown on opening. */ -- _getDefaultDate: function() { -- return this._determineDate('defaultDate', new Date()); -+ _getDefaultDate: function(inst) { -+ var date = this._determineDate(this._get(inst, 'defaultDate'), new Date()); -+ var minDate = this._getMinMaxDate(inst, 'min', true); -+ var maxDate = this._getMinMaxDate(inst, 'max'); -+ date = (minDate && date < minDate ? minDate : date); -+ date = (maxDate && date > maxDate ? maxDate : date); -+ return date; - }, - - /* A date may be specified as an exact value or a relative one. */ -- _determineDate: function(name, defaultDate) { -+ _determineDate: function(date, defaultDate) { - var offsetNumeric = function(offset) { - var date = new Date(); -- date.setDate(date.getDate() + offset); -+ date.setUTCDate(date.getUTCDate() + offset); - return date; - }; - var offsetString = function(offset, getDaysInMonth) { - var date = new Date(); -- var matches = /^([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?$/.exec(offset); -- if (matches) { -- var year = date.getFullYear(); -- var month = date.getMonth(); -- var day = date.getDate(); -+ var year = date.getFullYear(); -+ var month = date.getMonth(); -+ var day = date.getDate(); -+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; -+ var matches = pattern.exec(offset); -+ while (matches) { - switch (matches[2] || 'd') { - case 'd' : case 'D' : - day += (matches[1] - 0); break; -@@ -1028,74 +1119,80 @@ - day = Math.min(day, getDaysInMonth(year, month)); - break; - } -- date = new Date(year, month, day); -+ matches = pattern.exec(offset); - } -- return date; -+ return new Date(year, month, day); - }; -- var date = this._get(name); - return (date == null ? defaultDate : - (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) : - (typeof date == 'number' ? offsetNumeric(date) : date))); - }, - - /* Set the date(s) directly. */ -- _setDate: function(date, endDate) { -- this._selectedDay = this._currentDay = date.getDate(); -- this._selectedMonth = this._currentMonth = date.getMonth(); -- this._selectedYear = this._currentYear = date.getFullYear(); -- if (this._get('rangeSelect')) { -+ _setDate: function(inst, date, endDate) { -+ var clear = !(date); -+ date = this._determineDate(date, new Date()); -+ inst.selectedDay = inst.currentDay = date.getDate(); -+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); -+ inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); -+ if (this._get(inst, 'rangeSelect')) { - if (endDate) { -- this._endDay = endDate.getDate(); -- this._endMonth = endDate.getMonth(); -- this._endYear = endDate.getFullYear(); -+ endDate = this._determineDate(endDate, null); -+ inst.endDay = endDate.getDate(); -+ inst.endMonth = endDate.getMonth(); -+ inst.endYear = endDate.getFullYear(); -+ } else { -+ inst.endDay = inst.currentDay; -+ inst.endMonth = inst.currentMonth; -+ inst.endYear = inst.currentYear; - } -- else { -- this._endDay = this._currentDay; -- this._endMonth = this._currentMonth; -- this._endYear = this._currentYear; -- } - } -- this._adjustDate(); -+ this._adjustInstDate(inst); -+ if (inst.input) -+ inst.input.val(clear ? '' : this._formatDate(inst) + -+ (!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') + -+ this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear))); - }, - - /* Retrieve the date(s) directly. */ -- _getDate: function() { -- var startDate = (!this._currentYear || (this._input && this._input.val() == '') ? null : -- new Date(this._currentYear, this._currentMonth, this._currentDay)); -- if (this._get('rangeSelect')) { -- return [startDate, (!this._endYear ? null : -- new Date(this._endYear, this._endMonth, this._endDay))]; -- } -- else { -+ _getDate: function(inst) { -+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : -+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); -+ if (this._get(inst, 'rangeSelect')) { -+ return [inst.rangeStart || startDate, (!inst.endYear ? null : -+ new Date(inst.endYear, inst.endMonth, inst.endDay))]; -+ } else - return startDate; -- } - }, - - /* Generate the HTML for the current state of the date picker. */ -- _generateDatepicker: function() { -+ _generateDatepicker: function(inst) { - var today = new Date(); - today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time -- var showStatus = this._get('showStatus'); -- var isRTL = this._get('isRTL'); -+ var showStatus = this._get(inst, 'showStatus'); -+ var isRTL = this._get(inst, 'isRTL'); - // build the date picker HTML -- var clear = (this._get('mandatory') ? '' : -- '
' + -- this._get('clearText') + '
'); -- var controls = '
' + (isRTL ? '' : clear) + -- '' + (isRTL ? clear : '') + '
'; -- var prompt = this._get('prompt'); -- var closeAtTop = this._get('closeAtTop'); -- var hideIfNoPrevNext = this._get('hideIfNoPrevNext'); -- var numMonths = this._getNumberOfMonths(); -- var stepMonths = this._get('stepMonths'); -+ var clear = (this._get(inst, 'mandatory') ? '' : -+ '
' + -+ this._get(inst, 'clearText') + '
'); -+ var controls = '
' + (isRTL ? '' : clear) + -+ '' + (isRTL ? clear : '') + '
'; -+ var prompt = this._get(inst, 'prompt'); -+ var closeAtTop = this._get(inst, 'closeAtTop'); -+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); -+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); -+ var numMonths = this._getNumberOfMonths(inst); -+ var stepMonths = this._get(inst, 'stepMonths'); - var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); -- var minDate = this._getMinMaxDate('min', true); -- var maxDate = this._getMinMaxDate('max'); -- var drawMonth = this._selectedMonth; -- var drawYear = this._selectedYear; -+ var currentDate = (!inst.currentDay ? new Date(9999, 9, 9) : -+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); -+ var minDate = this._getMinMaxDate(inst, 'min', true); -+ var maxDate = this._getMinMaxDate(inst, 'max'); -+ var drawMonth = inst.drawMonth; -+ var drawYear = inst.drawYear; - if (maxDate) { - var maxDraw = new Date(maxDate.getFullYear(), - maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()); -@@ -1109,167 +1206,174 @@ - } - } - // controls and links -- var prev = '
' + (this._canAdjustMonth(-1, drawYear, drawMonth) ? -- '' + -- this._get('prevText') + '' : -- (hideIfNoPrevNext ? '' : '')) + '
'; -- var next = '
' + (this._canAdjustMonth(+1, drawYear, drawMonth) ? -- '' + -- this._get('nextText') + '' : -- (hideIfNoPrevNext ? '>' : '')) + '
'; -- var html = (prompt ? '
' + prompt + '
' : '') + -- (closeAtTop && !this._inline ? controls : '') + -- ''; -- var showWeeks = this._get('showWeeks'); -- for (var row = 0; row < numMonths[0]; row++) { -- for (var col = 0; col < numMonths[1]; col++) { -- var selectedDate = new Date(drawYear, drawMonth, this._selectedDay); -- html += '
' + -- this._generateMonthYearHeader(drawMonth, drawYear, minDate, maxDate, -- selectedDate, row > 0 || col > 0) + // draw month headers -- '' + -- '' + -- (showWeeks ? '' : ''); -- var firstDay = this._get('firstDay'); -- var changeFirstDay = this._get('changeFirstDay'); -- var dayNames = this._get('dayNames'); -- var dayNamesShort = this._get('dayNamesShort'); -- var dayNamesMin = this._get('dayNamesMin'); -- for (var dow = 0; dow < 7; dow++) { // days of the week -- var day = (dow + firstDay) % 7; -- var status = this._get('dayStatus') || ' '; -- status = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) : -- status.replace(/D/, dayNamesShort[day])); -- html += '= 5 ? ' class="datepicker_weekEndCell"' : '') + '>' + -- (!changeFirstDay ? '' + -- dayNamesMin[day] + (changeFirstDay ? '' : '') + ''; -- } -- html += ''; -- var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); -- if (drawYear == this._selectedYear && drawMonth == this._selectedMonth) { -- this._selectedDay = Math.min(this._selectedDay, daysInMonth); -- } -- var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; -- var currentDate = new Date(this._currentYear, this._currentMonth, this._currentDay); -- var endDate = this._endDay ? new Date(this._endYear, this._endMonth, this._endDay) : currentDate; -- var printDate = new Date(drawYear, drawMonth, 1 - leadDays); -- var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate -- var beforeShowDay = this._get('beforeShowDay'); -- var showOtherMonths = this._get('showOtherMonths'); -- var calculateWeek = this._get('calculateWeek') || $.datepicker.iso8601Week; -- var dateStatus = this._get('statusForDate') || $.datepicker.dateStatus; -- for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows -- html += '' + -- (showWeeks ? '' : ''); -- for (var dow = 0; dow < 7; dow++) { // create date picker days -- var daySettings = (beforeShowDay ? -- beforeShowDay.apply((this._input ? this._input[0] : null), [printDate]) : [true, '']); -- var otherMonth = (printDate.getMonth() != drawMonth); -- var unselectable = otherMonth || !daySettings[0] || -- (minDate && printDate < minDate) || (maxDate && printDate > maxDate); -- html += ''; // display for this month -- printDate.setDate(printDate.getDate() + 1); -+ var prevText = this._get(inst, 'prevText'); -+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate( -+ prevText, new Date(drawYear, drawMonth - stepMonths, 1), this._getFormatConfig(inst))); -+ var prev = '
' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? -+ '' + prevText + '' : -+ (hideIfNoPrevNext ? '' : '')) + '
'; -+ var nextText = this._get(inst, 'nextText'); -+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate( -+ nextText, new Date(drawYear, drawMonth + stepMonths, 1), this._getFormatConfig(inst))); -+ var next = '
' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? -+ '' + nextText + '' : -+ (hideIfNoPrevNext ? '' : '')) + '
'; -+ var currentText = this._get(inst, 'currentText'); -+ currentText = (!navigationAsDateFormat ? currentText: this.formatDate( -+ currentText, today, this._getFormatConfig(inst))); -+ var html = (prompt ? '
' + prompt + '
' : '') + -+ (closeAtTop && !inst.inline ? controls : '') + -+ ''; -+ var firstDay = this._get(inst, 'firstDay'); -+ var changeFirstDay = this._get(inst, 'changeFirstDay'); -+ var dayNames = this._get(inst, 'dayNames'); -+ var dayNamesShort = this._get(inst, 'dayNamesShort'); -+ var dayNamesMin = this._get(inst, 'dayNamesMin'); -+ var monthNames = this._get(inst, 'monthNames'); -+ var beforeShowDay = this._get(inst, 'beforeShowDay'); -+ var highlightWeek = this._get(inst, 'highlightWeek'); -+ var showOtherMonths = this._get(inst, 'showOtherMonths'); -+ var showWeeks = this._get(inst, 'showWeeks'); -+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; -+ var status = (showStatus ? this._get(inst, 'dayStatus') || ' ' : ''); -+ var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus; -+ var endDate = inst.endDay ? new Date(inst.endYear, inst.endMonth, inst.endDay) : currentDate; -+ for (var row = 0; row < numMonths[0]; row++) -+ for (var col = 0; col < numMonths[1]; col++) { -+ var selectedDate = new Date(drawYear, drawMonth, inst.selectedDay); -+ html += '
' + -+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, -+ selectedDate, row > 0 || col > 0, showStatus, monthNames) + // draw month headers -+ '
' + this._get('weekHeader') + '
' + calculateWeek(printDate) + '' + // actions -- (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months -- (unselectable ? printDate.getDate() : '' + printDate.getDate() + '')) + '
' + -+ '' + -+ (showWeeks ? '' : ''); -+ for (var dow = 0; dow < 7; dow++) { // days of the week -+ var day = (dow + firstDay) % 7; -+ var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) : -+ status.replace(/D/, dayNamesShort[day])); -+ html += '= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' + -+ (!changeFirstDay ? '' + -+ dayNamesMin[day] + (changeFirstDay ? '' : '') + ''; - } -- html += ''; -+ html += ''; -+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); -+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) -+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); -+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; -+ var printDate = new Date(drawYear, drawMonth, 1 - leadDays); -+ var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate -+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows -+ html += '' + -+ (showWeeks ? '' : ''); -+ for (var dow = 0; dow < 7; dow++) { // create date picker days -+ var daySettings = (beforeShowDay ? -+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); -+ var otherMonth = (printDate.getMonth() != drawMonth); -+ var unselectable = otherMonth || !daySettings[0] || -+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate); -+ html += ''; // display for this month -+ printDate.setUTCDate(printDate.getUTCDate() + 1); -+ } -+ html += ''; -+ } -+ drawMonth++; -+ if (drawMonth > 11) { -+ drawMonth = 0; -+ drawYear++; -+ } -+ html += '
' + this._get(inst, 'weekHeader') + '
' + calculateWeek(printDate) + '' + // actions -+ (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months -+ (unselectable ? printDate.getDate() : '' + printDate.getDate() + '')) + '
'; - } -- drawMonth++; -- if (drawMonth > 11) { -- drawMonth = 0; -- drawYear++; -- } -- html += ''; -- } -- } -- html += (showStatus ? '
' + (this._get('initStatus') || ' ') + '
' : '') + -- (!closeAtTop && !this._inline ? controls : '') + -+ html += (showStatus ? '
' + (this._get(inst, 'initStatus') || ' ') + '
' : '') + -+ (!closeAtTop && !inst.inline ? controls : '') + - '
' + -- ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ? -- '' : ''); -+ ($.browser.msie && parseInt($.browser.version) < 7 && !inst.inline ? -+ '' : ''); - return html; - }, - - /* Generate the month and year header. */ -- _generateMonthYearHeader: function(drawMonth, drawYear, minDate, maxDate, selectedDate, secondary) { -- minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); -- var showStatus = this._get('showStatus'); -- var html = '
'; -+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, -+ selectedDate, secondary, showStatus, monthNames) { -+ minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); -+ var html = '
'; - // month selection -- var monthNames = this._get('monthNames'); -- if (secondary || !this._get('changeMonth')) { -+ if (secondary || !this._get(inst, 'changeMonth')) - html += monthNames[drawMonth] + ' '; -- } - else { - var inMinYear = (minDate && minDate.getFullYear() == drawYear); - var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); -- html += ''; - for (var month = 0; month < 12; month++) { - if ((!inMinYear || month >= minDate.getMonth()) && -- (!inMaxYear || month <= maxDate.getMonth())) { -+ (!inMaxYear || month <= maxDate.getMonth())) - html += ''; -- } - } - html += ''; - } - // year selection -- if (secondary || !this._get('changeYear')) { -+ if (secondary || !this._get(inst, 'changeYear')) - html += drawYear; -- } - else { - // determine range of years to display -- var years = this._get('yearRange').split(':'); -+ var years = this._get(inst, 'yearRange').split(':'); - var year = 0; - var endYear = 0; - if (years.length != 2) { - year = drawYear - 10; - endYear = drawYear + 10; -- } -- else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { -- year = drawYear + parseInt(years[0], 10); -- endYear = drawYear + parseInt(years[1], 10); -- } -- else { -+ } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { -+ year = endYear = new Date().getFullYear(); -+ year += parseInt(years[0], 10); -+ endYear += parseInt(years[1], 10); -+ } else { - year = parseInt(years[0], 10); - endYear = parseInt(years[1], 10); - } - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); -- html += ''; - for (; year <= endYear; year++) { - html += '