Projet

Général

Profil

Paste
Télécharger (75,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / jquery_update / replace / ui / ui / jquery.ui.datepicker.js @ 503b3f7b

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