keithsalisbury-subtrac 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/VERSION.yml +1 -1
  2. data/bin/subtrac +2 -0
  3. data/lib/subtrac.rb +85 -50
  4. data/lib/subtrac/config/config.yml +22 -19
  5. data/lib/subtrac/templates/location.erb +2 -2
  6. data/lib/subtrac/templates/projects/blank/trac/wiki/WikiStart +1 -1
  7. data/lib/subtrac/templates/trac.erb +1 -1
  8. data/lib/subtrac/templates/vhost.erb +6 -6
  9. metadata +1 -105
  10. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/__init__.py +0 -0
  11. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/controller.py +0 -419
  12. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.cfg +0 -3
  13. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.py +0 -20
  14. data/lib/subtrac/trac-plugins/clientsplugin/clients/__init__.py +0 -0
  15. data/lib/subtrac/trac-plugins/clientsplugin/clients/action.py +0 -28
  16. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_email.py +0 -168
  17. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_zendesk_forum.py +0 -137
  18. data/lib/subtrac/trac-plugins/clientsplugin/clients/admin.py +0 -91
  19. data/lib/subtrac/trac-plugins/clientsplugin/clients/api.py +0 -199
  20. data/lib/subtrac/trac-plugins/clientsplugin/clients/client.py +0 -105
  21. data/lib/subtrac/trac-plugins/clientsplugin/clients/events.py +0 -287
  22. data/lib/subtrac/trac-plugins/clientsplugin/clients/eventsadmin.py +0 -71
  23. data/lib/subtrac/trac-plugins/clientsplugin/clients/htdocs/clients.css +0 -4
  24. data/lib/subtrac/trac-plugins/clientsplugin/clients/model.py +0 -135
  25. data/lib/subtrac/trac-plugins/clientsplugin/clients/processor.py +0 -70
  26. data/lib/subtrac/trac-plugins/clientsplugin/clients/reportmanager.py +0 -142
  27. data/lib/subtrac/trac-plugins/clientsplugin/clients/reports.py +0 -231
  28. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary.py +0 -27
  29. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_milestone.py +0 -152
  30. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_ticketchanges.py +0 -160
  31. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_client_events.html +0 -124
  32. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_clients.html +0 -134
  33. data/lib/subtrac/trac-plugins/clientsplugin/cron/changes.xslt +0 -132
  34. data/lib/subtrac/trac-plugins/clientsplugin/cron/run-client-event +0 -97
  35. data/lib/subtrac/trac-plugins/clientsplugin/cron/summary.xslt +0 -161
  36. data/lib/subtrac/trac-plugins/clientsplugin/setup.py +0 -43
  37. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/__init__.py +0 -4
  38. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/burndownchart.py +0 -273
  39. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursinplaceeditor.py +0 -44
  40. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursremaining.py +0 -36
  41. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery-1.2.3.min.js +0 -32
  42. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.js +0 -409
  43. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.mini.js +0 -30
  44. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/templates/edithours.html +0 -53
  45. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/burndownchart.py +0 -181
  46. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/hoursremaining.py +0 -66
  47. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/workloadchart.py +0 -47
  48. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/utils.py +0 -93
  49. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/workloadchart.py +0 -86
  50. data/lib/subtrac/trac-plugins/estimationtoolsplugin/setup.py +0 -20
  51. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/SumRollups.js +0 -23
  52. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/adw_tracdb.py +0 -128
  53. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/git-post-receive +0 -40
  54. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac-post-commit.py +0 -285
  55. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac_billing.py +0 -173
  56. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/__init__.py +0 -0
  57. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/mail.py +0 -164
  58. data/lib/subtrac/trac-plugins/timingandestimationplugin/setup.py +0 -69
  59. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/__init__.py +0 -1
  60. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/api.py +0 -292
  61. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/blackmagic.py +0 -172
  62. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/dbhelper.py +0 -178
  63. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/billingplugin.css +0 -25
  64. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/field_disabler.js +0 -6
  65. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/formatDate.js +0 -356
  66. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_centerwindow.js +0 -100
  67. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_followscroll.js +0 -84
  68. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/wz_tooltip.js +0 -1149
  69. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/linkifyer.js +0 -119
  70. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/query.js +0 -73
  71. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/ticket.js +0 -165
  72. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/query_webui.py +0 -28
  73. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reportmanager.py +0 -221
  74. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports.py +0 -675
  75. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports_filter.py +0 -150
  76. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/statuses.py +0 -25
  77. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/tande_filters.py +0 -131
  78. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.cs +0 -84
  79. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.html +0 -104
  80. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_daemon.py +0 -194
  81. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_policy.py +0 -62
  82. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_webui.py +0 -28
  83. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/usermanual.py +0 -127
  84. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/webui.py +0 -129
  85. data/lib/subtrac/trac-plugins/worklogplugin/setup.py +0 -29
  86. data/lib/subtrac/trac-plugins/worklogplugin/worklog/__init__.py +0 -1
  87. data/lib/subtrac/trac-plugins/worklogplugin/worklog/api.py +0 -187
  88. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.css +0 -40
  89. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.js +0 -67
  90. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.mousewheel.pack.js +0 -12
  91. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.timeentry.pack.js +0 -7
  92. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/tracWorklog.js +0 -40
  93. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.css +0 -208
  94. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.js +0 -1439
  95. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.png +0 -0
  96. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.xcf +0 -0
  97. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/worklogplugin.css +0 -80
  98. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstart.png +0 -0
  99. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstop.png +0 -0
  100. data/lib/subtrac/trac-plugins/worklogplugin/worklog/manager.py +0 -336
  101. data/lib/subtrac/trac-plugins/worklogplugin/worklog/reports.py +0 -598
  102. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog.html +0 -45
  103. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_stop.html +0 -70
  104. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_user.html +0 -40
  105. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_webadminui.html +0 -59
  106. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_daemon.py +0 -33
  107. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_filter.py +0 -153
  108. data/lib/subtrac/trac-plugins/worklogplugin/worklog/timeline_hook.py +0 -96
  109. data/lib/subtrac/trac-plugins/worklogplugin/worklog/usermanual.py +0 -29
  110. data/lib/subtrac/trac-plugins/worklogplugin/worklog/util.py +0 -31
  111. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webadminui.py +0 -47
  112. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webui.py +0 -174
  113. data/lib/subtrac/trac-plugins/worklogplugin/worklog/xmlrpc.py +0 -73
@@ -1,1439 +0,0 @@
1
- /* jQuery UI Date Picker v3.4.3 (previously jQuery Calendar)
2
- Written by Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).
3
-
4
- Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datepicker)
5
- Dual licensed under the MIT (MIT-LICENSE.txt)
6
- and GPL (GPL-LICENSE.txt) licenses.
7
- Date: 09-03-2007 */
8
-
9
- ;(function($) { // hide the namespace
10
-
11
- /* Date picker manager.
12
- Use the singleton instance of this class, $.datepicker, to interact with the date picker.
13
- Settings for (groups of) date pickers are maintained in an instance object
14
- (DatepickerInstance), allowing multiple different settings on the same page. */
15
-
16
- function Datepicker() {
17
- this.debug = false; // Change this to true to start debugging
18
- this._nextId = 0; // Next ID for a date picker instance
19
- this._inst = []; // List of instances indexed by ID
20
- this._curInst = null; // The current instance in use
21
- this._disabledInputs = []; // List of date picker inputs that have been disabled
22
- this._datepickerShowing = false; // True if the popup picker is showing , false if not
23
- this._inDialog = false; // True if showing within a "dialog", false if not
24
- this.regional = []; // Available regional settings, indexed by language code
25
- this.regional[''] = { // Default regional settings
26
- clearText: 'Clear', // Display text for clear link
27
- clearStatus: 'Erase the current date', // Status text for clear link
28
- closeText: 'Close', // Display text for close link
29
- closeStatus: 'Close without change', // Status text for close link
30
- prevText: '<Prev', // Display text for previous month link
31
- prevStatus: 'Show the previous month', // Status text for previous month link
32
- nextText: 'Next>', // Display text for next month link
33
- nextStatus: 'Show the next month', // Status text for next month link
34
- currentText: 'Today', // Display text for current month link
35
- currentStatus: 'Show the current month', // Status text for current month link
36
- monthNames: ['January','February','March','April','May','June',
37
- 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
38
- monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
39
- monthStatus: 'Show a different month', // Status text for selecting a month
40
- yearStatus: 'Show a different year', // Status text for selecting a year
41
- weekHeader: 'Wk', // Header for the week of the year column
42
- weekStatus: 'Week of the year', // Status text for the week of the year column
43
- dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
44
- dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
45
- dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
46
- dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
47
- dateStatus: 'Select DD, M d', // Status text for the date selection
48
- dateFormat: 'mm/dd/yy', // See format options on parseDate
49
- firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
50
- initStatus: 'Select a date', // Initial Status text on opening
51
- isRTL: false // True if right-to-left language, false if left-to-right
52
- };
53
- this._defaults = { // Global defaults for all the date picker instances
54
- showOn: 'focus', // 'focus' for popup on focus,
55
- // 'button' for trigger button, or 'both' for either
56
- showAnim: 'show', // Name of jQuery animation for popup
57
- defaultDate: null, // Used when field is blank: actual date,
58
- // +/-number for offset from today, null for today
59
- appendText: '', // Display text following the input box, e.g. showing the format
60
- buttonText: '...', // Text for trigger button
61
- buttonImage: '', // URL for trigger button image
62
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
63
- closeAtTop: true, // True to have the clear/close at the top,
64
- // false to have them at the bottom
65
- mandatory: false, // True to hide the Clear link, false to include it
66
- hideIfNoPrevNext: false, // True to hide next/previous month links
67
- // if not applicable, false to just disable them
68
- changeMonth: true, // True if month can be selected directly, false if only prev/next
69
- changeYear: true, // True if year can be selected directly, false if only prev/next
70
- yearRange: '-10:+10', // Range of years to display in drop-down,
71
- // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
72
- changeFirstDay: true, // True to click on day name to change, false to remain as set
73
- showOtherMonths: false, // True to show dates in other months, false to leave blank
74
- showWeeks: false, // True to show week of the year, false to omit
75
- calculateWeek: this.iso8601Week, // How to calculate the week of the year,
76
- // takes a Date and returns the number of the week for it
77
- shortYearCutoff: '+10', // Short year values < this are in the current century,
78
- // > this are in the previous century,
79
- // string value starting with '+' for current year + value
80
- showStatus: false, // True to show status bar at bottom, false to not show it
81
- statusForDate: this.dateStatus, // Function to provide status text for a date -
82
- // takes date and instance as parameters, returns display text
83
- minDate: null, // The earliest selectable date, or null for no limit
84
- maxDate: null, // The latest selectable date, or null for no limit
85
- speed: 'normal', // Speed of display/closure
86
- beforeShowDay: null, // Function that takes a date and returns an array with
87
- // [0] = true if selectable, false if not,
88
- // [1] = custom CSS class name(s) or '', e.g. $.datepicker.noWeekends
89
- beforeShow: null, // Function that takes an input field and
90
- // returns a set of custom settings for the date picker
91
- onSelect: null, // Define a callback function when a date is selected
92
- onClose: null, // Define a callback function when the datepicker is closed
93
- numberOfMonths: 1, // Number of months to show at a time
94
- stepMonths: 1, // Number of months to step back/forward
95
- rangeSelect: false, // Allows for selecting a date range on one date picker
96
- rangeSeparator: ' - ' // Text between two dates in a range
97
- };
98
- $.extend(this._defaults, this.regional['']);
99
- this._datepickerDiv = $('<div id="datepicker_div">');
100
- }
101
-
102
- $.extend(Datepicker.prototype, {
103
- /* Class name added to elements to indicate already configured with a date picker. */
104
- markerClassName: 'hasDatepicker',
105
-
106
- /* Debug logging (if enabled). */
107
- log: function () {
108
- if (this.debug)
109
- console.log.apply('', arguments);
110
- },
111
-
112
- /* Register a new date picker instance - with custom settings. */
113
- _register: function(inst) {
114
- var id = this._nextId++;
115
- this._inst[id] = inst;
116
- return id;
117
- },
118
-
119
- /* Retrieve a particular date picker instance based on its ID. */
120
- _getInst: function(id) {
121
- return this._inst[id] || id;
122
- },
123
-
124
- /* Override the default settings for all instances of the date picker.
125
- @param settings object - the new settings to use as defaults (anonymous object)
126
- @return the manager object */
127
- setDefaults: function(settings) {
128
- extendRemove(this._defaults, settings || {});
129
- return this;
130
- },
131
-
132
- /* Attach the date picker to a jQuery selection.
133
- @param target element - the target input field or division or span
134
- @param settings object - the new settings to use for this date picker instance (anonymous) */
135
- _attachDatepicker: function(target, settings) {
136
- // check for settings on the control itself - in namespace 'date:'
137
- var inlineSettings = null;
138
- for (attrName in this._defaults) {
139
- var attrValue = target.getAttribute('date:' + attrName);
140
- if (attrValue) {
141
- inlineSettings = inlineSettings || {};
142
- try {
143
- inlineSettings[attrName] = eval(attrValue);
144
- } catch (err) {
145
- inlineSettings[attrName] = attrValue;
146
- }
147
- }
148
- }
149
- var nodeName = target.nodeName.toLowerCase();
150
- var instSettings = (inlineSettings ?
151
- $.extend(settings || {}, inlineSettings || {}) : settings);
152
- if (nodeName == 'input') {
153
- var inst = (inst && !inlineSettings ? inst :
154
- new DatepickerInstance(instSettings, false));
155
- this._connectDatepicker(target, inst);
156
- } else if (nodeName == 'div' || nodeName == 'span') {
157
- var inst = new DatepickerInstance(instSettings, true);
158
- this._inlineDatepicker(target, inst);
159
- }
160
- },
161
-
162
- /* Detach a datepicker from its control.
163
- @param target element - the target input field or division or span */
164
- _destroyDatepicker: function(target) {
165
- var nodeName = target.nodeName.toLowerCase();
166
- var calId = target._calId;
167
- target._calId = null;
168
- var $target = $(target);
169
- if (nodeName == 'input') {
170
- $target.siblings('.datepicker_append').replaceWith('').end()
171
- .siblings('.datepicker_trigger').replaceWith('').end()
172
- .removeClass(this.markerClassName)
173
- .unbind('focus', this._showDatepicker)
174
- .unbind('keydown', this._doKeyDown)
175
- .unbind('keypress', this._doKeyPress);
176
- var wrapper = $target.parents('.datepicker_wrap');
177
- if (wrapper)
178
- wrapper.replaceWith(wrapper.html());
179
- } else if (nodeName == 'div' || nodeName == 'span')
180
- $target.removeClass(this.markerClassName).empty();
181
- if ($('input[_calId=' + calId + ']').length == 0)
182
- // clean up if last for this ID
183
- this._inst[calId] = null;
184
- },
185
-
186
- /* Enable the date picker to a jQuery selection.
187
- @param target element - the target input field or division or span */
188
- _enableDatepicker: function(target) {
189
- target.disabled = false;
190
- $(target).siblings('button.datepicker_trigger').each(function() { this.disabled = false; }).end()
191
- .siblings('img.datepicker_trigger').css({opacity: '1.0', cursor: ''});
192
- this._disabledInputs = $.map(this._disabledInputs,
193
- function(value) { return (value == target ? null : value); }); // delete entry
194
- },
195
-
196
- /* Disable the date picker to a jQuery selection.
197
- @param target element - the target input field or division or span */
198
- _disableDatepicker: function(target) {
199
- target.disabled = true;
200
- $(target).siblings('button.datepicker_trigger').each(function() { this.disabled = true; }).end()
201
- .siblings('img.datepicker_trigger').css({opacity: '0.5', cursor: 'default'});
202
- this._disabledInputs = $.map($.datepicker._disabledInputs,
203
- function(value) { return (value == target ? null : value); }); // delete entry
204
- this._disabledInputs[$.datepicker._disabledInputs.length] = target;
205
- },
206
-
207
- /* Is the first field in a jQuery collection disabled as a datepicker?
208
- @param target element - the target input field or division or span
209
- @return boolean - true if disabled, false if enabled */
210
- _isDisabledDatepicker: function(target) {
211
- if (!target)
212
- return false;
213
- for (var i = 0; i < this._disabledInputs.length; i++) {
214
- if (this._disabledInputs[i] == target)
215
- return true;
216
- }
217
- return false;
218
- },
219
-
220
- /* Update the settings for a date picker attached to an input field or division.
221
- @param target element - the target input field or division or span
222
- @param name string - the name of the setting to change or
223
- object - the new settings to update
224
- @param value any - the new value for the setting (omit if above is an object) */
225
- _changeDatepicker: function(target, name, value) {
226
- var settings = name || {};
227
- if (typeof name == 'string') {
228
- settings = {};
229
- settings[name] = value;
230
- }
231
- if (inst = this._getInst(target._calId)) {
232
- extendRemove(inst._settings, settings);
233
- this._updateDatepicker(inst);
234
- }
235
- },
236
-
237
- /* Set the dates for a jQuery selection.
238
- @param target element - the target input field or division or span
239
- @param date Date - the new date
240
- @param endDate Date - the new end date for a range (optional) */
241
- _setDateDatepicker: function(target, date, endDate) {
242
- if (inst = this._getInst(target._calId)) {
243
- inst._setDate(date, endDate);
244
- this._updateDatepicker(inst);
245
- }
246
- },
247
-
248
- /* Get the date(s) for the first entry in a jQuery selection.
249
- @param target element - the target input field or division or span
250
- @return Date - the current date or
251
- Date[2] - the current dates for a range */
252
- _getDateDatepicker: function(target) {
253
- var inst = this._getInst(target._calId);
254
- return (inst ? inst._getDate() : null);
255
- },
256
-
257
- /* Handle keystrokes. */
258
- _doKeyDown: function(e) {
259
- var inst = $.datepicker._getInst(this._calId);
260
- if ($.datepicker._datepickerShowing)
261
- switch (e.keyCode) {
262
- case 9: $.datepicker._hideDatepicker(null, '');
263
- break; // hide on tab out
264
- case 13: $.datepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear,
265
- $('td.datepicker_daysCellOver', inst._datepickerDiv)[0]);
266
- return false; // don't submit the form
267
- break; // select the value on enter
268
- case 27: $.datepicker._hideDatepicker(null, inst._get('speed'));
269
- break; // hide on escape
270
- case 33: $.datepicker._adjustDate(inst,
271
- (e.ctrlKey ? -1 : -inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
272
- break; // previous month/year on page up/+ ctrl
273
- case 34: $.datepicker._adjustDate(inst,
274
- (e.ctrlKey ? +1 : +inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
275
- break; // next month/year on page down/+ ctrl
276
- case 35: if (e.ctrlKey) $.datepicker._clearDate(inst);
277
- break; // clear on ctrl+end
278
- case 36: if (e.ctrlKey) $.datepicker._gotoToday(inst);
279
- break; // current on ctrl+home
280
- case 37: if (e.ctrlKey) $.datepicker._adjustDate(inst, -1, 'D');
281
- break; // -1 day on ctrl+left
282
- case 38: if (e.ctrlKey) $.datepicker._adjustDate(inst, -7, 'D');
283
- break; // -1 week on ctrl+up
284
- case 39: if (e.ctrlKey) $.datepicker._adjustDate(inst, +1, 'D');
285
- break; // +1 day on ctrl+right
286
- case 40: if (e.ctrlKey) $.datepicker._adjustDate(inst, +7, 'D');
287
- break; // +1 week on ctrl+down
288
- }
289
- else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
290
- $.datepicker._showDatepicker(this);
291
- },
292
-
293
- /* Filter entered characters - based on date format. */
294
- _doKeyPress: function(e) {
295
- var inst = $.datepicker._getInst(this._calId);
296
- var chars = $.datepicker._possibleChars(inst._get('dateFormat'));
297
- var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
298
- return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
299
- },
300
-
301
- /* Attach the date picker to an input field. */
302
- _connectDatepicker: function(target, inst) {
303
- var input = $(target);
304
- if (input.is('.' + this.markerClassName))
305
- return;
306
- var appendText = inst._get('appendText');
307
- var isRTL = inst._get('isRTL');
308
- if (appendText) {
309
- if (isRTL)
310
- input.before('<span class="datepicker_append">' + appendText);
311
- else
312
- input.after('<span class="datepicker_append">' + appendText);
313
- }
314
- var showOn = inst._get('showOn');
315
- if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
316
- input.focus(this._showDatepicker);
317
- if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
318
- input.wrap('<span class="datepicker_wrap">');
319
- var buttonText = inst._get('buttonText');
320
- var buttonImage = inst._get('buttonImage');
321
- var trigger = $(inst._get('buttonImageOnly') ?
322
- $('<img>').addClass('datepicker_trigger').attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
323
- $('<button>').addClass('datepicker_trigger').attr({ type: 'button' }).html(buttonImage != '' ?
324
- $('<img>').attr({ src:buttonImage, alt:buttonText, title:buttonText }) : buttonText));
325
- if (isRTL)
326
- input.before(trigger);
327
- else
328
- input.after(trigger);
329
- trigger.click(function() {
330
- if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
331
- $.datepicker._hideDatepicker();
332
- else
333
- $.datepicker._showDatepicker(target);
334
- });
335
- }
336
- input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress)
337
- .bind("setData.datepicker", function(event, key, value) {
338
- inst._settings[key] = value;
339
- }).bind("getData.datepicker", function(event, key) {
340
- return inst._get(key);
341
- });
342
- input[0]._calId = inst._id;
343
- },
344
-
345
- /* Attach an inline date picker to a div. */
346
- _inlineDatepicker: function(target, inst) {
347
- var input = $(target);
348
- if (input.is('.' + this.markerClassName))
349
- return;
350
- input.addClass(this.markerClassName).append(inst._datepickerDiv)
351
- .bind("setData.datepicker", function(event, key, value){
352
- inst._settings[key] = value;
353
- }).bind("getData.datepicker", function(event, key){
354
- return inst._get(key);
355
- });
356
- input[0]._calId = inst._id;
357
- this._updateDatepicker(inst);
358
- },
359
-
360
- /* Tidy up after displaying the date picker. */
361
- _inlineShow: function(inst) {
362
- var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers
363
- inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0]).width());
364
- },
365
-
366
- /* Pop-up the date picker in a "dialog" box.
367
- @param input element - ignored
368
- @param dateText string - the initial date to display (in the current format)
369
- @param onSelect function - the function(dateText) to call when a date is selected
370
- @param settings object - update the dialog date picker instance's settings (anonymous object)
371
- @param pos int[2] - coordinates for the dialog's position within the screen or
372
- event - with x/y coordinates or
373
- leave empty for default (screen centre)
374
- @return the manager object */
375
- _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
376
- var inst = this._dialogInst; // internal instance
377
- if (!inst) {
378
- inst = this._dialogInst = new DatepickerInstance({}, false);
379
- this._dialogInput = $('<input type="text" size="1" style="position: absolute; top: -100px;"/>');
380
- this._dialogInput.keydown(this._doKeyDown);
381
- $('body').append(this._dialogInput);
382
- this._dialogInput[0]._calId = inst._id;
383
- }
384
- extendRemove(inst._settings, settings || {});
385
- this._dialogInput.val(dateText);
386
-
387
- this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
388
- if (!this._pos) {
389
- var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
390
- var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
391
- var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
392
- var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
393
- this._pos = // should use actual width/height below
394
- [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
395
- }
396
-
397
- // move input on screen for focus, but hidden behind dialog
398
- this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
399
- inst._settings.onSelect = onSelect;
400
- this._inDialog = true;
401
- this._datepickerDiv.addClass('datepicker_dialog');
402
- this._showDatepicker(this._dialogInput[0]);
403
- if ($.blockUI)
404
- $.blockUI(this._datepickerDiv);
405
- return this;
406
- },
407
-
408
- /* Pop-up the date picker for a given input field.
409
- @param input element - the input field attached to the date picker or
410
- event - if triggered by focus */
411
- _showDatepicker: function(input) {
412
- input = input.target || input;
413
- if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
414
- input = $('input', input.parentNode)[0];
415
- if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
416
- return;
417
- var inst = $.datepicker._getInst(input._calId);
418
- var beforeShow = inst._get('beforeShow');
419
- extendRemove(inst._settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
420
- $.datepicker._hideDatepicker(null, '');
421
- $.datepicker._lastInput = input;
422
- inst._setDateFromField(input);
423
- if ($.datepicker._inDialog) // hide cursor
424
- input.value = '';
425
- if (!$.datepicker._pos) { // position below input
426
- $.datepicker._pos = $.datepicker._findPos(input);
427
- $.datepicker._pos[1] += input.offsetHeight; // add the height
428
- }
429
- var isFixed = false;
430
- $(input).parents().each(function() {
431
- isFixed |= $(this).css('position') == 'fixed';
432
- });
433
- if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
434
- $.datepicker._pos[0] -= document.documentElement.scrollLeft;
435
- $.datepicker._pos[1] -= document.documentElement.scrollTop;
436
- }
437
- inst._datepickerDiv.css('position', ($.datepicker._inDialog && $.blockUI ?
438
- 'static' : (isFixed ? 'fixed' : 'absolute')))
439
- .css({ left: $.datepicker._pos[0] + 'px', top: $.datepicker._pos[1] + 'px' });
440
- $.datepicker._pos = null;
441
- inst._rangeStart = null;
442
- $.datepicker._updateDatepicker(inst);
443
- if (!inst._inline) {
444
- var speed = inst._get('speed');
445
- var postProcess = function() {
446
- $.datepicker._datepickerShowing = true;
447
- $.datepicker._afterShow(inst);
448
- };
449
- var showAnim = inst._get('showAnim') || 'show';
450
- inst._datepickerDiv[showAnim](speed, postProcess);
451
- if (speed == '')
452
- postProcess();
453
- if (inst._input[0].type != 'hidden')
454
- inst._input[0].focus();
455
- $.datepicker._curInst = inst;
456
- }
457
- },
458
-
459
- /* Generate the date picker content. */
460
- _updateDatepicker: function(inst) {
461
- inst._datepickerDiv.empty().append(inst._generateDatepicker());
462
- var numMonths = inst._getNumberOfMonths();
463
- if (numMonths[0] != 1 || numMonths[1] != 1)
464
- inst._datepickerDiv.addClass('datepicker_multi');
465
- else
466
- inst._datepickerDiv.removeClass('datepicker_multi');
467
-
468
- if (inst._get('isRTL'))
469
- inst._datepickerDiv.addClass('datepicker_rtl');
470
- else
471
- inst._datepickerDiv.removeClass('datepicker_rtl');
472
-
473
- if (inst._input && inst._input[0].type != 'hidden')
474
- inst._input[0].focus();
475
- },
476
-
477
- /* Tidy up after displaying the date picker. */
478
- _afterShow: function(inst) {
479
- var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers
480
- inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0])[0].offsetWidth);
481
- if ($.browser.msie && parseInt($.browser.version) < 7) { // fix IE < 7 select problems
482
- $('#datepicker_cover').css({width: inst._datepickerDiv.width() + 4,
483
- height: inst._datepickerDiv.height() + 4});
484
- }
485
- // re-position on screen if necessary
486
- var isFixed = inst._datepickerDiv.css('position') == 'fixed';
487
- var pos = inst._input ? $.datepicker._findPos(inst._input[0]) : null;
488
- var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
489
- var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
490
- var scrollX = (isFixed ? 0 : document.documentElement.scrollLeft || document.body.scrollLeft);
491
- var scrollY = (isFixed ? 0 : document.documentElement.scrollTop || document.body.scrollTop);
492
- // reposition date picker horizontally if outside the browser window
493
- if ((inst._datepickerDiv.offset().left + inst._datepickerDiv.width() -
494
- (isFixed && $.browser.msie ? document.documentElement.scrollLeft : 0)) >
495
- (browserWidth + scrollX)) {
496
- inst._datepickerDiv.css('left', Math.max(scrollX,
497
- pos[0] + (inst._input ? $(inst._input[0]).width() : null) - inst._datepickerDiv.width() -
498
- (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)) + 'px');
499
- }
500
- // reposition date picker vertically if outside the browser window
501
- if ((inst._datepickerDiv.offset().top + inst._datepickerDiv.height() -
502
- (isFixed && $.browser.msie ? document.documentElement.scrollTop : 0)) >
503
- (browserHeight + scrollY) ) {
504
- inst._datepickerDiv.css('top', Math.max(scrollY,
505
- pos[1] - (this._inDialog ? 0 : inst._datepickerDiv.height()) -
506
- (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + 'px');
507
- }
508
- },
509
-
510
- /* Find an object's position on the screen. */
511
- _findPos: function(obj) {
512
- while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
513
- obj = obj.nextSibling;
514
- }
515
- var position = $(obj).offset();
516
- return [position.left, position.top];
517
- },
518
-
519
- /* Hide the date picker from view.
520
- @param input element - the input field attached to the date picker
521
- @param speed string - the speed at which to close the date picker */
522
- _hideDatepicker: function(input, speed) {
523
- var inst = this._curInst;
524
- if (!inst)
525
- return;
526
- var rangeSelect = inst._get('rangeSelect');
527
- if (rangeSelect && this._stayOpen) {
528
- this._selectDate(inst, inst._formatDate(
529
- inst._currentDay, inst._currentMonth, inst._currentYear));
530
- }
531
- this._stayOpen = false;
532
- if (this._datepickerShowing) {
533
- speed = (speed != null ? speed : inst._get('speed'));
534
- var showAnim = inst._get('showAnim');
535
- inst._datepickerDiv[(showAnim == 'slideDown' ? 'slideUp' :
536
- (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))](speed, function() {
537
- $.datepicker._tidyDialog(inst);
538
- });
539
- if (speed == '')
540
- this._tidyDialog(inst);
541
- var onClose = inst._get('onClose');
542
- if (onClose) {
543
- onClose.apply((inst._input ? inst._input[0] : null),
544
- [inst._getDate(), inst]); // trigger custom callback
545
- }
546
- this._datepickerShowing = false;
547
- this._lastInput = null;
548
- inst._settings.prompt = null;
549
- if (this._inDialog) {
550
- this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
551
- if ($.blockUI) {
552
- $.unblockUI();
553
- $('body').append(this._datepickerDiv);
554
- }
555
- }
556
- this._inDialog = false;
557
- }
558
- this._curInst = null;
559
- },
560
-
561
- /* Tidy up after a dialog display. */
562
- _tidyDialog: function(inst) {
563
- inst._datepickerDiv.removeClass('datepicker_dialog').unbind('.datepicker');
564
- $('.datepicker_prompt', inst._datepickerDiv).remove();
565
- },
566
-
567
- /* Close date picker if clicked elsewhere. */
568
- _checkExternalClick: function(event) {
569
- if (!$.datepicker._curInst)
570
- return;
571
- var $target = $(event.target);
572
- if (($target.parents("#datepicker_div").length == 0) &&
573
- ($target.attr('class') != 'datepicker_trigger') &&
574
- $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) {
575
- $.datepicker._hideDatepicker(null, '');
576
- }
577
- },
578
-
579
- /* Adjust one of the date sub-fields. */
580
- _adjustDate: function(id, offset, period) {
581
- var inst = this._getInst(id);
582
- inst._adjustDate(offset, period);
583
- this._updateDatepicker(inst);
584
- },
585
-
586
- /* Action for current link. */
587
- _gotoToday: function(id) {
588
- var date = new Date();
589
- var inst = this._getInst(id);
590
- inst._selectedDay = date.getDate();
591
- inst._drawMonth = inst._selectedMonth = date.getMonth();
592
- inst._drawYear = inst._selectedYear = date.getFullYear();
593
- this._adjustDate(inst);
594
- },
595
-
596
- /* Action for selecting a new month/year. */
597
- _selectMonthYear: function(id, select, period) {
598
- var inst = this._getInst(id);
599
- inst._selectingMonthYear = false;
600
- inst[period == 'M' ? '_drawMonth' : '_drawYear'] =
601
- select.options[select.selectedIndex].value - 0;
602
- this._adjustDate(inst);
603
- },
604
-
605
- /* Restore input focus after not changing month/year. */
606
- _clickMonthYear: function(id) {
607
- var inst = this._getInst(id);
608
- if (inst._input && inst._selectingMonthYear && !$.browser.msie)
609
- inst._input[0].focus();
610
- inst._selectingMonthYear = !inst._selectingMonthYear;
611
- },
612
-
613
- /* Action for changing the first week day. */
614
- _changeFirstDay: function(id, day) {
615
- var inst = this._getInst(id);
616
- inst._settings.firstDay = day;
617
- this._updateDatepicker(inst);
618
- },
619
-
620
- /* Action for selecting a day. */
621
- _selectDay: function(id, month, year, td) {
622
- if ($(td).is('.datepicker_unselectable'))
623
- return;
624
- var inst = this._getInst(id);
625
- var rangeSelect = inst._get('rangeSelect');
626
- if (rangeSelect) {
627
- if (!this._stayOpen) {
628
- $('.datepicker td').removeClass('datepicker_currentDay');
629
- $(td).addClass('datepicker_currentDay');
630
- }
631
- this._stayOpen = !this._stayOpen;
632
- }
633
- inst._selectedDay = inst._currentDay = $('a', td).html();
634
- inst._selectedMonth = inst._currentMonth = month;
635
- inst._selectedYear = inst._currentYear = year;
636
- this._selectDate(id, inst._formatDate(
637
- inst._currentDay, inst._currentMonth, inst._currentYear));
638
- if (this._stayOpen) {
639
- inst._endDay = inst._endMonth = inst._endYear = null;
640
- inst._rangeStart = new Date(inst._currentYear, inst._currentMonth, inst._currentDay);
641
- this._updateDatepicker(inst);
642
- }
643
- else if (rangeSelect) {
644
- inst._endDay = inst._currentDay;
645
- inst._endMonth = inst._currentMonth;
646
- inst._endYear = inst._currentYear;
647
- inst._selectedDay = inst._currentDay = inst._rangeStart.getDate();
648
- inst._selectedMonth = inst._currentMonth = inst._rangeStart.getMonth();
649
- inst._selectedYear = inst._currentYear = inst._rangeStart.getFullYear();
650
- inst._rangeStart = null;
651
- if (inst._inline)
652
- this._updateDatepicker(inst);
653
- }
654
- },
655
-
656
- /* Erase the input field and hide the date picker. */
657
- _clearDate: function(id) {
658
- var inst = this._getInst(id);
659
- if (inst._get('mandatory'))
660
- return;
661
- this._stayOpen = false;
662
- inst._endDay = inst._endMonth = inst._endYear = inst._rangeStart = null;
663
- this._selectDate(inst, '');
664
- },
665
-
666
- /* Update the input field with the selected date. */
667
- _selectDate: function(id, dateStr) {
668
- var inst = this._getInst(id);
669
- dateStr = (dateStr != null ? dateStr : inst._formatDate());
670
- if (inst._rangeStart)
671
- dateStr = inst._formatDate(inst._rangeStart) + inst._get('rangeSeparator') + dateStr;
672
- if (inst._input)
673
- inst._input.val(dateStr);
674
- var onSelect = inst._get('onSelect');
675
- if (onSelect)
676
- onSelect.apply((inst._input ? inst._input[0] : null), [dateStr, inst]); // trigger custom callback
677
- else if (inst._input)
678
- inst._input.trigger('change'); // fire the change event
679
- if (inst._inline)
680
- this._updateDatepicker(inst);
681
- else if (!this._stayOpen) {
682
- this._hideDatepicker(null, inst._get('speed'));
683
- this._lastInput = inst._input[0];
684
- if (typeof(inst._input[0]) != 'object')
685
- inst._input[0].focus(); // restore focus
686
- this._lastInput = null;
687
- }
688
- },
689
-
690
- /* Set as beforeShowDay function to prevent selection of weekends.
691
- @param date Date - the date to customise
692
- @return [boolean, string] - is this date selectable?, what is its CSS class? */
693
- noWeekends: function(date) {
694
- var day = date.getDay();
695
- return [(day > 0 && day < 6), ''];
696
- },
697
-
698
- /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
699
- @param date Date - the date to get the week for
700
- @return number - the number of the week within the year that contains this date */
701
- iso8601Week: function(date) {
702
- var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60));
703
- var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
704
- var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
705
- firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
706
- if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
707
- checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
708
- return $.datepicker.iso8601Week(checkDate);
709
- } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
710
- firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
711
- if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
712
- checkDate.setDate(checkDate.getDate() + 3); // Generate for next year
713
- return $.datepicker.iso8601Week(checkDate);
714
- }
715
- }
716
- return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
717
- },
718
-
719
- /* Provide status text for a particular date.
720
- @param date the date to get the status for
721
- @param inst the current datepicker instance
722
- @return the status display text for this date */
723
- dateStatus: function(date, inst) {
724
- return $.datepicker.formatDate(inst._get('dateStatus'), date, inst._getFormatConfig());
725
- },
726
-
727
- /* Parse a string value into a date object.
728
- The format can be combinations of the following:
729
- d - day of month (no leading zero)
730
- dd - day of month (two digit)
731
- D - day name short
732
- DD - day name long
733
- m - month of year (no leading zero)
734
- mm - month of year (two digit)
735
- M - month name short
736
- MM - month name long
737
- y - year (two digit)
738
- yy - year (four digit)
739
- '...' - literal text
740
- '' - single quote
741
-
742
- @param format String - the expected format of the date
743
- @param value String - the date in the above format
744
- @param settings Object - attributes include:
745
- shortYearCutoff Number - the cutoff year for determining the century (optional)
746
- dayNamesShort String[7] - abbreviated names of the days from Sunday (optional)
747
- dayNames String[7] - names of the days from Sunday (optional)
748
- monthNamesShort String[12] - abbreviated names of the months (optional)
749
- monthNames String[12] - names of the months (optional)
750
- @return Date - the extracted date value or null if value is blank */
751
- parseDate: function (format, value, settings) {
752
- if (format == null || value == null)
753
- throw 'Invalid arguments';
754
- value = (typeof value == 'object' ? value.toString() : value + '');
755
- if (value == '')
756
- return null;
757
- var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
758
- var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
759
- var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
760
- var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
761
- var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
762
- var year = -1;
763
- var month = -1;
764
- var day = -1;
765
- var literal = false;
766
- // Check whether a format character is doubled
767
- var lookAhead = function(match) {
768
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
769
- if (matches)
770
- iFormat++;
771
- return matches;
772
- };
773
- // Extract a number from the string value
774
- var getNumber = function(match) {
775
- lookAhead(match);
776
- var size = (match == 'y' ? 4 : 2);
777
- var num = 0;
778
- while (size > 0 && iValue < value.length &&
779
- value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
780
- num = num * 10 + (value.charAt(iValue++) - 0);
781
- size--;
782
- }
783
- if (size == (match == 'y' ? 4 : 2))
784
- throw 'Missing number at position ' + iValue;
785
- return num;
786
- };
787
- // Extract a name from the string value and convert to an index
788
- var getName = function(match, shortNames, longNames) {
789
- var names = (lookAhead(match) ? longNames : shortNames);
790
- var size = 0;
791
- for (var j = 0; j < names.length; j++)
792
- size = Math.max(size, names[j].length);
793
- var name = '';
794
- var iInit = iValue;
795
- while (size > 0 && iValue < value.length) {
796
- name += value.charAt(iValue++);
797
- for (var i = 0; i < names.length; i++)
798
- if (name == names[i])
799
- return i + 1;
800
- size--;
801
- }
802
- throw 'Unknown name at position ' + iInit;
803
- };
804
- // Confirm that a literal character matches the string value
805
- var checkLiteral = function() {
806
- if (value.charAt(iValue) != format.charAt(iFormat))
807
- throw 'Unexpected literal at position ' + iValue;
808
- iValue++;
809
- };
810
- var iValue = 0;
811
- for (var iFormat = 0; iFormat < format.length; iFormat++) {
812
- if (literal)
813
- if (format.charAt(iFormat) == "'" && !lookAhead("'"))
814
- literal = false;
815
- else
816
- checkLiteral();
817
- else
818
- switch (format.charAt(iFormat)) {
819
- case 'd':
820
- day = getNumber('d');
821
- break;
822
- case 'D':
823
- getName('D', dayNamesShort, dayNames);
824
- break;
825
- case 'm':
826
- month = getNumber('m');
827
- break;
828
- case 'M':
829
- month = getName('M', monthNamesShort, monthNames);
830
- break;
831
- case 'y':
832
- year = getNumber('y');
833
- break;
834
- case "'":
835
- if (lookAhead("'"))
836
- checkLiteral();
837
- else
838
- literal = true;
839
- break;
840
- default:
841
- checkLiteral();
842
- }
843
- }
844
- if (year < 100) {
845
- year += new Date().getFullYear() - new Date().getFullYear() % 100 +
846
- (year <= shortYearCutoff ? 0 : -100);
847
- }
848
- var date = new Date(year, month - 1, day);
849
- if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) {
850
- throw 'Invalid date'; // E.g. 31/02/*
851
- }
852
- return date;
853
- },
854
-
855
- /* Format a date object into a string value.
856
- The format can be combinations of the following:
857
- d - day of month (no leading zero)
858
- dd - day of month (two digit)
859
- D - day name short
860
- DD - day name long
861
- m - month of year (no leading zero)
862
- mm - month of year (two digit)
863
- M - month name short
864
- MM - month name long
865
- y - year (two digit)
866
- yy - year (four digit)
867
- '...' - literal text
868
- '' - single quote
869
-
870
- @param format String - the desired format of the date
871
- @param date Date - the date value to format
872
- @param settings Object - attributes include:
873
- dayNamesShort String[7] - abbreviated names of the days from Sunday (optional)
874
- dayNames String[7] - names of the days from Sunday (optional)
875
- monthNamesShort String[12] - abbreviated names of the months (optional)
876
- monthNames String[12] - names of the months (optional)
877
- @return String - the date in the above format */
878
- formatDate: function (format, date, settings) {
879
- if (!date)
880
- return '';
881
- var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
882
- var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
883
- var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
884
- var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
885
- // Check whether a format character is doubled
886
- var lookAhead = function(match) {
887
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
888
- if (matches)
889
- iFormat++;
890
- return matches;
891
- };
892
- // Format a number, with leading zero if necessary
893
- var formatNumber = function(match, value) {
894
- return (lookAhead(match) && value < 10 ? '0' : '') + value;
895
- };
896
- // Format a name, short or long as requested
897
- var formatName = function(match, value, shortNames, longNames) {
898
- return (lookAhead(match) ? longNames[value] : shortNames[value]);
899
- };
900
- var output = '';
901
- var literal = false;
902
- if (date) {
903
- for (var iFormat = 0; iFormat < format.length; iFormat++) {
904
- if (literal)
905
- if (format.charAt(iFormat) == "'" && !lookAhead("'"))
906
- literal = false;
907
- else
908
- output += format.charAt(iFormat);
909
- else
910
- switch (format.charAt(iFormat)) {
911
- case 'd':
912
- output += formatNumber('d', date.getDate());
913
- break;
914
- case 'D':
915
- output += formatName('D', date.getDay(), dayNamesShort, dayNames);
916
- break;
917
- case 'm':
918
- output += formatNumber('m', date.getMonth() + 1);
919
- break;
920
- case 'M':
921
- output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
922
- break;
923
- case 'y':
924
- output += (lookAhead('y') ? date.getFullYear() :
925
- (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
926
- break;
927
- case "'":
928
- if (lookAhead("'"))
929
- output += "'";
930
- else
931
- literal = true;
932
- break;
933
- default:
934
- output += format.charAt(iFormat);
935
- }
936
- }
937
- }
938
- return output;
939
- },
940
-
941
- /* Extract all possible characters from the date format. */
942
- _possibleChars: function (format) {
943
- var chars = '';
944
- var literal = false;
945
- for (var iFormat = 0; iFormat < format.length; iFormat++)
946
- if (literal)
947
- if (format.charAt(iFormat) == "'" && !lookAhead("'"))
948
- literal = false;
949
- else
950
- chars += format.charAt(iFormat);
951
- else
952
- switch (format.charAt(iFormat)) {
953
- case 'd' || 'm' || 'y':
954
- chars += '0123456789';
955
- break;
956
- case 'D' || 'M':
957
- return null; // Accept anything
958
- case "'":
959
- if (lookAhead("'"))
960
- chars += "'";
961
- else
962
- literal = true;
963
- break;
964
- default:
965
- chars += format.charAt(iFormat);
966
- }
967
- return chars;
968
- }
969
- });
970
-
971
- /* Individualised settings for date picker functionality applied to one or more related inputs.
972
- Instances are managed and manipulated through the Datepicker manager. */
973
- function DatepickerInstance(settings, inline) {
974
- this._id = $.datepicker._register(this);
975
- this._selectedDay = 0; // Current date for selection
976
- this._selectedMonth = 0; // 0-11
977
- this._selectedYear = 0; // 4-digit year
978
- this._drawMonth = 0; // Current month at start of datepicker
979
- this._drawYear = 0;
980
- this._input = null; // The attached input field
981
- this._inline = inline; // True if showing inline, false if used in a popup
982
- this._datepickerDiv = (!inline ? $.datepicker._datepickerDiv :
983
- $('<div id="datepicker_div_' + this._id + '" class="datepicker_inline">'));
984
- // customise the date picker object - uses manager defaults if not overridden
985
- this._settings = extendRemove(settings || {}); // clone
986
- if (inline)
987
- this._setDate(this._getDefaultDate());
988
- }
989
-
990
- $.extend(DatepickerInstance.prototype, {
991
- /* Get a setting value, defaulting if necessary. */
992
- _get: function(name) {
993
- return this._settings[name] || $.datepicker._defaults[name];
994
- },
995
-
996
- /* Parse existing date and initialise date picker. */
997
- _setDateFromField: function(input) {
998
- this._input = $(input);
999
- var dateFormat = this._get('dateFormat');
1000
- var dates = this._input ? this._input.val().split(this._get('rangeSeparator')) : null;
1001
- this._endDay = this._endMonth = this._endYear = null;
1002
- var date = defaultDate = this._getDefaultDate();
1003
- if (dates.length > 0) {
1004
- var settings = this._getFormatConfig();
1005
- if (dates.length > 1) {
1006
- date = $.datepicker.parseDate(dateFormat, dates[1], settings) || defaultDate;
1007
- this._endDay = date.getDate();
1008
- this._endMonth = date.getMonth();
1009
- this._endYear = date.getFullYear();
1010
- }
1011
- try {
1012
- date = $.datepicker.parseDate(dateFormat, dates[0], settings) || defaultDate;
1013
- } catch (e) {
1014
- $.datepicker.log(e);
1015
- date = defaultDate;
1016
- }
1017
- }
1018
- this._selectedDay = date.getDate();
1019
- this._drawMonth = this._selectedMonth = date.getMonth();
1020
- this._drawYear = this._selectedYear = date.getFullYear();
1021
- this._currentDay = (dates[0] ? date.getDate() : 0);
1022
- this._currentMonth = (dates[0] ? date.getMonth() : 0);
1023
- this._currentYear = (dates[0] ? date.getFullYear() : 0);
1024
- this._adjustDate();
1025
- },
1026
-
1027
- /* Retrieve the default date shown on opening. */
1028
- _getDefaultDate: function() {
1029
- var date = this._determineDate('defaultDate', new Date());
1030
- var minDate = this._getMinMaxDate('min', true);
1031
- var maxDate = this._getMinMaxDate('max');
1032
- date = (minDate && date < minDate ? minDate : date);
1033
- date = (maxDate && date > maxDate ? maxDate : date);
1034
- return date;
1035
- },
1036
-
1037
- /* A date may be specified as an exact value or a relative one. */
1038
- _determineDate: function(name, defaultDate) {
1039
- var offsetNumeric = function(offset) {
1040
- var date = new Date();
1041
- date.setDate(date.getDate() + offset);
1042
- return date;
1043
- };
1044
- var offsetString = function(offset, getDaysInMonth) {
1045
- var date = new Date();
1046
- var matches = /^([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?$/.exec(offset);
1047
- if (matches) {
1048
- var year = date.getFullYear();
1049
- var month = date.getMonth();
1050
- var day = date.getDate();
1051
- switch (matches[2] || 'd') {
1052
- case 'd' : case 'D' :
1053
- day += (matches[1] - 0); break;
1054
- case 'w' : case 'W' :
1055
- day += (matches[1] * 7); break;
1056
- case 'm' : case 'M' :
1057
- month += (matches[1] - 0);
1058
- day = Math.min(day, getDaysInMonth(year, month));
1059
- break;
1060
- case 'y': case 'Y' :
1061
- year += (matches[1] - 0);
1062
- day = Math.min(day, getDaysInMonth(year, month));
1063
- break;
1064
- }
1065
- date = new Date(year, month, day);
1066
- }
1067
- return date;
1068
- };
1069
- var date = this._get(name);
1070
- return (date == null ? defaultDate :
1071
- (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
1072
- (typeof date == 'number' ? offsetNumeric(date) : date)));
1073
- },
1074
-
1075
- /* Set the date(s) directly. */
1076
- _setDate: function(date, endDate) {
1077
- this._selectedDay = this._currentDay = date.getDate();
1078
- this._drawMonth = this._selectedMonth = this._currentMonth = date.getMonth();
1079
- this._drawYear = this._selectedYear = this._currentYear = date.getFullYear();
1080
- if (this._get('rangeSelect')) {
1081
- if (endDate) {
1082
- this._endDay = endDate.getDate();
1083
- this._endMonth = endDate.getMonth();
1084
- this._endYear = endDate.getFullYear();
1085
- } else {
1086
- this._endDay = this._currentDay;
1087
- this._endMonth = this._currentMonth;
1088
- this._endYear = this._currentYear;
1089
- }
1090
- }
1091
- this._adjustDate();
1092
- },
1093
-
1094
- /* Retrieve the date(s) directly. */
1095
- _getDate: function() {
1096
- var startDate = (!this._currentYear || (this._input && this._input.val() == '') ? null :
1097
- new Date(this._currentYear, this._currentMonth, this._currentDay));
1098
- if (this._get('rangeSelect')) {
1099
- return [startDate, (!this._endYear ? null :
1100
- new Date(this._endYear, this._endMonth, this._endDay))];
1101
- } else
1102
- return startDate;
1103
- },
1104
-
1105
- /* Generate the HTML for the current state of the date picker. */
1106
- _generateDatepicker: function() {
1107
- var today = new Date();
1108
- today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
1109
- var showStatus = this._get('showStatus');
1110
- var isRTL = this._get('isRTL');
1111
- // build the date picker HTML
1112
- var clear = (this._get('mandatory') ? '' :
1113
- '<div class="datepicker_clear"><a onclick="jQuery.datepicker._clearDate(' + this._id + ');"' +
1114
- (showStatus ? this._addStatus(this._get('clearStatus') || '&#xa0;') : '') + '>' +
1115
- this._get('clearText') + '</a></div>');
1116
- var controls = '<div class="datepicker_control">' + (isRTL ? '' : clear) +
1117
- '<div class="datepicker_close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
1118
- (showStatus ? this._addStatus(this._get('closeStatus') || '&#xa0;') : '') + '>' +
1119
- this._get('closeText') + '</a></div>' + (isRTL ? clear : '') + '</div>';
1120
- var prompt = this._get('prompt');
1121
- var closeAtTop = this._get('closeAtTop');
1122
- var hideIfNoPrevNext = this._get('hideIfNoPrevNext');
1123
- var numMonths = this._getNumberOfMonths();
1124
- var stepMonths = this._get('stepMonths');
1125
- var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1126
- var minDate = this._getMinMaxDate('min', true);
1127
- var maxDate = this._getMinMaxDate('max');
1128
- var drawMonth = this._drawMonth;
1129
- var drawYear = this._drawYear;
1130
- if (maxDate) {
1131
- var maxDraw = new Date(maxDate.getFullYear(),
1132
- maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
1133
- maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1134
- while (new Date(drawYear, drawMonth, 1) > maxDraw) {
1135
- drawMonth--;
1136
- if (drawMonth < 0) {
1137
- drawMonth = 11;
1138
- drawYear--;
1139
- }
1140
- }
1141
- }
1142
- // controls and links
1143
- var prev = '<div class="datepicker_prev">' + (this._canAdjustMonth(-1, drawYear, drawMonth) ?
1144
- '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ', -' + stepMonths + ', \'M\');"' +
1145
- (showStatus ? this._addStatus(this._get('prevStatus') || '&#xa0;') : '') + '>' +
1146
- this._get('prevText') + '</a>' :
1147
- (hideIfNoPrevNext ? '' : '<label>' + this._get('prevText') + '</label>')) + '</div>';
1148
- var next = '<div class="datepicker_next">' + (this._canAdjustMonth(+1, drawYear, drawMonth) ?
1149
- '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ', +' + stepMonths + ', \'M\');"' +
1150
- (showStatus ? this._addStatus(this._get('nextStatus') || '&#xa0;') : '') + '>' +
1151
- this._get('nextText') + '</a>' :
1152
- (hideIfNoPrevNext ? '>' : '<label>' + this._get('nextText') + '</label>')) + '</div>';
1153
- var html = (prompt ? '<div class="datepicker_prompt">' + prompt + '</div>' : '') +
1154
- (closeAtTop && !this._inline ? controls : '') +
1155
- '<div class="datepicker_links">' + (isRTL ? next : prev) +
1156
- (this._isInRange(today) ? '<div class="datepicker_current">' +
1157
- '<a onclick="jQuery.datepicker._gotoToday(' + this._id + ');"' +
1158
- (showStatus ? this._addStatus(this._get('currentStatus') || '&#xa0;') : '') + '>' +
1159
- this._get('currentText') + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
1160
- var showWeeks = this._get('showWeeks');
1161
- for (var row = 0; row < numMonths[0]; row++)
1162
- for (var col = 0; col < numMonths[1]; col++) {
1163
- var selectedDate = new Date(drawYear, drawMonth, this._selectedDay);
1164
- html += '<div class="datepicker_oneMonth' + (col == 0 ? ' datepicker_newRow' : '') + '">' +
1165
- this._generateMonthYearHeader(drawMonth, drawYear, minDate, maxDate,
1166
- selectedDate, row > 0 || col > 0) + // draw month headers
1167
- '<table class="datepicker" cellpadding="0" cellspacing="0"><thead>' +
1168
- '<tr class="datepicker_titleRow">' +
1169
- (showWeeks ? '<td>' + this._get('weekHeader') + '</td>' : '');
1170
- var firstDay = this._get('firstDay');
1171
- var changeFirstDay = this._get('changeFirstDay');
1172
- var dayNames = this._get('dayNames');
1173
- var dayNamesShort = this._get('dayNamesShort');
1174
- var dayNamesMin = this._get('dayNamesMin');
1175
- for (var dow = 0; dow < 7; dow++) { // days of the week
1176
- var day = (dow + firstDay) % 7;
1177
- var status = this._get('dayStatus') || '&#xa0;';
1178
- status = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
1179
- status.replace(/D/, dayNamesShort[day]));
1180
- html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="datepicker_weekEndCell"' : '') + '>' +
1181
- (!changeFirstDay ? '<span' :
1182
- '<a onclick="jQuery.datepicker._changeFirstDay(' + this._id + ', ' + day + ');"') +
1183
- (showStatus ? this._addStatus(status) : '') + ' title="' + dayNames[day] + '">' +
1184
- dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
1185
- }
1186
- html += '</tr></thead><tbody>';
1187
- var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1188
- if (drawYear == this._selectedYear && drawMonth == this._selectedMonth) {
1189
- this._selectedDay = Math.min(this._selectedDay, daysInMonth);
1190
- }
1191
- var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1192
- var currentDate = (!this._currentDay ? new Date(9999, 9, 9) :
1193
- new Date(this._currentYear, this._currentMonth, this._currentDay));
1194
- var endDate = this._endDay ? new Date(this._endYear, this._endMonth, this._endDay) : currentDate;
1195
- var printDate = new Date(drawYear, drawMonth, 1 - leadDays);
1196
- var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
1197
- var beforeShowDay = this._get('beforeShowDay');
1198
- var showOtherMonths = this._get('showOtherMonths');
1199
- var calculateWeek = this._get('calculateWeek') || $.datepicker.iso8601Week;
1200
- var dateStatus = this._get('statusForDate') || $.datepicker.dateStatus;
1201
- for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1202
- html += '<tr class="datepicker_daysRow">' +
1203
- (showWeeks ? '<td class="datepicker_weekCol">' + calculateWeek(printDate) + '</td>' : '');
1204
- for (var dow = 0; dow < 7; dow++) { // create date picker days
1205
- var daySettings = (beforeShowDay ?
1206
- beforeShowDay.apply((this._input ? this._input[0] : null), [printDate]) : [true, '']);
1207
- var otherMonth = (printDate.getMonth() != drawMonth);
1208
- var unselectable = otherMonth || !daySettings[0] ||
1209
- (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1210
- html += '<td class="datepicker_daysCell' +
1211
- ((dow + firstDay + 6) % 7 >= 5 ? ' datepicker_weekEndCell' : '') + // highlight weekends
1212
- (otherMonth ? ' datepicker_otherMonth' : '') + // highlight days from other months
1213
- (printDate.getTime() == selectedDate.getTime() && drawMonth == this._selectedMonth ?
1214
- ' datepicker_daysCellOver' : '') + // highlight selected day
1215
- (unselectable ? ' datepicker_unselectable' : '') + // highlight unselectable days
1216
- (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1217
- (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1218
- ' datepicker_currentDay' : '') + // highlight selected day
1219
- (printDate.getTime() == today.getTime() ? ' datepicker_today' : '')) + '"' + // highlight today (if different)
1220
- (unselectable ? '' : ' onmouseover="jQuery(this).addClass(\'datepicker_daysCellOver\');' +
1221
- (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#datepicker_status_' +
1222
- this._id + '\').html(\'' + (dateStatus.apply((this._input ? this._input[0] : null),
1223
- [printDate, this]) || '&#xa0;') +'\');') + '"' +
1224
- ' onmouseout="jQuery(this).removeClass(\'datepicker_daysCellOver\');' +
1225
- (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#datepicker_status_' +
1226
- this._id + '\').html(\'&#xa0;\');') + '" onclick="jQuery.datepicker._selectDay(' +
1227
- this._id + ',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
1228
- (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
1229
- (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
1230
- printDate.setDate(printDate.getDate() + 1);
1231
- }
1232
- html += '</tr>';
1233
- }
1234
- drawMonth++;
1235
- if (drawMonth > 11) {
1236
- drawMonth = 0;
1237
- drawYear++;
1238
- }
1239
- html += '</tbody></table></div>';
1240
- }
1241
- html += (showStatus ? '<div id="datepicker_status_' + this._id +
1242
- '" class="datepicker_status">' + (this._get('initStatus') || '&#xa0;') + '</div>' : '') +
1243
- (!closeAtTop && !this._inline ? controls : '') +
1244
- '<div style="clear: both;"></div>' +
1245
- ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ?
1246
- '<iframe src="javascript:false;" class="datepicker_cover"></iframe>' : '');
1247
- return html;
1248
- },
1249
-
1250
- /* Generate the month and year header. */
1251
- _generateMonthYearHeader: function(drawMonth, drawYear, minDate, maxDate, selectedDate, secondary) {
1252
- minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
1253
- var showStatus = this._get('showStatus');
1254
- var html = '<div class="datepicker_header">';
1255
- // month selection
1256
- var monthNames = this._get('monthNames');
1257
- if (secondary || !this._get('changeMonth'))
1258
- html += monthNames[drawMonth] + '&#xa0;';
1259
-
1260
- else {
1261
- var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1262
- var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1263
- html += '<select class="datepicker_newMonth" ' +
1264
- 'onchange="jQuery.datepicker._selectMonthYear(' + this._id + ', this, \'M\');" ' +
1265
- 'onclick="jQuery.datepicker._clickMonthYear(' + this._id + ');"' +
1266
- (showStatus ? this._addStatus(this._get('monthStatus') || '&#xa0;') : '') + '>';
1267
- for (var month = 0; month < 12; month++) {
1268
- if ((!inMinYear || month >= minDate.getMonth()) &&
1269
- (!inMaxYear || month <= maxDate.getMonth())) {
1270
- html += '<option value="' + month + '"' +
1271
- (month == drawMonth ? ' selected="selected"' : '') +
1272
- '>' + monthNames[month] + '</option>';
1273
- }
1274
- }
1275
- html += '</select>';
1276
- }
1277
- // year selection
1278
- if (secondary || !this._get('changeYear'))
1279
- html += drawYear;
1280
- else {
1281
- // determine range of years to display
1282
- var years = this._get('yearRange').split(':');
1283
- var year = 0;
1284
- var endYear = 0;
1285
- if (years.length != 2) {
1286
- year = drawYear - 10;
1287
- endYear = drawYear + 10;
1288
- } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
1289
- year = drawYear + parseInt(years[0], 10);
1290
- endYear = drawYear + parseInt(years[1], 10);
1291
- } else {
1292
- year = parseInt(years[0], 10);
1293
- endYear = parseInt(years[1], 10);
1294
- }
1295
- year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1296
- endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1297
- html += '<select class="datepicker_newYear" ' +
1298
- 'onchange="jQuery.datepicker._selectMonthYear(' + this._id + ', this, \'Y\');" ' +
1299
- 'onclick="jQuery.datepicker._clickMonthYear(' + this._id + ');"' +
1300
- (showStatus ? this._addStatus(this._get('yearStatus') || '&#xa0;') : '') + '>';
1301
- for (; year <= endYear; year++) {
1302
- html += '<option value="' + year + '"' +
1303
- (year == drawYear ? ' selected="selected"' : '') +
1304
- '>' + year + '</option>';
1305
- }
1306
- html += '</select>';
1307
- }
1308
- html += '</div>'; // Close datepicker_header
1309
- return html;
1310
- },
1311
-
1312
- /* Provide code to set and clear the status panel. */
1313
- _addStatus: function(text) {
1314
- return ' onmouseover="jQuery(\'#datepicker_status_' + this._id + '\').html(\'' + text + '\');" ' +
1315
- 'onmouseout="jQuery(\'#datepicker_status_' + this._id + '\').html(\'&#xa0;\');"';
1316
- },
1317
-
1318
- /* Adjust one of the date sub-fields. */
1319
- _adjustDate: function(offset, period) {
1320
- var year = this._drawYear + (period == 'Y' ? offset : 0);
1321
- var month = this._drawMonth + (period == 'M' ? offset : 0);
1322
- var day = Math.min(this._selectedDay, this._getDaysInMonth(year, month)) +
1323
- (period == 'D' ? offset : 0);
1324
- var date = new Date(year, month, day);
1325
- // ensure it is within the bounds set
1326
- var minDate = this._getMinMaxDate('min', true);
1327
- var maxDate = this._getMinMaxDate('max');
1328
- date = (minDate && date < minDate ? minDate : date);
1329
- date = (maxDate && date > maxDate ? maxDate : date);
1330
- this._selectedDay = date.getDate();
1331
- this._drawMonth = this._selectedMonth = date.getMonth();
1332
- this._drawYear = this._selectedYear = date.getFullYear();
1333
- },
1334
-
1335
- /* Determine the number of months to show. */
1336
- _getNumberOfMonths: function() {
1337
- var numMonths = this._get('numberOfMonths');
1338
- return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1339
- },
1340
-
1341
- /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
1342
- _getMinMaxDate: function(minMax, checkRange) {
1343
- var date = this._determineDate(minMax + 'Date', null);
1344
- if (date) {
1345
- date.setHours(0);
1346
- date.setMinutes(0);
1347
- date.setSeconds(0);
1348
- date.setMilliseconds(0);
1349
- }
1350
- return date || (checkRange ? this._rangeStart : null);
1351
- },
1352
-
1353
- /* Find the number of days in a given month. */
1354
- _getDaysInMonth: function(year, month) {
1355
- return 32 - new Date(year, month, 32).getDate();
1356
- },
1357
-
1358
- /* Find the day of the week of the first of a month. */
1359
- _getFirstDayOfMonth: function(year, month) {
1360
- return new Date(year, month, 1).getDay();
1361
- },
1362
-
1363
- /* Determines if we should allow a "next/prev" month display change. */
1364
- _canAdjustMonth: function(offset, curYear, curMonth) {
1365
- var numMonths = this._getNumberOfMonths();
1366
- var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
1367
- if (offset < 0)
1368
- date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1369
- return this._isInRange(date);
1370
- },
1371
-
1372
- /* Is the given date in the accepted range? */
1373
- _isInRange: function(date) {
1374
- // during range selection, use minimum of selected date and range start
1375
- var newMinDate = (!this._rangeStart ? null :
1376
- new Date(this._selectedYear, this._selectedMonth, this._selectedDay));
1377
- newMinDate = (newMinDate && this._rangeStart < newMinDate ? this._rangeStart : newMinDate);
1378
- var minDate = newMinDate || this._getMinMaxDate('min');
1379
- var maxDate = this._getMinMaxDate('max');
1380
- return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
1381
- },
1382
-
1383
- /* Provide the configuration settings for formatting/parsing. */
1384
- _getFormatConfig: function() {
1385
- var shortYearCutoff = this._get('shortYearCutoff');
1386
- shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1387
- new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1388
- return {shortYearCutoff: shortYearCutoff,
1389
- dayNamesShort: this._get('dayNamesShort'), dayNames: this._get('dayNames'),
1390
- monthNamesShort: this._get('monthNamesShort'), monthNames: this._get('monthNames')};
1391
- },
1392
-
1393
- /* Format the given date for display. */
1394
- _formatDate: function(day, month, year) {
1395
- if (!day) {
1396
- this._currentDay = this._selectedDay;
1397
- this._currentMonth = this._selectedMonth;
1398
- this._currentYear = this._selectedYear;
1399
- }
1400
- var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
1401
- new Date(this._currentYear, this._currentMonth, this._currentDay));
1402
- return $.datepicker.formatDate(this._get('dateFormat'), date, this._getFormatConfig());
1403
- }
1404
- });
1405
-
1406
- /* jQuery extend now ignores nulls! */
1407
- function extendRemove(target, props) {
1408
- $.extend(target, props);
1409
- for (var name in props)
1410
- if (props[name] == null)
1411
- target[name] = null;
1412
- return target;
1413
- };
1414
-
1415
- /* Invoke the datepicker functionality.
1416
- @param options String - a command, optionally followed by additional parameters or
1417
- Object - settings for attaching new datepicker functionality
1418
- @return jQuery object */
1419
- $.fn.datepicker = function(options){
1420
- var otherArgs = Array.prototype.slice.call(arguments, 1);
1421
- if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate')) {
1422
- return $.datepicker['_' + options + 'Datepicker'].apply($.datepicker, [this[0]].concat(otherArgs));
1423
- }
1424
- return this.each(function() {
1425
- typeof options == 'string' ?
1426
- $.datepicker['_' + options + 'Datepicker'].apply($.datepicker, [this].concat(otherArgs)) :
1427
- $.datepicker._attachDatepicker(this, options);
1428
- });
1429
- };
1430
-
1431
- /* Initialise the date picker. */
1432
- $(document).ready(function() {
1433
- $(document.body).append($.datepicker._datepickerDiv)
1434
- .mousedown($.datepicker._checkExternalClick);
1435
- });
1436
-
1437
- $.datepicker = new Datepicker(); // singleton instance
1438
-
1439
- })(jQuery);