zebra-datepicker-rails 0.0.2 → 1.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/zebra-datepicker-rails/version.rb +1 -1
- data/vendor/assets/javascripts/zebra-datepicker/zebra_datepicker.js +1 -2878
- data/vendor/assets/javascripts/zebra-datepicker/zebra_datepicker.src.js +2900 -0
- data/vendor/assets/stylesheets/zebra-datepicker/bootstrap.css +91 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59788182ff6bd589f820e7a50c0332d8bb8bc0b3
|
4
|
+
data.tar.gz: 9a66e3fcfceac5c82301885d543d90839b0c990e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a78d8d34d3b3fab0536ae8fb1b0f008cea68925678bc4705c9dabd3b5b3a5a4db29e2bc21564607f2f99d7226e587278d9f707ca048751857f32b17b008b2f6
|
7
|
+
data.tar.gz: 5f86c45d3fdc51d1556ca6d95e04cab81800b4f92ccbc46761797938396f32853422e73a2f39f88a2b8082bf97eb414624de7e6da97c8b9a9b6ac5a05eebe922
|
@@ -1,2878 +1 @@
|
|
1
|
-
/**
|
2
|
-
* Zebra_DatePicker
|
3
|
-
*
|
4
|
-
* Zebra_DatePicker is a small, compact and highly configurable date picker plugin for jQuery
|
5
|
-
*
|
6
|
-
* Visit {@link http://stefangabos.ro/jquery/zebra-datepicker/} for more information.
|
7
|
-
*
|
8
|
-
* For more resources visit {@link http://stefangabos.ro/}
|
9
|
-
*
|
10
|
-
* @author Stefan Gabos <contact@stefangabos.ro>
|
11
|
-
* @version 1.8.4 (last revision: August 11, 2013)
|
12
|
-
* @copyright (c) 2011 - 2013 Stefan Gabos
|
13
|
-
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE
|
14
|
-
* @package Zebra_DatePicker
|
15
|
-
*/
|
16
|
-
;(function($) {
|
17
|
-
|
18
|
-
$.Zebra_DatePicker = function(element, options) {
|
19
|
-
|
20
|
-
var defaults = {
|
21
|
-
|
22
|
-
// setting this property to a jQuery element, will result in the date picker being always visible, the indicated
|
23
|
-
// element being the date picker's container;
|
24
|
-
always_visible: false,
|
25
|
-
|
26
|
-
// days of the week; Sunday to Saturday
|
27
|
-
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
28
|
-
|
29
|
-
// by default, the abbreviated name of a day consists of the first 2 letters from the day's full name;
|
30
|
-
// while this is common for most languages, there are also exceptions for languages like Thai, Loa, Myanmar,
|
31
|
-
// etc. where this is not correct; for these cases, specify an array with the abbreviations to be used for
|
32
|
-
// the 7 days of the week; leave it FALSE to use the first 2 letters of a day's name as the abbreviation.
|
33
|
-
//
|
34
|
-
// default is FALSE
|
35
|
-
days_abbr: false,
|
36
|
-
|
37
|
-
// direction of the calendar
|
38
|
-
//
|
39
|
-
// a positive or negative integer: n (a positive integer) creates a future-only calendar beginning at n days
|
40
|
-
// after today; -n (a negative integer); if n is 0, the calendar has no restrictions. use boolean true for
|
41
|
-
// a future-only calendar starting with today and use boolean false for a past-only calendar ending today.
|
42
|
-
//
|
43
|
-
// you may also set this property to an array with two elements in the following combinations:
|
44
|
-
//
|
45
|
-
// - first item is boolean TRUE (calendar starts today), an integer > 0 (calendar starts n days after
|
46
|
-
// today), or a valid date given in the format defined by the "format" attribute, using English for
|
47
|
-
// month names (calendar starts at the specified date), and the second item is boolean FALSE (the calendar
|
48
|
-
// has no ending date), an integer > 0 (calendar ends n days after the starting date), or a valid date
|
49
|
-
// given in the format defined by the "format" attribute, using English for month names, and which occurs
|
50
|
-
// after the starting date (calendar ends at the specified date)
|
51
|
-
//
|
52
|
-
// - first item is boolean FALSE (calendar ends today), an integer < 0 (calendar ends n days before today),
|
53
|
-
// or a valid date given in the format defined by the "format" attribute, using English for month names
|
54
|
-
// (calendar ends at the specified date), and the second item is an integer > 0 (calendar ends n days
|
55
|
-
// before the ending date), or a valid date given in the format defined by the "format" attribute, using
|
56
|
-
// English for month names and which occurs before the starting date (calendar starts at the specified
|
57
|
-
// date)
|
58
|
-
//
|
59
|
-
// [1, 7] - calendar starts tomorrow and ends seven days after that
|
60
|
-
// [true, 7] - calendar starts today and ends seven days after that
|
61
|
-
// ['2013-01-01', false] - calendar starts on January 1st 2013 and has no ending date ("format" is YYYY-MM-DD)
|
62
|
-
// [false, '2012-01-01'] - calendar ends today and starts on January 1st 2012 ("format" is YYYY-MM-DD)
|
63
|
-
//
|
64
|
-
// note that "disabled_dates" property will still apply!
|
65
|
-
//
|
66
|
-
// default is 0 (no restrictions)
|
67
|
-
direction: 0,
|
68
|
-
|
69
|
-
// an array of disabled dates in the following format: 'day month year weekday' where "weekday" is optional
|
70
|
-
// and can be 0-6 (Saturday to Sunday); the syntax is similar to cron's syntax: the values are separated by
|
71
|
-
// spaces and may contain * (asterisk) - (dash) and , (comma) delimiters:
|
72
|
-
//
|
73
|
-
// ['1 1 2012'] would disable January 1, 2012;
|
74
|
-
// ['* 1 2012'] would disable all days in January 2012;
|
75
|
-
// ['1-10 1 2012'] would disable January 1 through 10 in 2012;
|
76
|
-
// ['1,10 1 2012'] would disable January 1 and 10 in 2012;
|
77
|
-
// ['1-10,20,22,24 1-3 *'] would disable 1 through 10, plus the 22nd and 24th of January through March for every year;
|
78
|
-
// ['* * * 0,6'] would disable all Saturdays and Sundays;
|
79
|
-
// ['01 07 2012', '02 07 2012', '* 08 2012'] would disable 1st and 2nd of July 2012, and all of August of 2012
|
80
|
-
//
|
81
|
-
// default is FALSE, no disabled dates
|
82
|
-
disabled_dates: false,
|
83
|
-
|
84
|
-
// an array of enabled dates in the same format as required for "disabled_dates" property.
|
85
|
-
// to be used together with the "disabled_dates" property by first setting the "disabled_dates" property to
|
86
|
-
// something like "[* * * *]" (which will disable everything) and the setting the "enabled_dates" property to,
|
87
|
-
// say, "[* * * 0,6]" to enable just weekends.
|
88
|
-
enabled_dates: false,
|
89
|
-
|
90
|
-
// week's starting day
|
91
|
-
//
|
92
|
-
// valid values are 0 to 6, Sunday to Saturday
|
93
|
-
//
|
94
|
-
// default is 1, Monday
|
95
|
-
first_day_of_week: 1,
|
96
|
-
|
97
|
-
// format of the returned date
|
98
|
-
//
|
99
|
-
// accepts the following characters for date formatting: d, D, j, l, N, w, S, F, m, M, n, Y, y borrowing
|
100
|
-
// syntax from (PHP's date function)
|
101
|
-
//
|
102
|
-
// note that when setting a date format without days ('d', 'j'), the users will be able to select only years
|
103
|
-
// and months, and when setting a format without months and days ('F', 'm', 'M', 'n', 'd', 'j'), the
|
104
|
-
// users will be able to select only years; likewise, when setting a date format with just months ('F', 'm',
|
105
|
-
// 'M', 'n') or just years ('Y', 'y'), users will be able to select only months and years, respectively.
|
106
|
-
//
|
107
|
-
// also note that the value of the "view" property (see below) may be overridden if it is the case: a value of
|
108
|
-
// "days" for the "view" property makes no sense if the date format doesn't allow the selection of days.
|
109
|
-
//
|
110
|
-
// default is Y-m-d
|
111
|
-
format: 'Y-m-d',
|
112
|
-
|
113
|
-
// should the icon for opening the datepicker be inside the element?
|
114
|
-
// if set to FALSE, the icon will be placed to the right of the parent element, while if set to TRUE it will
|
115
|
-
// be placed to the right of the parent element, but *inside* the element itself
|
116
|
-
//
|
117
|
-
// default is TRUE
|
118
|
-
inside: true,
|
119
|
-
|
120
|
-
// the caption for the "Clear" button
|
121
|
-
lang_clear_date: 'Clear date',
|
122
|
-
|
123
|
-
// months names
|
124
|
-
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
125
|
-
|
126
|
-
// by default, the abbreviated name of a month consists of the first 3 letters from the month's full name;
|
127
|
-
// while this is common for most languages, there are also exceptions for languages like Thai, Loa, Myanmar,
|
128
|
-
// etc. where this is not correct; for these cases, specify an array with the abbreviations to be used for
|
129
|
-
// the months of the year; leave it FALSE to use the first 3 letters of a month's name as the abbreviation.
|
130
|
-
//
|
131
|
-
// default is FALSE
|
132
|
-
months_abbr: false,
|
133
|
-
|
134
|
-
// the offset, in pixels (x, y), to shift the date picker's position relative to the top-right of the icon
|
135
|
-
// that toggles the date picker or, if the icon is disabled, relative to the top-right corner of the element
|
136
|
-
// the plugin is attached to.
|
137
|
-
//
|
138
|
-
// note that this only applies if the position of element relative to the browser's viewport doesn't require
|
139
|
-
// the date picker to be placed automatically so that it is visible!
|
140
|
-
//
|
141
|
-
// default is [5, -5]
|
142
|
-
offset: [5, -5],
|
143
|
-
|
144
|
-
// if set as a jQuery element with a Zebra_DatePicker attached, that particular date picker will use the
|
145
|
-
// current date picker's value as starting date
|
146
|
-
// note that the rules set in the "direction" property will still apply, only that the reference date will
|
147
|
-
// not be the current system date but the value selected in the current date picker
|
148
|
-
// default is FALSE (not paired with another date picker)
|
149
|
-
pair: false,
|
150
|
-
|
151
|
-
// should the element the calendar is attached to, be read-only?
|
152
|
-
// if set to TRUE, a date can be set only through the date picker and cannot be entered manually
|
153
|
-
//
|
154
|
-
// default is TRUE
|
155
|
-
readonly_element: true,
|
156
|
-
|
157
|
-
// should days from previous and/or next month be selectable when visible?
|
158
|
-
// note that if the value of this property is set to TRUE, the value of "show_other_months" will be considered
|
159
|
-
// TRUE regardless of the actual value!
|
160
|
-
//
|
161
|
-
// default is FALSE
|
162
|
-
select_other_months: false,
|
163
|
-
|
164
|
-
// should the "Clear date" button be visible?
|
165
|
-
//
|
166
|
-
// accepted values are:
|
167
|
-
//
|
168
|
-
// - 0 (zero) - the button for clearing a previously selected date is shown only if a previously selected date
|
169
|
-
// already exists; this means that if the input the date picker is attached to is empty, and the user selects
|
170
|
-
// a date for the first time, this button will not be visible; once the user picked a date and opens the date
|
171
|
-
// picker again, this time the button will be visible.
|
172
|
-
//
|
173
|
-
// - TRUE will make the button visible all the time
|
174
|
-
//
|
175
|
-
// - FALSE will disable the button
|
176
|
-
//
|
177
|
-
// default is "0" (without quotes)
|
178
|
-
show_clear_date: 0,
|
179
|
-
|
180
|
-
// should a calendar icon be added to the elements the plugin is attached to?
|
181
|
-
//
|
182
|
-
// default is TRUE
|
183
|
-
show_icon: true,
|
184
|
-
|
185
|
-
// should days from previous and/or next month be visible?
|
186
|
-
//
|
187
|
-
// default is TRUE
|
188
|
-
show_other_months: true,
|
189
|
-
|
190
|
-
// should the "Today" button be visible?
|
191
|
-
// setting it to anything but boolean FALSE will enable the button and will use the property's value as
|
192
|
-
// caption for the button; setting it to FALSE will disable the button
|
193
|
-
//
|
194
|
-
// default is "Today"
|
195
|
-
show_select_today: 'Today',
|
196
|
-
|
197
|
-
// should an extra column be shown, showing the number of each week?
|
198
|
-
// anything other than FALSE will enable this feature, and use the given value as column title
|
199
|
-
// i.e. show_week_number: 'Wk' would enable this feature and have "Wk" as the column's title
|
200
|
-
//
|
201
|
-
// default is FALSE
|
202
|
-
show_week_number: false,
|
203
|
-
|
204
|
-
// a default date to start the date picker with
|
205
|
-
// must be specified in the format defined by the "format" property, or it will be ignored!
|
206
|
-
// note that this value is used only if there is no value in the field the date picker is attached to!
|
207
|
-
start_date: false,
|
208
|
-
|
209
|
-
// how should the date picker start; valid values are "days", "months" and "years"
|
210
|
-
// note that the date picker is always cycling days-months-years when clicking in the date picker's header,
|
211
|
-
// and years-months-days when selecting dates (unless one or more of the views are missing due to the date's
|
212
|
-
// format)
|
213
|
-
//
|
214
|
-
// also note that the value of the "view" property may be overridden if the date's format requires so! (i.e.
|
215
|
-
// "days" for the "view" property makes no sense if the date format doesn't allow the selection of days)
|
216
|
-
//
|
217
|
-
// default is "days"
|
218
|
-
view: 'days',
|
219
|
-
|
220
|
-
// days of the week that are considered "weekend days"
|
221
|
-
// valid values are 0 to 6, Sunday to Saturday
|
222
|
-
//
|
223
|
-
// default values are 0 and 6 (Saturday and Sunday)
|
224
|
-
weekend_days: [0, 6],
|
225
|
-
|
226
|
-
// when set to TRUE, day numbers < 10 will be prefixed with 0; set to FALSE if you don't want that
|
227
|
-
//
|
228
|
-
// default is TRUE
|
229
|
-
zero_pad: false,
|
230
|
-
|
231
|
-
// callback function to be executed whenever the user changes the view (days/months/years), as well as when
|
232
|
-
// the user navigates by clicking on the "next"/"previous" icons in any of the views;
|
233
|
-
//
|
234
|
-
// the callback function called by this event takes 3 arguments - the first argument represents the current
|
235
|
-
// view (can be "days", "months" or "years"), the second argument represents an array containing the "active"
|
236
|
-
// elements (not disabled) from the view, as jQuery elements, allowing for easy customization and interaction
|
237
|
-
// with particular cells in the date picker's view, while the third argument is a reference to the element
|
238
|
-
// the date picker is attached to, as a jQuery object
|
239
|
-
//
|
240
|
-
// for simplifying searching for particular dates, each element in the second argument will also have a
|
241
|
-
// "date" data attribute whose format depends on the value of the "view" argument:
|
242
|
-
// - YYYY-MM-DD for elements in the "days" view
|
243
|
-
// - YYYY-MM for elements in the "months" view
|
244
|
-
// - YYYY for elements in the "years" view
|
245
|
-
onChange: null,
|
246
|
-
|
247
|
-
// callback function to be executed when the user clicks the "Clear" button
|
248
|
-
// the callback function takes a single argument:
|
249
|
-
// - a reference to the element the date picker is attached to, as a jQuery object
|
250
|
-
onClear: null,
|
251
|
-
|
252
|
-
// callback function to be executed when a date is selected
|
253
|
-
// the callback function takes 4 arguments:
|
254
|
-
// - the date in the format specified by the "format" attribute;
|
255
|
-
// - the date in YYYY-MM-DD format
|
256
|
-
// - the date as a JavaScript Date object
|
257
|
-
// - a reference to the element the date picker is attached to, as a jQuery object
|
258
|
-
onSelect: null
|
259
|
-
|
260
|
-
};
|
261
|
-
|
262
|
-
// private properties
|
263
|
-
var view, datepicker, icon, header, daypicker, monthpicker, yearpicker, cleardate, current_system_month, current_system_year,
|
264
|
-
current_system_day, first_selectable_month, first_selectable_year, first_selectable_day, selected_month, selected_year,
|
265
|
-
default_day, default_month, default_year, enabled_dates, disabled_dates, shim, start_date, end_date, last_selectable_day,
|
266
|
-
last_selectable_year, last_selectable_month, daypicker_cells, monthpicker_cells, yearpicker_cells, views, clickables,
|
267
|
-
selecttoday, footer, show_select_today, timeout;
|
268
|
-
|
269
|
-
var plugin = this;
|
270
|
-
|
271
|
-
plugin.settings = {};
|
272
|
-
|
273
|
-
// the jQuery version of the element
|
274
|
-
// "element" (without the $) will point to the DOM element
|
275
|
-
var $element = $(element);
|
276
|
-
|
277
|
-
/**
|
278
|
-
* Constructor method. Initializes the date picker.
|
279
|
-
*
|
280
|
-
* @return void
|
281
|
-
*/
|
282
|
-
var init = function(update) {
|
283
|
-
|
284
|
-
// merge default settings with user-settings (unless we're just updating settings)
|
285
|
-
if (!update) plugin.settings = $.extend({}, defaults, options);
|
286
|
-
|
287
|
-
// if the element should be read-only, set the "readonly" attribute
|
288
|
-
if (plugin.settings.readonly_element) $element.attr('readonly', 'readonly');
|
289
|
-
|
290
|
-
// determine the views the user can cycle through, depending on the format
|
291
|
-
// that is, if the format doesn't contain the day, the user will be able to cycle only through years and months,
|
292
|
-
// whereas if the format doesn't contain months nor days, the user will only be able to select years
|
293
|
-
|
294
|
-
var
|
295
|
-
|
296
|
-
// the characters that may be present in the date format and that represent days, months and years
|
297
|
-
date_chars = {
|
298
|
-
days: ['d', 'j', 'D'],
|
299
|
-
months: ['F', 'm', 'M', 'n', 't'],
|
300
|
-
years: ['o', 'Y', 'y']
|
301
|
-
},
|
302
|
-
|
303
|
-
// some defaults
|
304
|
-
has_days = false,
|
305
|
-
has_months = false,
|
306
|
-
has_years = false,
|
307
|
-
type = null;
|
308
|
-
|
309
|
-
// iterate through all the character blocks
|
310
|
-
for (type in date_chars)
|
311
|
-
|
312
|
-
// iterate through the characters of each block
|
313
|
-
$.each(date_chars[type], function(index, character) {
|
314
|
-
|
315
|
-
// if current character exists in the "format" property
|
316
|
-
if (plugin.settings.format.indexOf(character) > -1)
|
317
|
-
|
318
|
-
// set to TRUE the appropriate flag
|
319
|
-
if (type == 'days') has_days = true;
|
320
|
-
else if (type == 'months') has_months = true;
|
321
|
-
else if (type == 'years') has_years = true;
|
322
|
-
|
323
|
-
});
|
324
|
-
|
325
|
-
// if user can cycle through all the views, set the flag accordingly
|
326
|
-
if (has_days && has_months && has_years) views = ['years', 'months', 'days'];
|
327
|
-
|
328
|
-
// if user can cycle only through year and months, set the flag accordingly
|
329
|
-
else if (!has_days && has_months && has_years) views = ['years', 'months'];
|
330
|
-
|
331
|
-
// if user can only see the year picker, set the flag accordingly
|
332
|
-
else if (!has_days && !has_months && has_years) views = ['years'];
|
333
|
-
|
334
|
-
// if user can only see the month picker, set the flag accordingly
|
335
|
-
else if (!has_days && has_months && !has_years) views = ['months'];
|
336
|
-
|
337
|
-
// if invalid format (no days, no months, no years) use the default where the user is able to cycle through
|
338
|
-
// all the views
|
339
|
-
else views = ['years', 'months', 'days'];
|
340
|
-
|
341
|
-
// if the starting view is not amongst the views the user can cycle through, set the correct starting view
|
342
|
-
if ($.inArray(plugin.settings.view, views) == -1) plugin.settings.view = views[views.length - 1];
|
343
|
-
|
344
|
-
// parse the rules for disabling dates and turn them into arrays of arrays
|
345
|
-
|
346
|
-
// array that will hold the rules for enabling/disabling dates
|
347
|
-
disabled_dates = []; enabled_dates = [];
|
348
|
-
|
349
|
-
var dates;
|
350
|
-
|
351
|
-
// it's the same logic for preparing the enabled/disable dates...
|
352
|
-
for (var l = 0; l < 2; l++) {
|
353
|
-
|
354
|
-
// first time we're doing disabled dates,
|
355
|
-
if (l === 0) dates = plugin.settings.disabled_dates;
|
356
|
-
|
357
|
-
// second time we're doing enabled_dates
|
358
|
-
else dates = plugin.settings.enabled_dates;
|
359
|
-
|
360
|
-
// if we have a non-empty array
|
361
|
-
if ($.isArray(dates) && dates.length > 0)
|
362
|
-
|
363
|
-
// iterate through the rules
|
364
|
-
$.each(dates, function() {
|
365
|
-
|
366
|
-
// split the values in rule by white space
|
367
|
-
var rules = this.split(' ');
|
368
|
-
|
369
|
-
// there can be a maximum of 4 rules (days, months, years and, optionally, day of the week)
|
370
|
-
for (var i = 0; i < 4; i++) {
|
371
|
-
|
372
|
-
// if one of the values is not available
|
373
|
-
// replace it with a * (wildcard)
|
374
|
-
if (!rules[i]) rules[i] = '*';
|
375
|
-
|
376
|
-
// if rule contains a comma, create a new array by splitting the rule by commas
|
377
|
-
// if there are no commas create an array containing the rule's string
|
378
|
-
rules[i] = (rules[i].indexOf(',') > -1 ? rules[i].split(',') : new Array(rules[i]));
|
379
|
-
|
380
|
-
// iterate through the items in the rule
|
381
|
-
for (var j = 0; j < rules[i].length; j++)
|
382
|
-
|
383
|
-
// if item contains a dash (defining a range)
|
384
|
-
if (rules[i][j].indexOf('-') > -1) {
|
385
|
-
|
386
|
-
// get the lower and upper limits of the range
|
387
|
-
var limits = rules[i][j].match(/^([0-9]+)\-([0-9]+)/);
|
388
|
-
|
389
|
-
// if range is valid
|
390
|
-
if (null !== limits) {
|
391
|
-
|
392
|
-
// iterate through the range
|
393
|
-
for (var k = to_int(limits[1]); k <= to_int(limits[2]); k++)
|
394
|
-
|
395
|
-
// if value is not already among the values of the rule
|
396
|
-
// add it to the rule
|
397
|
-
if ($.inArray(k, rules[i]) == -1) rules[i].push(k + '');
|
398
|
-
|
399
|
-
// remove the range indicator
|
400
|
-
rules[i].splice(j, 1);
|
401
|
-
|
402
|
-
}
|
403
|
-
|
404
|
-
}
|
405
|
-
|
406
|
-
// iterate through the items in the rule
|
407
|
-
// and make sure that numbers are numbers
|
408
|
-
for (j = 0; j < rules[i].length; j++) rules[i][j] = (isNaN(to_int(rules[i][j])) ? rules[i][j] : to_int(rules[i][j]));
|
409
|
-
|
410
|
-
}
|
411
|
-
|
412
|
-
// add to the correct list of processed rules
|
413
|
-
// first time we're doing disabled dates,
|
414
|
-
if (l === 0) disabled_dates.push(rules);
|
415
|
-
|
416
|
-
// second time we're doing enabled_dates
|
417
|
-
else enabled_dates.push(rules);
|
418
|
-
|
419
|
-
});
|
420
|
-
|
421
|
-
}
|
422
|
-
|
423
|
-
var
|
424
|
-
|
425
|
-
// cache the current system date
|
426
|
-
date = new Date(),
|
427
|
-
|
428
|
-
// when the date picker's starting date depends on the value of another date picker, this value will be
|
429
|
-
// set by the other date picker
|
430
|
-
// this value will be used as base for all calculations (if not set, will be the same as the current
|
431
|
-
// system date)
|
432
|
-
reference_date = (!plugin.settings.reference_date ? ($element.data('zdp_reference_date') && undefined !== $element.data('zdp_reference_date') ? $element.data('zdp_reference_date') : date) : plugin.settings.reference_date),
|
433
|
-
|
434
|
-
tmp_start_date, tmp_end_date;
|
435
|
-
|
436
|
-
// reset these values here as this method might be called more than once during a date picker's lifetime
|
437
|
-
// (when the selectable dates depend on the values from another date picker)
|
438
|
-
start_date = undefined; end_date = undefined;
|
439
|
-
|
440
|
-
// extract the date parts
|
441
|
-
// also, save the current system month/day/year - we'll use them to highlight the current system date
|
442
|
-
first_selectable_month = reference_date.getMonth();
|
443
|
-
current_system_month = date.getMonth();
|
444
|
-
first_selectable_year = reference_date.getFullYear();
|
445
|
-
current_system_year = date.getFullYear();
|
446
|
-
first_selectable_day = reference_date.getDate();
|
447
|
-
current_system_day = date.getDate();
|
448
|
-
|
449
|
-
// check if the calendar has any restrictions
|
450
|
-
|
451
|
-
// calendar is future-only, starting today
|
452
|
-
// it means we have a starting date (the current system date), but no ending date
|
453
|
-
if (plugin.settings.direction === true) start_date = reference_date;
|
454
|
-
|
455
|
-
// calendar is past only, ending today
|
456
|
-
else if (plugin.settings.direction === false) {
|
457
|
-
|
458
|
-
// it means we have an ending date (the reference date), but no starting date
|
459
|
-
end_date = reference_date;
|
460
|
-
|
461
|
-
// extract the date parts
|
462
|
-
last_selectable_month = end_date.getMonth();
|
463
|
-
last_selectable_year = end_date.getFullYear();
|
464
|
-
last_selectable_day = end_date.getDate();
|
465
|
-
|
466
|
-
} else if (
|
467
|
-
|
468
|
-
// if direction is not given as an array and the value is an integer > 0
|
469
|
-
(!$.isArray(plugin.settings.direction) && is_integer(plugin.settings.direction) && to_int(plugin.settings.direction) > 0) ||
|
470
|
-
|
471
|
-
// or direction is given as an array
|
472
|
-
($.isArray(plugin.settings.direction) && (
|
473
|
-
|
474
|
-
// and first entry is a valid date
|
475
|
-
(tmp_start_date = check_date(plugin.settings.direction[0])) ||
|
476
|
-
// or a boolean TRUE
|
477
|
-
plugin.settings.direction[0] === true ||
|
478
|
-
// or an integer > 0
|
479
|
-
(is_integer(plugin.settings.direction[0]) && plugin.settings.direction[0] > 0)
|
480
|
-
|
481
|
-
) && (
|
482
|
-
|
483
|
-
// and second entry is a valid date
|
484
|
-
(tmp_end_date = check_date(plugin.settings.direction[1])) ||
|
485
|
-
// or a boolean FALSE
|
486
|
-
plugin.settings.direction[1] === false ||
|
487
|
-
// or integer >= 0
|
488
|
-
(is_integer(plugin.settings.direction[1]) && plugin.settings.direction[1] >= 0)
|
489
|
-
|
490
|
-
))
|
491
|
-
|
492
|
-
) {
|
493
|
-
|
494
|
-
// if an exact starting date was given, use that as a starting date
|
495
|
-
if (tmp_start_date) start_date = tmp_start_date;
|
496
|
-
|
497
|
-
// otherwise
|
498
|
-
else
|
499
|
-
|
500
|
-
// figure out the starting date
|
501
|
-
// use the Date object to normalize the date
|
502
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
503
|
-
start_date = new Date(
|
504
|
-
first_selectable_year,
|
505
|
-
first_selectable_month,
|
506
|
-
first_selectable_day + (!$.isArray(plugin.settings.direction) ? to_int(plugin.settings.direction) : to_int(plugin.settings.direction[0] === true ? 0 : plugin.settings.direction[0]))
|
507
|
-
);
|
508
|
-
|
509
|
-
// re-extract the date parts
|
510
|
-
first_selectable_month = start_date.getMonth();
|
511
|
-
first_selectable_year = start_date.getFullYear();
|
512
|
-
first_selectable_day = start_date.getDate();
|
513
|
-
|
514
|
-
// if an exact ending date was given and the date is after the starting date, use that as a ending date
|
515
|
-
if (tmp_end_date && +tmp_end_date >= +start_date) end_date = tmp_end_date;
|
516
|
-
|
517
|
-
// if have information about the ending date
|
518
|
-
else if (!tmp_end_date && plugin.settings.direction[1] !== false && $.isArray(plugin.settings.direction))
|
519
|
-
|
520
|
-
// figure out the ending date
|
521
|
-
// use the Date object to normalize the date
|
522
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
523
|
-
end_date = new Date(
|
524
|
-
first_selectable_year,
|
525
|
-
first_selectable_month,
|
526
|
-
first_selectable_day + to_int(plugin.settings.direction[1])
|
527
|
-
);
|
528
|
-
|
529
|
-
// if a valid ending date exists
|
530
|
-
if (end_date) {
|
531
|
-
|
532
|
-
// extract the date parts
|
533
|
-
last_selectable_month = end_date.getMonth();
|
534
|
-
last_selectable_year = end_date.getFullYear();
|
535
|
-
last_selectable_day = end_date.getDate();
|
536
|
-
|
537
|
-
}
|
538
|
-
|
539
|
-
} else if (
|
540
|
-
|
541
|
-
// if direction is not given as an array and the value is an integer < 0
|
542
|
-
(!$.isArray(plugin.settings.direction) && is_integer(plugin.settings.direction) && to_int(plugin.settings.direction) < 0) ||
|
543
|
-
|
544
|
-
// or direction is given as an array
|
545
|
-
($.isArray(plugin.settings.direction) && (
|
546
|
-
|
547
|
-
// and first entry is boolean FALSE
|
548
|
-
plugin.settings.direction[0] === false ||
|
549
|
-
// or an integer < 0
|
550
|
-
(is_integer(plugin.settings.direction[0]) && plugin.settings.direction[0] < 0)
|
551
|
-
|
552
|
-
) && (
|
553
|
-
|
554
|
-
// and second entry is a valid date
|
555
|
-
(tmp_start_date = check_date(plugin.settings.direction[1])) ||
|
556
|
-
// or an integer >= 0
|
557
|
-
(is_integer(plugin.settings.direction[1]) && plugin.settings.direction[1] >= 0)
|
558
|
-
|
559
|
-
))
|
560
|
-
|
561
|
-
) {
|
562
|
-
|
563
|
-
// figure out the ending date
|
564
|
-
// use the Date object to normalize the date
|
565
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
566
|
-
end_date = new Date(
|
567
|
-
first_selectable_year,
|
568
|
-
first_selectable_month,
|
569
|
-
first_selectable_day + (!$.isArray(plugin.settings.direction) ? to_int(plugin.settings.direction) : to_int(plugin.settings.direction[0] === false ? 0 : plugin.settings.direction[0]))
|
570
|
-
);
|
571
|
-
|
572
|
-
// re-extract the date parts
|
573
|
-
last_selectable_month = end_date.getMonth();
|
574
|
-
last_selectable_year = end_date.getFullYear();
|
575
|
-
last_selectable_day = end_date.getDate();
|
576
|
-
|
577
|
-
// if an exact starting date was given, and the date is before the ending date, use that as a starting date
|
578
|
-
if (tmp_start_date && +tmp_start_date < +end_date) start_date = tmp_start_date;
|
579
|
-
|
580
|
-
// if have information about the starting date
|
581
|
-
else if (!tmp_start_date && $.isArray(plugin.settings.direction))
|
582
|
-
|
583
|
-
// figure out the staring date
|
584
|
-
// use the Date object to normalize the date
|
585
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
586
|
-
start_date = new Date(
|
587
|
-
last_selectable_year,
|
588
|
-
last_selectable_month,
|
589
|
-
last_selectable_day - to_int(plugin.settings.direction[1])
|
590
|
-
);
|
591
|
-
|
592
|
-
// if a valid starting date exists
|
593
|
-
if (start_date) {
|
594
|
-
|
595
|
-
// extract the date parts
|
596
|
-
first_selectable_month = start_date.getMonth();
|
597
|
-
first_selectable_year = start_date.getFullYear();
|
598
|
-
first_selectable_day = start_date.getDate();
|
599
|
-
|
600
|
-
}
|
601
|
-
|
602
|
-
// if there are disabled dates
|
603
|
-
} else if ($.isArray(plugin.settings.disabled_dates) && plugin.settings.disabled_dates.length > 0)
|
604
|
-
|
605
|
-
// iterate through the rules for disabling dates
|
606
|
-
for (var interval in disabled_dates)
|
607
|
-
|
608
|
-
// only if there is a rule that disables *everything*
|
609
|
-
if (disabled_dates[interval][0] == '*' && disabled_dates[interval][1] == '*' && disabled_dates[interval][2] == '*' && disabled_dates[interval][3] == '*') {
|
610
|
-
|
611
|
-
var tmpDates = [];
|
612
|
-
|
613
|
-
// iterate through the rules for enabling dates
|
614
|
-
// looking for the minimum/maximum selectable date (if it's the case)
|
615
|
-
$.each(enabled_dates, function() {
|
616
|
-
|
617
|
-
var rule = this;
|
618
|
-
|
619
|
-
// if the rule doesn't apply to all years
|
620
|
-
if (rule[2][0] != '*')
|
621
|
-
|
622
|
-
// format date and store it in our stack
|
623
|
-
tmpDates.push(parseInt(
|
624
|
-
rule[2][0] +
|
625
|
-
(rule[1][0] == '*' ? '12' : str_pad(rule[1][0], 2)) +
|
626
|
-
(rule[0][0] == '*' ? (rule[1][0] == '*' ? '31' : new Date(rule[2][0], rule[1][0], 0).getDate()) : str_pad(rule[0][0], 2)), 10));
|
627
|
-
|
628
|
-
});
|
629
|
-
|
630
|
-
// sort dates ascending
|
631
|
-
tmpDates.sort();
|
632
|
-
|
633
|
-
// if we have any rules
|
634
|
-
if (tmpDates.length > 0) {
|
635
|
-
|
636
|
-
// get date parts
|
637
|
-
var matches = (tmpDates[0] + '').match(/([0-9]{4})([0-9]{2})([0-9]{2})/);
|
638
|
-
|
639
|
-
// assign the date parts to the appropriate variables
|
640
|
-
first_selectable_year = parseInt(matches[1], 10);
|
641
|
-
first_selectable_month = parseInt(matches[2], 10) - 1;
|
642
|
-
first_selectable_day = parseInt(matches[3], 10);
|
643
|
-
|
644
|
-
}
|
645
|
-
|
646
|
-
// don't look further
|
647
|
-
break;
|
648
|
-
|
649
|
-
}
|
650
|
-
|
651
|
-
// if first selectable date exists but is disabled, find the actual first selectable date
|
652
|
-
if (is_disabled(first_selectable_year, first_selectable_month, first_selectable_day)) {
|
653
|
-
|
654
|
-
// loop until we find the first selectable year
|
655
|
-
while (is_disabled(first_selectable_year)) {
|
656
|
-
|
657
|
-
// if calendar is past-only,
|
658
|
-
if (!start_date) {
|
659
|
-
|
660
|
-
// decrement the year
|
661
|
-
first_selectable_year--;
|
662
|
-
|
663
|
-
// because we've changed years, reset the month to December
|
664
|
-
first_selectable_month = 11;
|
665
|
-
|
666
|
-
// otherwise
|
667
|
-
} else {
|
668
|
-
|
669
|
-
// increment the year
|
670
|
-
first_selectable_year++;
|
671
|
-
|
672
|
-
// because we've changed years, reset the month to January
|
673
|
-
first_selectable_month = 0;
|
674
|
-
|
675
|
-
}
|
676
|
-
|
677
|
-
}
|
678
|
-
|
679
|
-
// loop until we find the first selectable month
|
680
|
-
while (is_disabled(first_selectable_year, first_selectable_month)) {
|
681
|
-
|
682
|
-
// if calendar is past-only
|
683
|
-
if (!start_date) {
|
684
|
-
|
685
|
-
// decrement the month
|
686
|
-
first_selectable_month--;
|
687
|
-
|
688
|
-
// because we've changed months, reset the day to the last day of the month
|
689
|
-
first_selectable_day = new Date(first_selectable_year, first_selectable_month + 1, 0).getDate();
|
690
|
-
|
691
|
-
// otherwise
|
692
|
-
} else {
|
693
|
-
|
694
|
-
// increment the month
|
695
|
-
first_selectable_month++;
|
696
|
-
|
697
|
-
// because we've changed months, reset the day to the first day of the month
|
698
|
-
first_selectable_day = 1;
|
699
|
-
|
700
|
-
}
|
701
|
-
|
702
|
-
// if we moved to a following year
|
703
|
-
if (first_selectable_month > 11) {
|
704
|
-
|
705
|
-
// increment the year
|
706
|
-
first_selectable_year++;
|
707
|
-
|
708
|
-
// reset the month to January
|
709
|
-
first_selectable_month = 0;
|
710
|
-
|
711
|
-
// because we've changed months, reset the day to the first day of the month
|
712
|
-
first_selectable_day = 1;
|
713
|
-
|
714
|
-
// if we moved to a previous year
|
715
|
-
} else if (first_selectable_month < 0) {
|
716
|
-
|
717
|
-
// decrement the year
|
718
|
-
first_selectable_year--;
|
719
|
-
|
720
|
-
// reset the month to December
|
721
|
-
first_selectable_month = 11;
|
722
|
-
|
723
|
-
// because we've changed months, reset the day to the last day of the month
|
724
|
-
first_selectable_day = new Date(first_selectable_year, first_selectable_month + 1, 0).getDate();
|
725
|
-
|
726
|
-
}
|
727
|
-
|
728
|
-
}
|
729
|
-
|
730
|
-
// loop until we find the first selectable day
|
731
|
-
while (is_disabled(first_selectable_year, first_selectable_month, first_selectable_day)) {
|
732
|
-
|
733
|
-
// if calendar is past-only, decrement the day
|
734
|
-
if (!start_date) first_selectable_day--;
|
735
|
-
|
736
|
-
// otherwise, increment the day
|
737
|
-
else first_selectable_day++;
|
738
|
-
|
739
|
-
// use the Date object to normalize the date
|
740
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
741
|
-
date = new Date(first_selectable_year, first_selectable_month, first_selectable_day);
|
742
|
-
|
743
|
-
// re-extract date parts from the normalized date
|
744
|
-
// as we use them in the current loop
|
745
|
-
first_selectable_year = date.getFullYear();
|
746
|
-
first_selectable_month = date.getMonth();
|
747
|
-
first_selectable_day = date.getDate();
|
748
|
-
|
749
|
-
}
|
750
|
-
|
751
|
-
// use the Date object to normalize the date
|
752
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
753
|
-
date = new Date(first_selectable_year, first_selectable_month, first_selectable_day);
|
754
|
-
|
755
|
-
// re-extract date parts from the normalized date
|
756
|
-
// as we use them in the current loop
|
757
|
-
first_selectable_year = date.getFullYear();
|
758
|
-
first_selectable_month = date.getMonth();
|
759
|
-
first_selectable_day = date.getDate();
|
760
|
-
|
761
|
-
}
|
762
|
-
|
763
|
-
// get the default date, from the element, and check if it represents a valid date, according to the required format
|
764
|
-
var default_date = check_date($element.val() || (plugin.settings.start_date ? plugin.settings.start_date : ''));
|
765
|
-
|
766
|
-
// if there is a default date but it is disabled
|
767
|
-
if (default_date && is_disabled(default_date.getFullYear(), default_date.getMonth(), default_date.getDate()))
|
768
|
-
|
769
|
-
// clear the value of the parent element
|
770
|
-
$element.val('');
|
771
|
-
|
772
|
-
// updates value for the date picker whose starting date depends on the selected date (if any)
|
773
|
-
update_dependent(default_date);
|
774
|
-
|
775
|
-
// if date picker is not always visible
|
776
|
-
if (!plugin.settings.always_visible) {
|
777
|
-
|
778
|
-
// if we're just creating the date picker
|
779
|
-
if (!update) {
|
780
|
-
|
781
|
-
// if a calendar icon should be added to the element the plugin is attached to, create the icon now
|
782
|
-
if (plugin.settings.show_icon) {
|
783
|
-
|
784
|
-
// strangely, in Firefox 21+ (or maybe even earlier) input elements have their "display" property
|
785
|
-
// set to "inline" instead of "inline-block" as do all the other browsers.
|
786
|
-
// because this behavior brakes the positioning of the icon, we'll set the "display" property to
|
787
|
-
// "inline-block" before anything else;
|
788
|
-
if (browser.name == 'firefox' && $element.is('input[type="text"]') && $element.css('display') == 'inline') $element.css('display', 'inline-block');
|
789
|
-
|
790
|
-
// we create a wrapper for the parent element so that we can later position the icon
|
791
|
-
// also, make sure the wrapper inherits some important css properties of the parent element
|
792
|
-
var icon_wrapper = jQuery('<span class="Zebra_DatePicker_Icon_Wrapper"></span>').css({
|
793
|
-
'display': $element.css('display'),
|
794
|
-
'position': $element.css('position') == 'static' ? 'relative' : $element.css('position'),
|
795
|
-
'float': $element.css('float'),
|
796
|
-
'top': $element.css('top'),
|
797
|
-
'right': $element.css('right'),
|
798
|
-
'bottom': $element.css('bottom'),
|
799
|
-
'left': $element.css('left')
|
800
|
-
});
|
801
|
-
|
802
|
-
// put wrapper around the element
|
803
|
-
// also, make sure we set some important css properties for it
|
804
|
-
$element.wrap(icon_wrapper).css({
|
805
|
-
'position': 'relative',
|
806
|
-
'top': 'auto',
|
807
|
-
'right': 'auto',
|
808
|
-
'bottom': 'auto',
|
809
|
-
'left': 'auto'
|
810
|
-
});
|
811
|
-
|
812
|
-
// create the actual calendar icon (show a disabled icon if the element is disabled)
|
813
|
-
icon = jQuery('<button type="button" class="Zebra_DatePicker_Icon' + ($element.attr('disabled') == 'disabled' ? ' Zebra_DatePicker_Icon_Disabled' : '') + '">Pick a date</button>');
|
814
|
-
|
815
|
-
// a reference to the icon, as a global property
|
816
|
-
plugin.icon = icon;
|
817
|
-
|
818
|
-
// the date picker will open when clicking both the icon and the element the plugin is attached to
|
819
|
-
clickables = icon.add($element);
|
820
|
-
|
821
|
-
// if calendar icon is not visible, the date picker will open when clicking the element
|
822
|
-
} else clickables = $element;
|
823
|
-
|
824
|
-
// attach the click event to the clickable elements (icon and/or element)
|
825
|
-
clickables.bind('click', function(e) {
|
826
|
-
|
827
|
-
e.preventDefault();
|
828
|
-
|
829
|
-
// if element is not disabled
|
830
|
-
if (!$element.attr('disabled'))
|
831
|
-
|
832
|
-
// if the date picker is visible, hide it
|
833
|
-
if (datepicker.css('display') != 'none') plugin.hide();
|
834
|
-
|
835
|
-
// if the date picker is not visible, show it
|
836
|
-
else plugin.show();
|
837
|
-
|
838
|
-
});
|
839
|
-
|
840
|
-
// if icon exists, inject it into the DOM, right after the parent element (and inside the wrapper)
|
841
|
-
if (undefined !== icon) icon.insertAfter($element);
|
842
|
-
|
843
|
-
}
|
844
|
-
|
845
|
-
// if calendar icon exists
|
846
|
-
if (undefined !== icon) {
|
847
|
-
|
848
|
-
// needed when updating: remove any inline style set previously by library,
|
849
|
-
// so we get the right values below
|
850
|
-
icon.attr('style', '');
|
851
|
-
|
852
|
-
// if calendar icon is to be placed *inside* the element
|
853
|
-
// add an extra class to the icon
|
854
|
-
if (plugin.settings.inside) icon.addClass('Zebra_DatePicker_Icon_Inside');
|
855
|
-
|
856
|
-
var
|
857
|
-
|
858
|
-
// get element' width and height (including margins)
|
859
|
-
element_width = $element.outerWidth(),
|
860
|
-
element_height = $element.outerHeight(),
|
861
|
-
element_margin_left = parseInt($element.css('marginLeft'), 10) || 0,
|
862
|
-
element_margin_top = parseInt($element.css('marginTop'), 10) || 0,
|
863
|
-
|
864
|
-
// get icon's width, height and margins
|
865
|
-
icon_width = icon.outerWidth(),
|
866
|
-
icon_height = icon.outerHeight(),
|
867
|
-
icon_margin_left = parseInt(icon.css('marginLeft'), 10) || 0,
|
868
|
-
icon_margin_right = parseInt(icon.css('marginRight'), 10) || 0;
|
869
|
-
|
870
|
-
// if icon is to be placed *inside* the element
|
871
|
-
// position the icon accordingly
|
872
|
-
if (plugin.settings.inside)
|
873
|
-
|
874
|
-
icon.css({
|
875
|
-
'top': element_margin_top + ((element_height - icon_height) / 2),
|
876
|
-
'left': element_margin_left + (element_width - icon_width - icon_margin_right)
|
877
|
-
});
|
878
|
-
|
879
|
-
// if icon is to be placed to the right of the element
|
880
|
-
// position the icon accordingly
|
881
|
-
else
|
882
|
-
|
883
|
-
icon.css({
|
884
|
-
'top': element_margin_top + ((element_height - icon_height) / 2),
|
885
|
-
'left': element_margin_left + element_width + icon_margin_left
|
886
|
-
});
|
887
|
-
|
888
|
-
}
|
889
|
-
|
890
|
-
}
|
891
|
-
|
892
|
-
// if calendar icon exists (there's no icon if the date picker is always visible or it is specifically hidden)
|
893
|
-
if (undefined !== icon)
|
894
|
-
|
895
|
-
// if parent element is not visible (has display: none, width and height are explicitly set to 0, an ancestor
|
896
|
-
// element is hidden, so the element is not shown on the page), hide the icon, or show it otherwise
|
897
|
-
if (!($element.is(':visible'))) icon.hide(); else icon.show();
|
898
|
-
|
899
|
-
// if the "Today" button is to be shown and it makes sense to be shown
|
900
|
-
// (the "days" view is available and "today" is not a disabled date)
|
901
|
-
show_select_today = (plugin.settings.show_select_today !== false && $.inArray('days', views) > -1 && !is_disabled(current_system_year, current_system_month, current_system_day) ? plugin.settings.show_select_today : false);
|
902
|
-
|
903
|
-
// if we just needed to recompute the things above, return now
|
904
|
-
if (update) return;
|
905
|
-
|
906
|
-
// if icon exists, update its position when the page is resized
|
907
|
-
if (icon) $(window).bind('resize', _resize);
|
908
|
-
|
909
|
-
// generate the container that will hold everything
|
910
|
-
var html = '' +
|
911
|
-
'<div class="Zebra_DatePicker">' +
|
912
|
-
'<table class="dp_header">' +
|
913
|
-
'<tr>' +
|
914
|
-
'<td class="dp_previous">«</td>' +
|
915
|
-
'<td class="dp_caption"> </td>' +
|
916
|
-
'<td class="dp_next">»</td>' +
|
917
|
-
'</tr>' +
|
918
|
-
'</table>' +
|
919
|
-
'<table class="dp_daypicker"></table>' +
|
920
|
-
'<table class="dp_monthpicker"></table>' +
|
921
|
-
'<table class="dp_yearpicker"></table>' +
|
922
|
-
'<table class="dp_footer"><tr>' +
|
923
|
-
'<td class="dp_today"' + (plugin.settings.show_clear_date !== false ? ' style="width:50%"' : '') + '>' + show_select_today + '</td>' +
|
924
|
-
'<td class="dp_clear"' + (show_select_today !== false ? ' style="width:50%"' : '') + '>' + plugin.settings.lang_clear_date + '</td>' +
|
925
|
-
'</tr></table>' +
|
926
|
-
'</div>';
|
927
|
-
|
928
|
-
// create a jQuery object out of the HTML above and create a reference to it
|
929
|
-
datepicker = $(html);
|
930
|
-
|
931
|
-
// a reference to the calendar, as a global property
|
932
|
-
plugin.datepicker = datepicker;
|
933
|
-
|
934
|
-
// create references to the different parts of the date picker
|
935
|
-
header = $('table.dp_header', datepicker);
|
936
|
-
daypicker = $('table.dp_daypicker', datepicker);
|
937
|
-
monthpicker = $('table.dp_monthpicker', datepicker);
|
938
|
-
yearpicker = $('table.dp_yearpicker', datepicker);
|
939
|
-
footer = $('table.dp_footer', datepicker);
|
940
|
-
selecttoday = $('td.dp_today', footer);
|
941
|
-
cleardate = $('td.dp_clear', footer);
|
942
|
-
|
943
|
-
// if date picker is not always visible
|
944
|
-
if (!plugin.settings.always_visible)
|
945
|
-
|
946
|
-
// inject the container into the DOM
|
947
|
-
$('body').append(datepicker);
|
948
|
-
|
949
|
-
// otherwise, if element is not disabled
|
950
|
-
else if (!$element.attr('disabled')) {
|
951
|
-
|
952
|
-
// inject the date picker into the designated container element
|
953
|
-
plugin.settings.always_visible.append(datepicker);
|
954
|
-
|
955
|
-
// and make it visible right away
|
956
|
-
plugin.show();
|
957
|
-
|
958
|
-
}
|
959
|
-
|
960
|
-
// add the mouseover/mousevents to all to the date picker's cells
|
961
|
-
// except those that are not selectable
|
962
|
-
datepicker.
|
963
|
-
delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)', 'mouseover', function() {
|
964
|
-
$(this).addClass('dp_hover');
|
965
|
-
}).
|
966
|
-
delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)', 'mouseout', function() {
|
967
|
-
$(this).removeClass('dp_hover');
|
968
|
-
});
|
969
|
-
|
970
|
-
// prevent text highlighting for the text in the header
|
971
|
-
// (for the case when user keeps clicking the "next" and "previous" buttons)
|
972
|
-
disable_text_select($('td', header));
|
973
|
-
|
974
|
-
// event for when clicking the "previous" button
|
975
|
-
$('.dp_previous', header).bind('click', function() {
|
976
|
-
|
977
|
-
// if button is not disabled
|
978
|
-
if (!$(this).hasClass('dp_blocked')) {
|
979
|
-
|
980
|
-
// if view is "months"
|
981
|
-
// decrement year by one
|
982
|
-
if (view == 'months') selected_year--;
|
983
|
-
|
984
|
-
// if view is "years"
|
985
|
-
// decrement years by 12
|
986
|
-
else if (view == 'years') selected_year -= 12;
|
987
|
-
|
988
|
-
// if view is "days"
|
989
|
-
// decrement the month and
|
990
|
-
// if month is out of range
|
991
|
-
else if (--selected_month < 0) {
|
992
|
-
|
993
|
-
// go to the last month of the previous year
|
994
|
-
selected_month = 11;
|
995
|
-
selected_year--;
|
996
|
-
|
997
|
-
}
|
998
|
-
|
999
|
-
// generate the appropriate view
|
1000
|
-
manage_views();
|
1001
|
-
|
1002
|
-
}
|
1003
|
-
|
1004
|
-
});
|
1005
|
-
|
1006
|
-
// attach a click event to the caption in header
|
1007
|
-
$('.dp_caption', header).bind('click', function() {
|
1008
|
-
|
1009
|
-
// if current view is "days", take the user to the next view, depending on the format
|
1010
|
-
if (view == 'days') view = ($.inArray('months', views) > -1 ? 'months' : ($.inArray('years', views) > -1 ? 'years' : 'days'));
|
1011
|
-
|
1012
|
-
// if current view is "months", take the user to the next view, depending on the format
|
1013
|
-
else if (view == 'months') view = ($.inArray('years', views) > -1 ? 'years' : ($.inArray('days', views) > -1 ? 'days' : 'months'));
|
1014
|
-
|
1015
|
-
// if current view is "years", take the user to the next view, depending on the format
|
1016
|
-
else view = ($.inArray('days', views) > -1 ? 'days' : ($.inArray('months', views) > -1 ? 'months' : 'years'));
|
1017
|
-
|
1018
|
-
// generate the appropriate view
|
1019
|
-
manage_views();
|
1020
|
-
|
1021
|
-
});
|
1022
|
-
|
1023
|
-
// event for when clicking the "next" button
|
1024
|
-
$('.dp_next', header).bind('click', function() {
|
1025
|
-
|
1026
|
-
// if button is not disabled
|
1027
|
-
if (!$(this).hasClass('dp_blocked')) {
|
1028
|
-
|
1029
|
-
// if view is "months"
|
1030
|
-
// increment year by 1
|
1031
|
-
if (view == 'months') selected_year++;
|
1032
|
-
|
1033
|
-
// if view is "years"
|
1034
|
-
// increment years by 12
|
1035
|
-
else if (view == 'years') selected_year += 12;
|
1036
|
-
|
1037
|
-
// if view is "days"
|
1038
|
-
// increment the month and
|
1039
|
-
// if month is out of range
|
1040
|
-
else if (++selected_month == 12) {
|
1041
|
-
|
1042
|
-
// go to the first month of the next year
|
1043
|
-
selected_month = 0;
|
1044
|
-
selected_year++;
|
1045
|
-
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
// generate the appropriate view
|
1049
|
-
manage_views();
|
1050
|
-
|
1051
|
-
}
|
1052
|
-
|
1053
|
-
});
|
1054
|
-
|
1055
|
-
// attach a click event for the cells in the day picker
|
1056
|
-
daypicker.delegate('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)', 'click', function() {
|
1057
|
-
|
1058
|
-
// if other months are selectable and currently clicked cell contains a class with the cell's date
|
1059
|
-
if (plugin.settings.select_other_months && null !== (matches = $(this).attr('class').match(/date\_([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/)))
|
1060
|
-
|
1061
|
-
// use the stored date
|
1062
|
-
select_date(matches[1], matches[2], matches[3], 'days', $(this));
|
1063
|
-
|
1064
|
-
// put selected date in the element the plugin is attached to, and hide the date picker
|
1065
|
-
else select_date(selected_year, selected_month, to_int($(this).html()), 'days', $(this));
|
1066
|
-
|
1067
|
-
});
|
1068
|
-
|
1069
|
-
// attach a click event for the cells in the month picker
|
1070
|
-
monthpicker.delegate('td:not(.dp_disabled)', 'click', function() {
|
1071
|
-
|
1072
|
-
// get the month we've clicked on
|
1073
|
-
var matches = $(this).attr('class').match(/dp\_month\_([0-9]+)/);
|
1074
|
-
|
1075
|
-
// set the selected month
|
1076
|
-
selected_month = to_int(matches[1]);
|
1077
|
-
|
1078
|
-
// if user can select only years and months
|
1079
|
-
if ($.inArray('days', views) == -1)
|
1080
|
-
|
1081
|
-
// put selected date in the element the plugin is attached to, and hide the date picker
|
1082
|
-
select_date(selected_year, selected_month, 1, 'months', $(this));
|
1083
|
-
|
1084
|
-
else {
|
1085
|
-
|
1086
|
-
// direct the user to the "days" view
|
1087
|
-
view = 'days';
|
1088
|
-
|
1089
|
-
// if date picker is always visible
|
1090
|
-
// empty the value in the text box the date picker is attached to
|
1091
|
-
if (plugin.settings.always_visible) $element.val('');
|
1092
|
-
|
1093
|
-
// generate the appropriate view
|
1094
|
-
manage_views();
|
1095
|
-
|
1096
|
-
}
|
1097
|
-
|
1098
|
-
});
|
1099
|
-
|
1100
|
-
// attach a click event for the cells in the year picker
|
1101
|
-
yearpicker.delegate('td:not(.dp_disabled)', 'click', function() {
|
1102
|
-
|
1103
|
-
// set the selected year
|
1104
|
-
selected_year = to_int($(this).html());
|
1105
|
-
|
1106
|
-
// if user can select only years
|
1107
|
-
if ($.inArray('months', views) == -1)
|
1108
|
-
|
1109
|
-
// put selected date in the element the plugin is attached to, and hide the date picker
|
1110
|
-
select_date(selected_year, 1, 1, 'years', $(this));
|
1111
|
-
|
1112
|
-
else {
|
1113
|
-
|
1114
|
-
// direct the user to the "months" view
|
1115
|
-
view = 'months';
|
1116
|
-
|
1117
|
-
// if date picker is always visible
|
1118
|
-
// empty the value in the text box the date picker is attached to
|
1119
|
-
if (plugin.settings.always_visible) $element.val('');
|
1120
|
-
|
1121
|
-
// generate the appropriate view
|
1122
|
-
manage_views();
|
1123
|
-
|
1124
|
-
}
|
1125
|
-
|
1126
|
-
});
|
1127
|
-
|
1128
|
-
// function to execute when the "Today" button is clicked
|
1129
|
-
$(selecttoday).bind('click', function(e) {
|
1130
|
-
|
1131
|
-
e.preventDefault();
|
1132
|
-
|
1133
|
-
// select the current date
|
1134
|
-
select_date(current_system_year, current_system_month, current_system_day, 'days', $('.dp_current', daypicker));
|
1135
|
-
|
1136
|
-
// if date picker is always visible
|
1137
|
-
if (plugin.settings.always_visible)
|
1138
|
-
|
1139
|
-
// repaint the datepicker so it centers on the currently selected date
|
1140
|
-
plugin.show();
|
1141
|
-
|
1142
|
-
// hide the date picker
|
1143
|
-
plugin.hide();
|
1144
|
-
|
1145
|
-
});
|
1146
|
-
|
1147
|
-
// function to execute when the "Clear" button is clicked
|
1148
|
-
$(cleardate).bind('click', function(e) {
|
1149
|
-
|
1150
|
-
e.preventDefault();
|
1151
|
-
|
1152
|
-
// clear the element's value
|
1153
|
-
$element.val('');
|
1154
|
-
|
1155
|
-
// if date picker is not always visible
|
1156
|
-
if (!plugin.settings.always_visible) {
|
1157
|
-
|
1158
|
-
// reset these values
|
1159
|
-
default_day = null; default_month = null; default_year = null; selected_month = null; selected_year = null;
|
1160
|
-
|
1161
|
-
}
|
1162
|
-
|
1163
|
-
// hide the date picker
|
1164
|
-
plugin.hide();
|
1165
|
-
|
1166
|
-
// if a callback function exists for when clearing a date
|
1167
|
-
if (plugin.settings.onClear && typeof plugin.settings.onClear == 'function')
|
1168
|
-
|
1169
|
-
// execute the callback function and pass as argument the element the plugin is attached to
|
1170
|
-
plugin.settings.onClear($element);
|
1171
|
-
|
1172
|
-
});
|
1173
|
-
|
1174
|
-
// if date picker is not always visible
|
1175
|
-
if (!plugin.settings.always_visible)
|
1176
|
-
|
1177
|
-
// bind some events to the document
|
1178
|
-
$(document).bind({
|
1179
|
-
|
1180
|
-
//whenever anything is clicked on the page or a key is pressed
|
1181
|
-
'mousedown': _mousedown,
|
1182
|
-
'keyup': _keyup
|
1183
|
-
|
1184
|
-
});
|
1185
|
-
|
1186
|
-
// last thing is to pre-render some of the date picker right away
|
1187
|
-
manage_views();
|
1188
|
-
|
1189
|
-
};
|
1190
|
-
|
1191
|
-
/**
|
1192
|
-
* Destroys the date picker.
|
1193
|
-
*
|
1194
|
-
* @return void
|
1195
|
-
*/
|
1196
|
-
plugin.destroy = function() {
|
1197
|
-
|
1198
|
-
// remove the attached icon (if it exists)...
|
1199
|
-
if (undefined !== plugin.icon) plugin.icon.remove();
|
1200
|
-
|
1201
|
-
// ...and the calendar
|
1202
|
-
plugin.datepicker.remove();
|
1203
|
-
|
1204
|
-
// remove associated event handlers from the document
|
1205
|
-
$(document).unbind('keyup', _keyup);
|
1206
|
-
$(document).unbind('mousedown', _mousedown);
|
1207
|
-
$(window).unbind('resize', _resize);
|
1208
|
-
|
1209
|
-
// remove association with the element
|
1210
|
-
$element.removeData('Zebra_DatePicker');
|
1211
|
-
|
1212
|
-
// completely delete object
|
1213
|
-
delete plugin;
|
1214
|
-
|
1215
|
-
};
|
1216
|
-
|
1217
|
-
/**
|
1218
|
-
* Hides the date picker.
|
1219
|
-
*
|
1220
|
-
* @return void
|
1221
|
-
*/
|
1222
|
-
plugin.hide = function() {
|
1223
|
-
|
1224
|
-
// if date picker is not always visible
|
1225
|
-
if (!plugin.settings.always_visible) {
|
1226
|
-
|
1227
|
-
// hide the iFrameShim in Internet Explorer 6
|
1228
|
-
iframeShim('hide');
|
1229
|
-
|
1230
|
-
// hide the date picker
|
1231
|
-
datepicker.hide();
|
1232
|
-
|
1233
|
-
}
|
1234
|
-
|
1235
|
-
};
|
1236
|
-
|
1237
|
-
/**
|
1238
|
-
* Shows the date picker.
|
1239
|
-
*
|
1240
|
-
* @return void
|
1241
|
-
*/
|
1242
|
-
plugin.show = function() {
|
1243
|
-
|
1244
|
-
// always show the view defined in settings
|
1245
|
-
view = plugin.settings.view;
|
1246
|
-
|
1247
|
-
// get the default date, from the element, and check if it represents a valid date, according to the required format
|
1248
|
-
var default_date = check_date($element.val() || (plugin.settings.start_date ? plugin.settings.start_date : ''));
|
1249
|
-
|
1250
|
-
// if the value represents a valid date
|
1251
|
-
if (default_date) {
|
1252
|
-
|
1253
|
-
// extract the date parts
|
1254
|
-
// we'll use these to highlight the default date in the date picker and as starting point to
|
1255
|
-
// what year and month to start the date picker with
|
1256
|
-
// why separate values? because selected_* will change as user navigates within the date picker
|
1257
|
-
default_month = default_date.getMonth();
|
1258
|
-
selected_month = default_date.getMonth();
|
1259
|
-
default_year = default_date.getFullYear();
|
1260
|
-
selected_year = default_date.getFullYear();
|
1261
|
-
default_day = default_date.getDate();
|
1262
|
-
|
1263
|
-
// if the default date represents a disabled date
|
1264
|
-
if (is_disabled(default_year, default_month, default_day)) {
|
1265
|
-
|
1266
|
-
// clear the value of the parent element
|
1267
|
-
$element.val('');
|
1268
|
-
|
1269
|
-
// the calendar will start with the first selectable year/month
|
1270
|
-
selected_month = first_selectable_month;
|
1271
|
-
selected_year = first_selectable_year;
|
1272
|
-
|
1273
|
-
}
|
1274
|
-
|
1275
|
-
// if a default value is not available, or value does not represent a valid date
|
1276
|
-
} else {
|
1277
|
-
|
1278
|
-
// the calendar will start with the first selectable year/month
|
1279
|
-
selected_month = first_selectable_month;
|
1280
|
-
selected_year = first_selectable_year;
|
1281
|
-
|
1282
|
-
}
|
1283
|
-
|
1284
|
-
// generate the appropriate view
|
1285
|
-
manage_views();
|
1286
|
-
|
1287
|
-
// if date picker is not always visible and the calendar icon is visible
|
1288
|
-
if (!plugin.settings.always_visible) {
|
1289
|
-
|
1290
|
-
var
|
1291
|
-
|
1292
|
-
// get the date picker width and height
|
1293
|
-
datepicker_width = datepicker.outerWidth(),
|
1294
|
-
datepicker_height = datepicker.outerHeight(),
|
1295
|
-
|
1296
|
-
// compute the date picker's default left and top
|
1297
|
-
// this will be computed relative to the icon's top-right corner (if the calendar icon exists), or
|
1298
|
-
// relative to the element's top-right corner otherwise, to which the offsets given at initialization
|
1299
|
-
// are added/subtracted
|
1300
|
-
left = (undefined !== icon ? icon.offset().left + icon.outerWidth(true) : $element.offset().left + $element.outerWidth(true)) + plugin.settings.offset[0],
|
1301
|
-
top = (undefined !== icon ? icon.offset().top : $element.offset().top) - datepicker_height + plugin.settings.offset[1],
|
1302
|
-
|
1303
|
-
// get browser window's width and height
|
1304
|
-
window_width = $(window).width(),
|
1305
|
-
window_height = $(window).height(),
|
1306
|
-
|
1307
|
-
// get browser window's horizontal and vertical scroll offsets
|
1308
|
-
window_scroll_top = $(window).scrollTop(),
|
1309
|
-
window_scroll_left = $(window).scrollLeft();
|
1310
|
-
|
1311
|
-
// if date picker is outside the viewport, adjust its position so that it is visible
|
1312
|
-
if (left + datepicker_width > window_scroll_left + window_width) left = window_scroll_left + window_width - datepicker_width;
|
1313
|
-
if (left < window_scroll_left) left = window_scroll_left;
|
1314
|
-
if (top + datepicker_height > window_scroll_top + window_height) top = window_scroll_top + window_height - datepicker_height;
|
1315
|
-
if (top < window_scroll_top) top = window_scroll_top;
|
1316
|
-
|
1317
|
-
// make the date picker visible
|
1318
|
-
datepicker.css({
|
1319
|
-
'left': left,
|
1320
|
-
'top': top
|
1321
|
-
});
|
1322
|
-
|
1323
|
-
// fade-in the date picker
|
1324
|
-
// for Internet Explorer < 9 show the date picker instantly or fading alters the font's weight
|
1325
|
-
datepicker.fadeIn(browser.name == 'explorer' && browser.version < 9 ? 0 : 150, 'linear');
|
1326
|
-
|
1327
|
-
// show the iFrameShim in Internet Explorer 6
|
1328
|
-
iframeShim();
|
1329
|
-
|
1330
|
-
// if date picker is always visible, show it
|
1331
|
-
} else datepicker.show();
|
1332
|
-
|
1333
|
-
};
|
1334
|
-
|
1335
|
-
/**
|
1336
|
-
* Updates the configuration options given as argument
|
1337
|
-
*
|
1338
|
-
* @param object values An object containing any number of configuration options to be updated
|
1339
|
-
*
|
1340
|
-
* @return void
|
1341
|
-
*/
|
1342
|
-
plugin.update = function(values) {
|
1343
|
-
|
1344
|
-
// if original direction not saved, save it now
|
1345
|
-
if (plugin.original_direction) plugin.original_direction = plugin.direction;
|
1346
|
-
|
1347
|
-
// update configuration options
|
1348
|
-
plugin.settings = $.extend(plugin.settings, values);
|
1349
|
-
|
1350
|
-
// reinitialize the object with the new options
|
1351
|
-
init(true);
|
1352
|
-
|
1353
|
-
};
|
1354
|
-
|
1355
|
-
/**
|
1356
|
-
* Checks if a string represents a valid date according to the format defined by the "format" property.
|
1357
|
-
*
|
1358
|
-
* @param string str_date A string representing a date, formatted accordingly to the "format" property.
|
1359
|
-
* For example, if "format" is "Y-m-d" the string should look like "2011-06-01"
|
1360
|
-
*
|
1361
|
-
* @return mixed Returns a JavaScript Date object if string represents a valid date according
|
1362
|
-
* formatted according to the "format" property, or FALSE otherwise.
|
1363
|
-
*
|
1364
|
-
* @access private
|
1365
|
-
*/
|
1366
|
-
var check_date = function(str_date) {
|
1367
|
-
|
1368
|
-
// treat argument as a string
|
1369
|
-
str_date += '';
|
1370
|
-
|
1371
|
-
// if value is given
|
1372
|
-
if ($.trim(str_date) !== '') {
|
1373
|
-
|
1374
|
-
var
|
1375
|
-
|
1376
|
-
// prepare the format by removing white space from it
|
1377
|
-
// and also escape characters that could have special meaning in a regular expression
|
1378
|
-
format = escape_regexp(plugin.settings.format),
|
1379
|
-
|
1380
|
-
// allowed characters in date's format
|
1381
|
-
format_chars = ['d','D','j','l','N','S','w','F','m','M','n','Y','y'],
|
1382
|
-
|
1383
|
-
// "matches" will contain the characters defining the date's format
|
1384
|
-
matches = [],
|
1385
|
-
|
1386
|
-
// "regexp" will contain the regular expression built for each of the characters used in the date's format
|
1387
|
-
regexp = [],
|
1388
|
-
|
1389
|
-
// "position" will contain the position of the caracter found in the date's format
|
1390
|
-
position = null,
|
1391
|
-
|
1392
|
-
// "segments" will contain the matches of the regular expression
|
1393
|
-
segments = null;
|
1394
|
-
|
1395
|
-
// iterate through the allowed characters in date's format
|
1396
|
-
for (var i = 0; i < format_chars.length; i++)
|
1397
|
-
|
1398
|
-
// if character is found in the date's format
|
1399
|
-
if ((position = format.indexOf(format_chars[i])) > -1)
|
1400
|
-
|
1401
|
-
// save it, alongside the character's position
|
1402
|
-
matches.push({character: format_chars[i], position: position});
|
1403
|
-
|
1404
|
-
// sort characters defining the date's format based on their position, ascending
|
1405
|
-
matches.sort(function(a, b){ return a.position - b.position; });
|
1406
|
-
|
1407
|
-
// iterate through the characters defining the date's format
|
1408
|
-
$.each(matches, function(index, match) {
|
1409
|
-
|
1410
|
-
// add to the array of regular expressions, based on the character
|
1411
|
-
switch (match.character) {
|
1412
|
-
|
1413
|
-
case 'd': regexp.push('0[1-9]|[12][0-9]|3[01]'); break;
|
1414
|
-
case 'D': regexp.push('[a-z]{3}'); break;
|
1415
|
-
case 'j': regexp.push('[1-9]|[12][0-9]|3[01]'); break;
|
1416
|
-
case 'l': regexp.push('[a-z]+'); break;
|
1417
|
-
case 'N': regexp.push('[1-7]'); break;
|
1418
|
-
case 'S': regexp.push('st|nd|rd|th'); break;
|
1419
|
-
case 'w': regexp.push('[0-6]'); break;
|
1420
|
-
case 'F': regexp.push('[a-z]+'); break;
|
1421
|
-
case 'm': regexp.push('0[1-9]|1[012]+'); break;
|
1422
|
-
case 'M': regexp.push('[a-z]{3}'); break;
|
1423
|
-
case 'n': regexp.push('[1-9]|1[012]'); break;
|
1424
|
-
case 'Y': regexp.push('[0-9]{4}'); break;
|
1425
|
-
case 'y': regexp.push('[0-9]{2}'); break;
|
1426
|
-
|
1427
|
-
}
|
1428
|
-
|
1429
|
-
});
|
1430
|
-
|
1431
|
-
// if we have an array of regular expressions
|
1432
|
-
if (regexp.length) {
|
1433
|
-
|
1434
|
-
// we will replace characters in the date's format in reversed order
|
1435
|
-
matches.reverse();
|
1436
|
-
|
1437
|
-
// iterate through the characters in date's format
|
1438
|
-
$.each(matches, function(index, match) {
|
1439
|
-
|
1440
|
-
// replace each character with the appropriate regular expression
|
1441
|
-
format = format.replace(match.character, '(' + regexp[regexp.length - index - 1] + ')');
|
1442
|
-
|
1443
|
-
});
|
1444
|
-
|
1445
|
-
// the final regular expression
|
1446
|
-
regexp = new RegExp('^' + format + '$', 'ig');
|
1447
|
-
|
1448
|
-
// if regular expression was matched
|
1449
|
-
if ((segments = regexp.exec(str_date))) {
|
1450
|
-
|
1451
|
-
// check if date is a valid date (i.e. there's no February 31)
|
1452
|
-
|
1453
|
-
var tmpdate = new Date(),
|
1454
|
-
original_day = tmpdate.getDate(),
|
1455
|
-
original_month = tmpdate.getMonth() + 1,
|
1456
|
-
original_year = tmpdate.getFullYear(),
|
1457
|
-
english_days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
|
1458
|
-
english_months = ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
1459
|
-
iterable,
|
1460
|
-
|
1461
|
-
// by default, we assume the date is valid
|
1462
|
-
valid = true;
|
1463
|
-
|
1464
|
-
// reverse back the characters in the date's format
|
1465
|
-
matches.reverse();
|
1466
|
-
|
1467
|
-
// iterate through the characters in the date's format
|
1468
|
-
$.each(matches, function(index, match) {
|
1469
|
-
|
1470
|
-
// if the date is not valid, don't look further
|
1471
|
-
if (!valid) return true;
|
1472
|
-
|
1473
|
-
// based on the character
|
1474
|
-
switch (match.character) {
|
1475
|
-
|
1476
|
-
case 'm':
|
1477
|
-
case 'n':
|
1478
|
-
|
1479
|
-
// extract the month from the value entered by the user
|
1480
|
-
original_month = to_int(segments[index + 1]);
|
1481
|
-
|
1482
|
-
break;
|
1483
|
-
|
1484
|
-
case 'd':
|
1485
|
-
case 'j':
|
1486
|
-
|
1487
|
-
// extract the day from the value entered by the user
|
1488
|
-
original_day = to_int(segments[index + 1]);
|
1489
|
-
|
1490
|
-
break;
|
1491
|
-
|
1492
|
-
case 'D':
|
1493
|
-
case 'l':
|
1494
|
-
case 'F':
|
1495
|
-
case 'M':
|
1496
|
-
|
1497
|
-
// if day is given as day name, we'll check against the names in the used language
|
1498
|
-
if (match.character == 'D' || match.character == 'l') iterable = plugin.settings.days;
|
1499
|
-
|
1500
|
-
// if month is given as month name, we'll check against the names in the used language
|
1501
|
-
else iterable = plugin.settings.months;
|
1502
|
-
|
1503
|
-
// by default, we assume the day or month was not entered correctly
|
1504
|
-
valid = false;
|
1505
|
-
|
1506
|
-
// iterate through the month/days in the used language
|
1507
|
-
$.each(iterable, function(key, value) {
|
1508
|
-
|
1509
|
-
// if month/day was entered correctly, don't look further
|
1510
|
-
if (valid) return true;
|
1511
|
-
|
1512
|
-
// if month/day was entered correctly
|
1513
|
-
if (segments[index + 1].toLowerCase() == value.substring(0, (match.character == 'D' || match.character == 'M' ? 3 : value.length)).toLowerCase()) {
|
1514
|
-
|
1515
|
-
// extract the day/month from the value entered by the user
|
1516
|
-
switch (match.character) {
|
1517
|
-
|
1518
|
-
case 'D': segments[index + 1] = english_days[key].substring(0, 3); break;
|
1519
|
-
case 'l': segments[index + 1] = english_days[key]; break;
|
1520
|
-
case 'F': segments[index + 1] = english_months[key]; original_month = key + 1; break;
|
1521
|
-
case 'M': segments[index + 1] = english_months[key].substring(0, 3); original_month = key + 1; break;
|
1522
|
-
|
1523
|
-
}
|
1524
|
-
|
1525
|
-
// day/month value is valid
|
1526
|
-
valid = true;
|
1527
|
-
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
});
|
1531
|
-
|
1532
|
-
break;
|
1533
|
-
|
1534
|
-
case 'Y':
|
1535
|
-
|
1536
|
-
// extract the year from the value entered by the user
|
1537
|
-
original_year = to_int(segments[index + 1]);
|
1538
|
-
|
1539
|
-
break;
|
1540
|
-
|
1541
|
-
case 'y':
|
1542
|
-
|
1543
|
-
// extract the year from the value entered by the user
|
1544
|
-
original_year = '19' + to_int(segments[index + 1]);
|
1545
|
-
|
1546
|
-
break;
|
1547
|
-
|
1548
|
-
}
|
1549
|
-
});
|
1550
|
-
|
1551
|
-
// if everything is ok so far
|
1552
|
-
if (valid) {
|
1553
|
-
|
1554
|
-
// generate a Date object using the values entered by the user
|
1555
|
-
// (handle also the case when original_month and/or original_day are undefined - i.e date format is "Y-m" or "Y")
|
1556
|
-
var date = new Date(original_year, (original_month || 1) - 1, original_day || 1);
|
1557
|
-
|
1558
|
-
// if, after that, the date is the same as the date entered by the user
|
1559
|
-
if (date.getFullYear() == original_year && date.getDate() == (original_day || 1) && date.getMonth() == ((original_month || 1) - 1))
|
1560
|
-
|
1561
|
-
// return the date as JavaScript date object
|
1562
|
-
return date;
|
1563
|
-
|
1564
|
-
}
|
1565
|
-
|
1566
|
-
}
|
1567
|
-
|
1568
|
-
}
|
1569
|
-
|
1570
|
-
// if script gets this far, return false as something must've went wrong
|
1571
|
-
return false;
|
1572
|
-
|
1573
|
-
}
|
1574
|
-
|
1575
|
-
};
|
1576
|
-
|
1577
|
-
/**
|
1578
|
-
* Prevents the possibility of selecting text on a given element. Used on the "previous" and "next" buttons
|
1579
|
-
* where text might get accidentally selected when user quickly clicks on the buttons.
|
1580
|
-
*
|
1581
|
-
* Code by http://chris-barr.com/index.php/entry/disable_text_selection_with_jquery/
|
1582
|
-
*
|
1583
|
-
* @param jQuery Element el A jQuery element on which to prevents text selection.
|
1584
|
-
*
|
1585
|
-
* @return void
|
1586
|
-
*
|
1587
|
-
* @access private
|
1588
|
-
*/
|
1589
|
-
var disable_text_select = function(el) {
|
1590
|
-
|
1591
|
-
// if browser is Firefox
|
1592
|
-
if (browser.name == 'firefox') el.css('MozUserSelect', 'none');
|
1593
|
-
|
1594
|
-
// if browser is Internet Explorer
|
1595
|
-
else if (browser.name == 'explorer') el.bind('selectstart', function() { return false; });
|
1596
|
-
|
1597
|
-
// for the other browsers
|
1598
|
-
else el.mousedown(function() { return false; });
|
1599
|
-
|
1600
|
-
};
|
1601
|
-
|
1602
|
-
/**
|
1603
|
-
* Escapes special characters in a string, preparing it for use in a regular expression.
|
1604
|
-
*
|
1605
|
-
* @param string str The string in which special characters should be escaped.
|
1606
|
-
*
|
1607
|
-
* @return string Returns the string with escaped special characters.
|
1608
|
-
*
|
1609
|
-
* @access private
|
1610
|
-
*/
|
1611
|
-
var escape_regexp = function(str) {
|
1612
|
-
|
1613
|
-
// return string with special characters escaped
|
1614
|
-
return str.replace(/([-.,*+?^${}()|[\]\/\\])/g, '\\$1');
|
1615
|
-
|
1616
|
-
};
|
1617
|
-
|
1618
|
-
/**
|
1619
|
-
* Formats a JavaScript date object to the format specified by the "format" property.
|
1620
|
-
* Code taken from http://electricprism.com/aeron/calendar/
|
1621
|
-
*
|
1622
|
-
* @param date date A valid JavaScript date object
|
1623
|
-
*
|
1624
|
-
* @return string Returns a string containing the formatted date
|
1625
|
-
*
|
1626
|
-
* @access private
|
1627
|
-
*/
|
1628
|
-
var format = function(date) {
|
1629
|
-
|
1630
|
-
var result = '',
|
1631
|
-
|
1632
|
-
// extract parts of the date:
|
1633
|
-
// day number, 1 - 31
|
1634
|
-
j = date.getDate(),
|
1635
|
-
|
1636
|
-
// day of the week, 0 - 6, Sunday - Saturday
|
1637
|
-
w = date.getDay(),
|
1638
|
-
|
1639
|
-
// the name of the day of the week Sunday - Saturday
|
1640
|
-
l = plugin.settings.days[w],
|
1641
|
-
|
1642
|
-
// the month number, 1 - 12
|
1643
|
-
n = date.getMonth() + 1,
|
1644
|
-
|
1645
|
-
// the month name, January - December
|
1646
|
-
f = plugin.settings.months[n - 1],
|
1647
|
-
|
1648
|
-
// the year (as a string)
|
1649
|
-
y = date.getFullYear() + '';
|
1650
|
-
|
1651
|
-
// iterate through the characters in the format
|
1652
|
-
for (var i = 0; i < plugin.settings.format.length; i++) {
|
1653
|
-
|
1654
|
-
// extract the current character
|
1655
|
-
var chr = plugin.settings.format.charAt(i);
|
1656
|
-
|
1657
|
-
// see what character it is
|
1658
|
-
switch(chr) {
|
1659
|
-
|
1660
|
-
// year as two digits
|
1661
|
-
case 'y': y = y.substr(2);
|
1662
|
-
|
1663
|
-
// year as four digits
|
1664
|
-
case 'Y': result += y; break;
|
1665
|
-
|
1666
|
-
// month number, prefixed with 0
|
1667
|
-
case 'm': n = str_pad(n, 2);
|
1668
|
-
|
1669
|
-
// month number, not prefixed with 0
|
1670
|
-
case 'n': result += n; break;
|
1671
|
-
|
1672
|
-
// month name, three letters
|
1673
|
-
case 'M': f = ($.isArray(plugin.settings.months_abbr) && undefined !== plugin.settings.months_abbr[n - 1] ? plugin.settings.months_abbr[n - 1] : plugin.settings.months[n - 1].substr(0, 3));
|
1674
|
-
|
1675
|
-
// full month name
|
1676
|
-
case 'F': result += f; break;
|
1677
|
-
|
1678
|
-
// day number, prefixed with 0
|
1679
|
-
case 'd': j = str_pad(j, 2);
|
1680
|
-
|
1681
|
-
// day number not prefixed with 0
|
1682
|
-
case 'j': result += j; break;
|
1683
|
-
|
1684
|
-
// day name, three letters
|
1685
|
-
case 'D': l = ($.isArray(plugin.settings.days_abbr) && undefined !== plugin.settings.days_abbr[w] ? plugin.settings.days_abbr[w] : plugin.settings.days[w].substr(0, 3));
|
1686
|
-
|
1687
|
-
// full day name
|
1688
|
-
case 'l': result += l; break;
|
1689
|
-
|
1690
|
-
// ISO-8601 numeric representation of the day of the week, 1 - 7
|
1691
|
-
case 'N': w++;
|
1692
|
-
|
1693
|
-
// day of the week, 0 - 6
|
1694
|
-
case 'w': result += w; break;
|
1695
|
-
|
1696
|
-
// English ordinal suffix for the day of the month, 2 characters
|
1697
|
-
// (st, nd, rd or th (works well with j))
|
1698
|
-
case 'S':
|
1699
|
-
|
1700
|
-
if (j % 10 == 1 && j != '11') result += 'st';
|
1701
|
-
|
1702
|
-
else if (j % 10 == 2 && j != '12') result += 'nd';
|
1703
|
-
|
1704
|
-
else if (j % 10 == 3 && j != '13') result += 'rd';
|
1705
|
-
|
1706
|
-
else result += 'th';
|
1707
|
-
|
1708
|
-
break;
|
1709
|
-
|
1710
|
-
// this is probably the separator
|
1711
|
-
default: result += chr;
|
1712
|
-
|
1713
|
-
}
|
1714
|
-
|
1715
|
-
}
|
1716
|
-
|
1717
|
-
// return formated date
|
1718
|
-
return result;
|
1719
|
-
|
1720
|
-
};
|
1721
|
-
|
1722
|
-
/**
|
1723
|
-
* Generates the day picker view, and displays it
|
1724
|
-
*
|
1725
|
-
* @return void
|
1726
|
-
*
|
1727
|
-
* @access private
|
1728
|
-
*/
|
1729
|
-
var generate_daypicker = function() {
|
1730
|
-
|
1731
|
-
var
|
1732
|
-
|
1733
|
-
// get the number of days in the selected month
|
1734
|
-
days_in_month = new Date(selected_year, selected_month + 1, 0).getDate(),
|
1735
|
-
|
1736
|
-
// get the selected month's starting day (from 0 to 6)
|
1737
|
-
first_day = new Date(selected_year, selected_month, 1).getDay(),
|
1738
|
-
|
1739
|
-
// how many days are there in the previous month
|
1740
|
-
days_in_previous_month = new Date(selected_year, selected_month, 0).getDate(),
|
1741
|
-
|
1742
|
-
// how many days are there to be shown from the previous month
|
1743
|
-
days_from_previous_month = first_day - plugin.settings.first_day_of_week;
|
1744
|
-
|
1745
|
-
// the final value of how many days are there to be shown from the previous month
|
1746
|
-
days_from_previous_month = days_from_previous_month < 0 ? 7 + days_from_previous_month : days_from_previous_month;
|
1747
|
-
|
1748
|
-
// manage header caption and enable/disable navigation buttons if necessary
|
1749
|
-
manage_header(plugin.settings.months[selected_month] + ', ' + selected_year);
|
1750
|
-
|
1751
|
-
// start generating the HTML
|
1752
|
-
var html = '<tr>';
|
1753
|
-
|
1754
|
-
// if a column featuring the number of the week is to be shown
|
1755
|
-
if (plugin.settings.show_week_number)
|
1756
|
-
|
1757
|
-
// column title
|
1758
|
-
html += '<th>' + plugin.settings.show_week_number + '</th>';
|
1759
|
-
|
1760
|
-
// name of week days
|
1761
|
-
// show the abbreviated day names (or only the first two letters of the full name if no abbreviations are specified)
|
1762
|
-
// and also, take in account the value of the "first_day_of_week" property
|
1763
|
-
for (var i = 0; i < 7; i++)
|
1764
|
-
|
1765
|
-
html += '<th>' + ($.isArray(plugin.settings.days_abbr) && undefined !== plugin.settings.days_abbr[(plugin.settings.first_day_of_week + i) % 7] ? plugin.settings.days_abbr[(plugin.settings.first_day_of_week + i) % 7] : plugin.settings.days[(plugin.settings.first_day_of_week + i) % 7].substr(0, 2)) + '</th>';
|
1766
|
-
|
1767
|
-
html += '</tr><tr>';
|
1768
|
-
|
1769
|
-
// the calendar shows a total of 42 days
|
1770
|
-
for (i = 0; i < 42; i++) {
|
1771
|
-
|
1772
|
-
// seven days per row
|
1773
|
-
if (i > 0 && i % 7 === 0) html += '</tr><tr>';
|
1774
|
-
|
1775
|
-
// if week number is to be shown
|
1776
|
-
if (i % 7 === 0 && plugin.settings.show_week_number)
|
1777
|
-
|
1778
|
-
// show ISO 8601 week number
|
1779
|
-
html += '<td class="dp_week_number">' + getWeekNumber(new Date(selected_year, selected_month, (i - days_from_previous_month + 1))) + '</td>';
|
1780
|
-
|
1781
|
-
// the number of the day in month
|
1782
|
-
var day = (i - days_from_previous_month + 1);
|
1783
|
-
|
1784
|
-
// if dates in previous/next month can be selected, and this is one of those days
|
1785
|
-
if (plugin.settings.select_other_months && (i < days_from_previous_month || day > days_in_month)) {
|
1786
|
-
|
1787
|
-
// use the Date object to normalize the date
|
1788
|
-
// for example, 2011 05 33 will be transformed to 2011 06 02
|
1789
|
-
var real_date = new Date(selected_year, selected_month, day),
|
1790
|
-
real_year = real_date.getFullYear(),
|
1791
|
-
real_month = real_date.getMonth(),
|
1792
|
-
real_day = real_date.getDate();
|
1793
|
-
|
1794
|
-
// extract normalized date parts and merge them
|
1795
|
-
real_date = real_year + str_pad(real_month, 2) + str_pad(real_day, 2);
|
1796
|
-
|
1797
|
-
}
|
1798
|
-
|
1799
|
-
// if this is a day from the previous month
|
1800
|
-
if (i < days_from_previous_month)
|
1801
|
-
|
1802
|
-
html += '<td class="' + (plugin.settings.select_other_months && !is_disabled(real_year, real_month, real_day) ? 'dp_not_in_month_selectable date_' + real_date : 'dp_not_in_month') + '">' + (plugin.settings.select_other_months || plugin.settings.show_other_months ? str_pad(days_in_previous_month - days_from_previous_month + i + 1, plugin.settings.zero_pad ? 2 : 0) : ' ') + '</td>';
|
1803
|
-
|
1804
|
-
// if this is a day from the next month
|
1805
|
-
else if (day > days_in_month)
|
1806
|
-
|
1807
|
-
html += '<td class="' + (plugin.settings.select_other_months && !is_disabled(real_year, real_month, real_day) ? 'dp_not_in_month_selectable date_' + real_date : 'dp_not_in_month') + '">' + (plugin.settings.select_other_months || plugin.settings.show_other_months ? str_pad(day - days_in_month, plugin.settings.zero_pad ? 2 : 0) : ' ') + '</td>';
|
1808
|
-
|
1809
|
-
// if this is a day from the current month
|
1810
|
-
else {
|
1811
|
-
|
1812
|
-
var
|
1813
|
-
|
1814
|
-
// get the week day (0 to 6, Sunday to Saturday)
|
1815
|
-
weekday = (plugin.settings.first_day_of_week + i) % 7,
|
1816
|
-
|
1817
|
-
class_name = '';
|
1818
|
-
|
1819
|
-
// if date needs to be disabled
|
1820
|
-
if (is_disabled(selected_year, selected_month, day)) {
|
1821
|
-
|
1822
|
-
// if day is in weekend
|
1823
|
-
if ($.inArray(weekday, plugin.settings.weekend_days) > -1) class_name = 'dp_weekend_disabled';
|
1824
|
-
|
1825
|
-
// if work day
|
1826
|
-
else class_name += ' dp_disabled';
|
1827
|
-
|
1828
|
-
// highlight the current system date
|
1829
|
-
if (selected_month == current_system_month && selected_year == current_system_year && current_system_day == day) class_name += ' dp_disabled_current';
|
1830
|
-
|
1831
|
-
// if there are no restrictions
|
1832
|
-
} else {
|
1833
|
-
|
1834
|
-
// if day is in weekend
|
1835
|
-
if ($.inArray(weekday, plugin.settings.weekend_days) > -1) class_name = 'dp_weekend';
|
1836
|
-
|
1837
|
-
// highlight the currently selected date
|
1838
|
-
if (selected_month == default_month && selected_year == default_year && default_day == day) class_name += ' dp_selected';
|
1839
|
-
|
1840
|
-
// highlight the current system date
|
1841
|
-
if (selected_month == current_system_month && selected_year == current_system_year && current_system_day == day) class_name += ' dp_current';
|
1842
|
-
|
1843
|
-
}
|
1844
|
-
|
1845
|
-
// print the day of the month
|
1846
|
-
html += '<td' + (class_name !== '' ? ' class="' + $.trim(class_name) + '"' : '') + '>' + (plugin.settings.zero_pad ? str_pad(day, 2) : day) + '</td>';
|
1847
|
-
|
1848
|
-
}
|
1849
|
-
|
1850
|
-
}
|
1851
|
-
|
1852
|
-
// wrap up generating the day picker
|
1853
|
-
html += '</tr>';
|
1854
|
-
|
1855
|
-
// inject the day picker into the DOM
|
1856
|
-
daypicker.html($(html));
|
1857
|
-
|
1858
|
-
// if date picker is always visible
|
1859
|
-
if (plugin.settings.always_visible)
|
1860
|
-
|
1861
|
-
// cache all the cells
|
1862
|
-
// (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a date)
|
1863
|
-
daypicker_cells = $('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)', daypicker);
|
1864
|
-
|
1865
|
-
// make the day picker visible
|
1866
|
-
daypicker.show();
|
1867
|
-
|
1868
|
-
};
|
1869
|
-
|
1870
|
-
/**
|
1871
|
-
* Generates the month picker view, and displays it
|
1872
|
-
*
|
1873
|
-
* @return void
|
1874
|
-
*
|
1875
|
-
* @access private
|
1876
|
-
*/
|
1877
|
-
var generate_monthpicker = function() {
|
1878
|
-
|
1879
|
-
// manage header caption and enable/disable navigation buttons if necessary
|
1880
|
-
manage_header(selected_year);
|
1881
|
-
|
1882
|
-
// start generating the HTML
|
1883
|
-
var html = '<tr>';
|
1884
|
-
|
1885
|
-
// iterate through all the months
|
1886
|
-
for (var i = 0; i < 12; i++) {
|
1887
|
-
|
1888
|
-
// three month per row
|
1889
|
-
if (i > 0 && i % 3 === 0) html += '</tr><tr>';
|
1890
|
-
|
1891
|
-
var class_name = 'dp_month_' + i;
|
1892
|
-
|
1893
|
-
// if month needs to be disabled
|
1894
|
-
if (is_disabled(selected_year, i)) class_name += ' dp_disabled';
|
1895
|
-
|
1896
|
-
// else, if a date is already selected and this is that particular month, highlight it
|
1897
|
-
else if (default_month !== false && default_month == i) class_name += ' dp_selected';
|
1898
|
-
|
1899
|
-
// else, if this the current system month, highlight it
|
1900
|
-
else if (current_system_month == i && current_system_year == selected_year) class_name += ' dp_current';
|
1901
|
-
|
1902
|
-
// first three letters of the month's name
|
1903
|
-
html += '<td class="' + $.trim(class_name) + '">' + ($.isArray(plugin.settings.months_abbr) && undefined !== plugin.settings.months_abbr[i] ? plugin.settings.months_abbr[i] : plugin.settings.months[i].substr(0, 3)) + '</td>';
|
1904
|
-
|
1905
|
-
}
|
1906
|
-
|
1907
|
-
// wrap up
|
1908
|
-
html += '</tr>';
|
1909
|
-
|
1910
|
-
// inject into the DOM
|
1911
|
-
monthpicker.html($(html));
|
1912
|
-
|
1913
|
-
// if date picker is always visible
|
1914
|
-
if (plugin.settings.always_visible)
|
1915
|
-
|
1916
|
-
// cache all the cells
|
1917
|
-
// (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a month)
|
1918
|
-
monthpicker_cells = $('td:not(.dp_disabled)', monthpicker);
|
1919
|
-
|
1920
|
-
// make the month picker visible
|
1921
|
-
monthpicker.show();
|
1922
|
-
|
1923
|
-
};
|
1924
|
-
|
1925
|
-
/**
|
1926
|
-
* Generates the year picker view, and displays it
|
1927
|
-
*
|
1928
|
-
* @return void
|
1929
|
-
*
|
1930
|
-
* @access private
|
1931
|
-
*/
|
1932
|
-
var generate_yearpicker = function() {
|
1933
|
-
|
1934
|
-
// manage header caption and enable/disable navigation buttons if necessary
|
1935
|
-
manage_header(selected_year - 7 + ' - ' + (selected_year + 4));
|
1936
|
-
|
1937
|
-
// start generating the HTML
|
1938
|
-
var html = '<tr>';
|
1939
|
-
|
1940
|
-
// we're showing 9 years at a time, current year in the middle
|
1941
|
-
for (var i = 0; i < 12; i++) {
|
1942
|
-
|
1943
|
-
// three years per row
|
1944
|
-
if (i > 0 && i % 3 === 0) html += '</tr><tr>';
|
1945
|
-
|
1946
|
-
var class_name = '';
|
1947
|
-
|
1948
|
-
// if year needs to be disabled
|
1949
|
-
if (is_disabled(selected_year - 7 + i)) class_name += ' dp_disabled';
|
1950
|
-
|
1951
|
-
// else, if a date is already selected and this is that particular year, highlight it
|
1952
|
-
else if (default_year && default_year == selected_year - 7 + i) class_name += ' dp_selected';
|
1953
|
-
|
1954
|
-
// else, if this is the current system year, highlight it
|
1955
|
-
else if (current_system_year == (selected_year - 7 + i)) class_name += ' dp_current';
|
1956
|
-
|
1957
|
-
// first three letters of the month's name
|
1958
|
-
html += '<td' + ($.trim(class_name) !== '' ? ' class="' + $.trim(class_name) + '"' : '') + '>' + (selected_year - 7 + i) + '</td>';
|
1959
|
-
|
1960
|
-
}
|
1961
|
-
|
1962
|
-
// wrap up
|
1963
|
-
html += '</tr>';
|
1964
|
-
|
1965
|
-
// inject into the DOM
|
1966
|
-
yearpicker.html($(html));
|
1967
|
-
|
1968
|
-
// if date picker is always visible
|
1969
|
-
if (plugin.settings.always_visible)
|
1970
|
-
|
1971
|
-
// cache all the cells
|
1972
|
-
// (we need them so that we can easily remove the "dp_selected" class from all of them when user selects a year)
|
1973
|
-
yearpicker_cells = $('td:not(.dp_disabled)', yearpicker);
|
1974
|
-
|
1975
|
-
// make the year picker visible
|
1976
|
-
yearpicker.show();
|
1977
|
-
|
1978
|
-
};
|
1979
|
-
|
1980
|
-
/**
|
1981
|
-
* Generates an iFrame shim in Internet Explorer 6 so that the date picker appears above select boxes.
|
1982
|
-
*
|
1983
|
-
* @return void
|
1984
|
-
*
|
1985
|
-
* @access private
|
1986
|
-
*/
|
1987
|
-
var iframeShim = function(action) {
|
1988
|
-
|
1989
|
-
// this is necessary only if browser is Internet Explorer 6
|
1990
|
-
if (browser.name == 'explorer' && browser.version == 6) {
|
1991
|
-
|
1992
|
-
// if the iFrame was not yet created
|
1993
|
-
// "undefined" evaluates as FALSE
|
1994
|
-
if (!shim) {
|
1995
|
-
|
1996
|
-
// the iFrame has to have the element's zIndex minus 1
|
1997
|
-
var zIndex = to_int(datepicker.css('zIndex')) - 1;
|
1998
|
-
|
1999
|
-
// create the iFrame
|
2000
|
-
shim = jQuery('<iframe>', {
|
2001
|
-
'src': 'javascript:document.write("")',
|
2002
|
-
'scrolling': 'no',
|
2003
|
-
'frameborder': 0,
|
2004
|
-
'allowtransparency': 'true',
|
2005
|
-
css: {
|
2006
|
-
'zIndex': zIndex,
|
2007
|
-
'position': 'absolute',
|
2008
|
-
'top': -1000,
|
2009
|
-
'left': -1000,
|
2010
|
-
'width': datepicker.outerWidth(),
|
2011
|
-
'height': datepicker.outerHeight(),
|
2012
|
-
'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)',
|
2013
|
-
'display': 'none'
|
2014
|
-
}
|
2015
|
-
});
|
2016
|
-
|
2017
|
-
// inject iFrame into DOM
|
2018
|
-
$('body').append(shim);
|
2019
|
-
|
2020
|
-
}
|
2021
|
-
|
2022
|
-
// what do we need to do
|
2023
|
-
switch (action) {
|
2024
|
-
|
2025
|
-
// hide the iFrame?
|
2026
|
-
case 'hide':
|
2027
|
-
|
2028
|
-
// set the iFrame's display property to "none"
|
2029
|
-
shim.hide();
|
2030
|
-
|
2031
|
-
break;
|
2032
|
-
|
2033
|
-
// show the iFrame?
|
2034
|
-
default:
|
2035
|
-
|
2036
|
-
// get date picker top and left position
|
2037
|
-
var offset = datepicker.offset();
|
2038
|
-
|
2039
|
-
// position the iFrame shim right underneath the date picker
|
2040
|
-
// and set its display to "block"
|
2041
|
-
shim.css({
|
2042
|
-
'top': offset.top,
|
2043
|
-
'left': offset.left,
|
2044
|
-
'display': 'block'
|
2045
|
-
});
|
2046
|
-
|
2047
|
-
}
|
2048
|
-
|
2049
|
-
}
|
2050
|
-
|
2051
|
-
};
|
2052
|
-
|
2053
|
-
/**
|
2054
|
-
* Checks if, according to the restrictions of the calendar and/or the values defined by the "disabled_dates"
|
2055
|
-
* property, a day, a month or a year needs to be disabled.
|
2056
|
-
*
|
2057
|
-
* @param integer year The year to check
|
2058
|
-
* @param integer month The month to check
|
2059
|
-
* @param integer day The day to check
|
2060
|
-
*
|
2061
|
-
* @return boolean Returns TRUE if the given value is not disabled or FALSE otherwise
|
2062
|
-
*
|
2063
|
-
* @access private
|
2064
|
-
*/
|
2065
|
-
var is_disabled = function(year, month, day) {
|
2066
|
-
|
2067
|
-
// don't check bogus values
|
2068
|
-
if ((undefined === year || isNaN(year)) && (undefined === month || isNaN(month)) && (undefined === day || isNaN(day))) return false;
|
2069
|
-
|
2070
|
-
// if calendar has direction restrictions
|
2071
|
-
if (!(!$.isArray(plugin.settings.direction) && to_int(plugin.settings.direction) === 0)) {
|
2072
|
-
|
2073
|
-
var
|
2074
|
-
// normalize and merge arguments then transform the result to an integer
|
2075
|
-
now = to_int(str_concat(year, (typeof month != 'undefined' ? str_pad(month, 2) : ''), (typeof day != 'undefined' ? str_pad(day, 2) : ''))),
|
2076
|
-
|
2077
|
-
// get the length of the argument
|
2078
|
-
len = (now + '').length;
|
2079
|
-
|
2080
|
-
// if we're checking days
|
2081
|
-
if (len == 8 && (
|
2082
|
-
|
2083
|
-
// day is before the first selectable date
|
2084
|
-
(typeof start_date != 'undefined' && now < to_int(str_concat(first_selectable_year, str_pad(first_selectable_month, 2), str_pad(first_selectable_day, 2)))) ||
|
2085
|
-
|
2086
|
-
// or day is after the last selectable date
|
2087
|
-
(typeof end_date != 'undefined' && now > to_int(str_concat(last_selectable_year, str_pad(last_selectable_month, 2), str_pad(last_selectable_day, 2))))
|
2088
|
-
|
2089
|
-
// day needs to be disabled
|
2090
|
-
)) return true;
|
2091
|
-
|
2092
|
-
// if we're checking months
|
2093
|
-
else if (len == 6 && (
|
2094
|
-
|
2095
|
-
// month is before the first selectable month
|
2096
|
-
(typeof start_date != 'undefined' && now < to_int(str_concat(first_selectable_year, str_pad(first_selectable_month, 2)))) ||
|
2097
|
-
|
2098
|
-
// or day is after the last selectable date
|
2099
|
-
(typeof end_date != 'undefined' && now > to_int(str_concat(last_selectable_year, str_pad(last_selectable_month, 2))))
|
2100
|
-
|
2101
|
-
// month needs to be disabled
|
2102
|
-
)) return true;
|
2103
|
-
|
2104
|
-
// if we're checking years
|
2105
|
-
else if (len == 4 && (
|
2106
|
-
|
2107
|
-
// year is before the first selectable year
|
2108
|
-
(typeof start_date != 'undefined' && now < first_selectable_year) ||
|
2109
|
-
|
2110
|
-
// or day is after the last selectable date
|
2111
|
-
(typeof end_date != 'undefined' && now > last_selectable_year)
|
2112
|
-
|
2113
|
-
// year needs to be disabled
|
2114
|
-
)) return true;
|
2115
|
-
|
2116
|
-
}
|
2117
|
-
|
2118
|
-
// if month is given as argument, increment it (as JavaScript uses 0 for January, 1 for February...)
|
2119
|
-
if (typeof month != 'undefined') month = month + 1;
|
2120
|
-
|
2121
|
-
// by default, we assume the day/month/year is not enabled nor disabled
|
2122
|
-
var disabled = false, enabled = false;
|
2123
|
-
|
2124
|
-
// if there are rules for disabling dates
|
2125
|
-
if (disabled_dates)
|
2126
|
-
|
2127
|
-
// iterate through the rules for disabling dates
|
2128
|
-
$.each(disabled_dates, function() {
|
2129
|
-
|
2130
|
-
// if the date is to be disabled, don't look any further
|
2131
|
-
if (disabled) return;
|
2132
|
-
|
2133
|
-
var rule = this;
|
2134
|
-
|
2135
|
-
// if the rules apply for the current year
|
2136
|
-
if ($.inArray(year, rule[2]) > -1 || $.inArray('*', rule[2]) > -1)
|
2137
|
-
|
2138
|
-
// if the rules apply for the current month
|
2139
|
-
if ((typeof month != 'undefined' && $.inArray(month, rule[1]) > -1) || $.inArray('*', rule[1]) > -1)
|
2140
|
-
|
2141
|
-
// if the rules apply for the current day
|
2142
|
-
if ((typeof day != 'undefined' && $.inArray(day, rule[0]) > -1) || $.inArray('*', rule[0]) > -1) {
|
2143
|
-
|
2144
|
-
// if day is to be disabled whatever the day
|
2145
|
-
// don't look any further
|
2146
|
-
if (rule[3] == '*') return (disabled = true);
|
2147
|
-
|
2148
|
-
// get the weekday
|
2149
|
-
var weekday = new Date(year, month - 1, day).getDay();
|
2150
|
-
|
2151
|
-
// if weekday is to be disabled
|
2152
|
-
// don't look any further
|
2153
|
-
if ($.inArray(weekday, rule[3]) > -1) return (disabled = true);
|
2154
|
-
|
2155
|
-
}
|
2156
|
-
|
2157
|
-
});
|
2158
|
-
|
2159
|
-
// if there are rules that explicitly enable dates
|
2160
|
-
if (enabled_dates)
|
2161
|
-
|
2162
|
-
// iterate through the rules for enabling dates
|
2163
|
-
$.each(enabled_dates, function() {
|
2164
|
-
|
2165
|
-
// if the date is to be enabled, don't look any further
|
2166
|
-
if (enabled) return;
|
2167
|
-
|
2168
|
-
var rule = this;
|
2169
|
-
|
2170
|
-
// if the rules apply for the current year
|
2171
|
-
if ($.inArray(year, rule[2]) > -1 || $.inArray('*', rule[2]) > -1) {
|
2172
|
-
|
2173
|
-
// the year is enabled
|
2174
|
-
enabled = true;
|
2175
|
-
|
2176
|
-
// if we're also checking months
|
2177
|
-
if (typeof month != 'undefined') {
|
2178
|
-
|
2179
|
-
// we assume the month is enabled
|
2180
|
-
enabled = true;
|
2181
|
-
|
2182
|
-
// if the rules apply for the current month
|
2183
|
-
if ($.inArray(month, rule[1]) > -1 || $.inArray('*', rule[1]) > -1) {
|
2184
|
-
|
2185
|
-
// if we're also checking days
|
2186
|
-
if (typeof day != 'undefined') {
|
2187
|
-
|
2188
|
-
// we assume the day is enabled
|
2189
|
-
enabled = true;
|
2190
|
-
|
2191
|
-
// if the rules apply for the current day
|
2192
|
-
if ($.inArray(day, rule[0]) > -1 || $.inArray('*', rule[0]) > -1) {
|
2193
|
-
|
2194
|
-
// if day is to be enabled whatever the day
|
2195
|
-
// don't look any further
|
2196
|
-
if (rule[3] == '*') return (enabled = true);
|
2197
|
-
|
2198
|
-
// get the weekday
|
2199
|
-
var weekday = new Date(year, month - 1, day).getDay();
|
2200
|
-
|
2201
|
-
// if weekday is to be enabled
|
2202
|
-
// don't look any further
|
2203
|
-
if ($.inArray(weekday, rule[3]) > -1) return (enabled = true);
|
2204
|
-
|
2205
|
-
// if we get this far, it means the day is not enabled
|
2206
|
-
enabled = false;
|
2207
|
-
|
2208
|
-
// if day is not enabled
|
2209
|
-
} else enabled = false;
|
2210
|
-
|
2211
|
-
}
|
2212
|
-
|
2213
|
-
// if month is not enabled
|
2214
|
-
} else enabled = false;
|
2215
|
-
|
2216
|
-
}
|
2217
|
-
|
2218
|
-
}
|
2219
|
-
|
2220
|
-
});
|
2221
|
-
|
2222
|
-
// if checked date is enabled, return false
|
2223
|
-
if (enabled_dates && enabled) return false;
|
2224
|
-
|
2225
|
-
// if checked date is disabled return false
|
2226
|
-
else if (disabled_dates && disabled) return true;
|
2227
|
-
|
2228
|
-
// if script gets this far it means that the day/month/year doesn't need to be disabled
|
2229
|
-
return false;
|
2230
|
-
|
2231
|
-
};
|
2232
|
-
|
2233
|
-
/**
|
2234
|
-
* Checks whether a value is an integer number.
|
2235
|
-
*
|
2236
|
-
* @param mixed value Value to check
|
2237
|
-
*
|
2238
|
-
* @return Returns TRUE if the value represents an integer number, or FALSE otherwise
|
2239
|
-
*
|
2240
|
-
* @access private
|
2241
|
-
*/
|
2242
|
-
var is_integer = function(value) {
|
2243
|
-
|
2244
|
-
// return TRUE if value represents an integer number, or FALSE otherwise
|
2245
|
-
return (value + '').match(/^\-?[0-9]+$/) ? true : false;
|
2246
|
-
|
2247
|
-
};
|
2248
|
-
|
2249
|
-
/**
|
2250
|
-
* Sets the caption in the header of the date picker and enables or disables navigation buttons when necessary.
|
2251
|
-
*
|
2252
|
-
* @param string caption String that needs to be displayed in the header
|
2253
|
-
*
|
2254
|
-
* @return void
|
2255
|
-
*
|
2256
|
-
* @access private
|
2257
|
-
*/
|
2258
|
-
var manage_header = function(caption) {
|
2259
|
-
|
2260
|
-
// update the caption in the header
|
2261
|
-
$('.dp_caption', header).html(caption);
|
2262
|
-
|
2263
|
-
// if calendar has direction restrictions or we're looking only at months
|
2264
|
-
if (!(!$.isArray(plugin.settings.direction) && to_int(plugin.settings.direction) === 0) || (views.length == 1 && views[0] == 'months')) {
|
2265
|
-
|
2266
|
-
// get the current year and month
|
2267
|
-
var year = selected_year,
|
2268
|
-
month = selected_month,
|
2269
|
-
next, previous;
|
2270
|
-
|
2271
|
-
// if current view is showing days
|
2272
|
-
if (view == 'days') {
|
2273
|
-
|
2274
|
-
// check if we can click on the "previous" button
|
2275
|
-
previous = !is_disabled(month - 1 < 0 ? str_concat(year - 1, '11') : str_concat(year, str_pad(month - 1, 2)));
|
2276
|
-
|
2277
|
-
// check if we can click on the "next" button
|
2278
|
-
next = !is_disabled(month + 1 > 11 ? str_concat(year + 1, '00') : str_concat(year, str_pad(month + 1, 2)));
|
2279
|
-
|
2280
|
-
// if current view is showing months
|
2281
|
-
} else if (view == 'months') {
|
2282
|
-
|
2283
|
-
// check if we can click on the "previous" button
|
2284
|
-
if (!start_date || start_date.getFullYear() <= year - 1) previous = true;
|
2285
|
-
|
2286
|
-
// check if we can click on the "next" button
|
2287
|
-
if (!end_date || end_date.getFullYear() >= year + 1) next = true;
|
2288
|
-
|
2289
|
-
// if current view is showing years
|
2290
|
-
} else if (view == 'years') {
|
2291
|
-
|
2292
|
-
// check if we can click on the "previous" button
|
2293
|
-
if (!start_date || start_date.getFullYear() < year - 7) previous = true;
|
2294
|
-
|
2295
|
-
// check if we can click on the "next" button
|
2296
|
-
if (!end_date || end_date.getFullYear() > year + 4) next = true;
|
2297
|
-
|
2298
|
-
}
|
2299
|
-
|
2300
|
-
// if we cannot click on the "previous" button
|
2301
|
-
if (!previous) {
|
2302
|
-
|
2303
|
-
// disable the "previous" button
|
2304
|
-
$('.dp_previous', header).addClass('dp_blocked');
|
2305
|
-
$('.dp_previous', header).removeClass('dp_hover');
|
2306
|
-
|
2307
|
-
// otherwise enable the "previous" button
|
2308
|
-
} else $('.dp_previous', header).removeClass('dp_blocked');
|
2309
|
-
|
2310
|
-
// if we cannot click on the "next" button
|
2311
|
-
if (!next) {
|
2312
|
-
|
2313
|
-
// disable the "next" button
|
2314
|
-
$('.dp_next', header).addClass('dp_blocked');
|
2315
|
-
$('.dp_next', header).removeClass('dp_hover');
|
2316
|
-
|
2317
|
-
// otherwise enable the "next" button
|
2318
|
-
} else $('.dp_next', header).removeClass('dp_blocked');
|
2319
|
-
|
2320
|
-
}
|
2321
|
-
|
2322
|
-
};
|
2323
|
-
|
2324
|
-
/**
|
2325
|
-
* Shows the appropriate view (days, months or years) according to the current value of the "view" property.
|
2326
|
-
*
|
2327
|
-
* @return void
|
2328
|
-
*
|
2329
|
-
* @access private
|
2330
|
-
*/
|
2331
|
-
var manage_views = function() {
|
2332
|
-
|
2333
|
-
// if the day picker was not yet generated
|
2334
|
-
if (daypicker.text() === '' || view == 'days') {
|
2335
|
-
|
2336
|
-
// if the day picker was not yet generated
|
2337
|
-
if (daypicker.text() === '') {
|
2338
|
-
|
2339
|
-
// if date picker is not always visible
|
2340
|
-
if (!plugin.settings.always_visible)
|
2341
|
-
|
2342
|
-
// temporarily set the date picker's left outside of view
|
2343
|
-
// so that we can later grab its width and height
|
2344
|
-
datepicker.css('left', -1000);
|
2345
|
-
|
2346
|
-
// temporarily make the date picker visible
|
2347
|
-
// so that we can later grab its width and height
|
2348
|
-
datepicker.show();
|
2349
|
-
|
2350
|
-
// generate the day picker
|
2351
|
-
generate_daypicker();
|
2352
|
-
|
2353
|
-
// get the day picker's width and height
|
2354
|
-
var width = daypicker.outerWidth(),
|
2355
|
-
height = daypicker.outerHeight();
|
2356
|
-
|
2357
|
-
// make the month picker have the same size as the day picker
|
2358
|
-
monthpicker.css({
|
2359
|
-
'width': width,
|
2360
|
-
'height': height
|
2361
|
-
});
|
2362
|
-
|
2363
|
-
// make the year picker have the same size as the day picker
|
2364
|
-
yearpicker.css({
|
2365
|
-
'width': width,
|
2366
|
-
'height': height
|
2367
|
-
});
|
2368
|
-
|
2369
|
-
// make the header and the footer have the same size as the day picker
|
2370
|
-
header.css('width', width);
|
2371
|
-
footer.css('width', width);
|
2372
|
-
|
2373
|
-
// hide the date picker again
|
2374
|
-
datepicker.hide();
|
2375
|
-
|
2376
|
-
// if the day picker was previously generated at least once
|
2377
|
-
// generate the day picker
|
2378
|
-
} else generate_daypicker();
|
2379
|
-
|
2380
|
-
// hide the year and the month pickers
|
2381
|
-
monthpicker.hide();
|
2382
|
-
yearpicker.hide();
|
2383
|
-
|
2384
|
-
// if the view is "months"
|
2385
|
-
} else if (view == 'months') {
|
2386
|
-
|
2387
|
-
// generate the month picker
|
2388
|
-
generate_monthpicker();
|
2389
|
-
|
2390
|
-
// hide the day and the year pickers
|
2391
|
-
daypicker.hide();
|
2392
|
-
yearpicker.hide();
|
2393
|
-
|
2394
|
-
// if the view is "years"
|
2395
|
-
} else if (view == 'years') {
|
2396
|
-
|
2397
|
-
// generate the year picker
|
2398
|
-
generate_yearpicker();
|
2399
|
-
|
2400
|
-
// hide the day and the month pickers
|
2401
|
-
daypicker.hide();
|
2402
|
-
monthpicker.hide();
|
2403
|
-
|
2404
|
-
}
|
2405
|
-
|
2406
|
-
// if a callback function exists for when navigating through months/years
|
2407
|
-
if (plugin.settings.onChange && typeof plugin.settings.onChange == 'function' && undefined !== view) {
|
2408
|
-
|
2409
|
-
// get the "active" elements in the view (ignoring the disabled ones)
|
2410
|
-
var elements = (view == 'days' ?
|
2411
|
-
daypicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)') :
|
2412
|
-
(view == 'months' ?
|
2413
|
-
monthpicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)') :
|
2414
|
-
yearpicker.find('td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)')));
|
2415
|
-
|
2416
|
-
// iterate through the active elements
|
2417
|
-
// and attach a "date" data attribute to each element in the form of
|
2418
|
-
// YYYY-MM-DD if the view is "days"
|
2419
|
-
// YYYY-MM if the view is "months"
|
2420
|
-
// YYYY if the view is "years"
|
2421
|
-
// so it's easy to identify elements in the list
|
2422
|
-
elements.each(function() {
|
2423
|
-
|
2424
|
-
// if view is "days"
|
2425
|
-
if (view == 'days')
|
2426
|
-
|
2427
|
-
// attach a "date" data attribute to each element in the form of of YYYY-MM-DD for easily identifying sought elements
|
2428
|
-
$(this).data('date', selected_year + '-' + str_pad(selected_month + 1, 2) + '-' + str_pad(to_int($(this).text()), 2));
|
2429
|
-
|
2430
|
-
// if view is "months"
|
2431
|
-
else if (view == 'months') {
|
2432
|
-
|
2433
|
-
// get the month's number for the element's class
|
2434
|
-
var matches = $(this).attr('class').match(/dp\_month\_([0-9]+)/);
|
2435
|
-
|
2436
|
-
// attach a "date" data attribute to each element in the form of of YYYY-MM for easily identifying sought elements
|
2437
|
-
$(this).data('date', selected_year + '-' + str_pad(to_int(matches[1]) + 1, 2));
|
2438
|
-
|
2439
|
-
// if view is "years"
|
2440
|
-
} else
|
2441
|
-
|
2442
|
-
// attach a "date" data attribute to each element in the form of of YYYY for easily identifying sought elements
|
2443
|
-
$(this).data('date', to_int($(this).text()));
|
2444
|
-
|
2445
|
-
});
|
2446
|
-
|
2447
|
-
// execute the callback function and send as arguments the current view, the elements in the view, and
|
2448
|
-
// the element the plugin is attached to
|
2449
|
-
plugin.settings.onChange(view, elements, $element);
|
2450
|
-
|
2451
|
-
}
|
2452
|
-
|
2453
|
-
// assume the footer is visible
|
2454
|
-
footer.show();
|
2455
|
-
|
2456
|
-
// if the button for clearing a previously selected date needs to be visible all the time,
|
2457
|
-
// or the "Clear" button needs to be shown only when a date was previously selected, and now it's the case,
|
2458
|
-
// or the date picker is always visible and the "Clear" button was not explicitly disabled
|
2459
|
-
if (
|
2460
|
-
plugin.settings.show_clear_date === true ||
|
2461
|
-
(plugin.settings.show_clear_date === 0 && $element.val() !== '') ||
|
2462
|
-
(plugin.settings.always_visible && plugin.settings.show_clear_date !== false)
|
2463
|
-
) {
|
2464
|
-
|
2465
|
-
// show the "Clear" button
|
2466
|
-
cleardate.show();
|
2467
|
-
|
2468
|
-
// if the "Today" button is visible
|
2469
|
-
if (show_select_today) {
|
2470
|
-
|
2471
|
-
// show it, and set it's width to 50% of the available space
|
2472
|
-
selecttoday.css('width', '50%');
|
2473
|
-
|
2474
|
-
// the "Clear date" button only takes up 50% of the available space
|
2475
|
-
cleardate.css('width', '50%');
|
2476
|
-
|
2477
|
-
// if the "Today" button is not visible
|
2478
|
-
} else {
|
2479
|
-
|
2480
|
-
// hide the "Today" button
|
2481
|
-
selecttoday.hide();
|
2482
|
-
|
2483
|
-
// the "Clear date" button takes up 100% of the available space
|
2484
|
-
cleardate.css('width', '100%');
|
2485
|
-
|
2486
|
-
}
|
2487
|
-
|
2488
|
-
// otherwise
|
2489
|
-
} else {
|
2490
|
-
|
2491
|
-
// hide the "Clear" button
|
2492
|
-
cleardate.hide();
|
2493
|
-
|
2494
|
-
// if the "Today" button is visible, it will now take up all the available space
|
2495
|
-
if (show_select_today) selecttoday.show().css('width', '100%');
|
2496
|
-
|
2497
|
-
// if the "Today" button is also not visible, hide the footer entirely
|
2498
|
-
else footer.hide();
|
2499
|
-
|
2500
|
-
}
|
2501
|
-
|
2502
|
-
|
2503
|
-
};
|
2504
|
-
|
2505
|
-
/**
|
2506
|
-
* Puts the specified date in the element the plugin is attached to, and hides the date picker.
|
2507
|
-
*
|
2508
|
-
* @param integer year The year
|
2509
|
-
*
|
2510
|
-
* @param integer month The month
|
2511
|
-
*
|
2512
|
-
* @param integer day The day
|
2513
|
-
*
|
2514
|
-
* @param string view The view from where the method was called
|
2515
|
-
*
|
2516
|
-
* @param object cell The element that was clicked
|
2517
|
-
*
|
2518
|
-
* @return void
|
2519
|
-
*
|
2520
|
-
* @access private
|
2521
|
-
*/
|
2522
|
-
var select_date = function(year, month, day, view, cell) {
|
2523
|
-
|
2524
|
-
var
|
2525
|
-
|
2526
|
-
// construct a new date object from the arguments
|
2527
|
-
default_date = new Date(year, month, day, 12, 0, 0),
|
2528
|
-
|
2529
|
-
// pointer to the cells in the current view
|
2530
|
-
view_cells = (view == 'days' ? daypicker_cells : (view == 'months' ? monthpicker_cells : yearpicker_cells)),
|
2531
|
-
|
2532
|
-
// the selected date, formatted correctly
|
2533
|
-
selected_value = format(default_date);
|
2534
|
-
|
2535
|
-
// set the currently selected and formated date as the value of the element the plugin is attached to
|
2536
|
-
$element.val(selected_value);
|
2537
|
-
|
2538
|
-
// if date picker is always visible
|
2539
|
-
if (plugin.settings.always_visible) {
|
2540
|
-
|
2541
|
-
// extract the date parts and reassign values to these variables
|
2542
|
-
// so that everything will be correctly highlighted
|
2543
|
-
default_month = default_date.getMonth();
|
2544
|
-
selected_month = default_date.getMonth();
|
2545
|
-
default_year = default_date.getFullYear();
|
2546
|
-
selected_year = default_date.getFullYear();
|
2547
|
-
default_day = default_date.getDate();
|
2548
|
-
|
2549
|
-
// remove the "selected" class from all cells in the current view
|
2550
|
-
view_cells.removeClass('dp_selected');
|
2551
|
-
|
2552
|
-
// add the "selected" class to the currently selected cell
|
2553
|
-
cell.addClass('dp_selected');
|
2554
|
-
|
2555
|
-
}
|
2556
|
-
|
2557
|
-
// hide the date picker
|
2558
|
-
plugin.hide();
|
2559
|
-
|
2560
|
-
// updates value for the date picker whose starting date depends on the selected date (if any)
|
2561
|
-
update_dependent(default_date);
|
2562
|
-
|
2563
|
-
// if a callback function exists for when selecting a date
|
2564
|
-
if (plugin.settings.onSelect && typeof plugin.settings.onSelect == 'function')
|
2565
|
-
|
2566
|
-
// execute the callback function
|
2567
|
-
plugin.settings.onSelect(selected_value, year + '-' + str_pad(month + 1, 2) + '-' + str_pad(day, 2), default_date, $element);
|
2568
|
-
|
2569
|
-
// move focus to the element the plugin is attached to
|
2570
|
-
$element.focus();
|
2571
|
-
|
2572
|
-
};
|
2573
|
-
|
2574
|
-
/**
|
2575
|
-
* Concatenates any number of arguments and returns them as string.
|
2576
|
-
*
|
2577
|
-
* @return string Returns the concatenated values.
|
2578
|
-
*
|
2579
|
-
* @access private
|
2580
|
-
*/
|
2581
|
-
var str_concat = function() {
|
2582
|
-
|
2583
|
-
var str = '';
|
2584
|
-
|
2585
|
-
// concatenate as string
|
2586
|
-
for (var i = 0; i < arguments.length; i++) str += (arguments[i] + '');
|
2587
|
-
|
2588
|
-
// return the concatenated values
|
2589
|
-
return str;
|
2590
|
-
|
2591
|
-
};
|
2592
|
-
|
2593
|
-
/**
|
2594
|
-
* Left-pad a string to a certain length with zeroes.
|
2595
|
-
*
|
2596
|
-
* @param string str The string to be padded.
|
2597
|
-
*
|
2598
|
-
* @param integer len The length to which the string must be padded
|
2599
|
-
*
|
2600
|
-
* @return string Returns the string left-padded with leading zeroes
|
2601
|
-
*
|
2602
|
-
* @access private
|
2603
|
-
*/
|
2604
|
-
var str_pad = function(str, len) {
|
2605
|
-
|
2606
|
-
// make sure argument is a string
|
2607
|
-
str += '';
|
2608
|
-
|
2609
|
-
// pad with leading zeroes until we get to the desired length
|
2610
|
-
while (str.length < len) str = '0' + str;
|
2611
|
-
|
2612
|
-
// return padded string
|
2613
|
-
return str;
|
2614
|
-
|
2615
|
-
};
|
2616
|
-
|
2617
|
-
/**
|
2618
|
-
* Returns the integer representation of a string
|
2619
|
-
*
|
2620
|
-
* @return int Returns the integer representation of the string given as argument
|
2621
|
-
*
|
2622
|
-
* @access private
|
2623
|
-
*/
|
2624
|
-
var to_int = function(str) {
|
2625
|
-
|
2626
|
-
// return the integer representation of the string given as argument
|
2627
|
-
return parseInt(str , 10);
|
2628
|
-
|
2629
|
-
};
|
2630
|
-
|
2631
|
-
/**
|
2632
|
-
* Updates the paired date picker (whose starting date depends on the value of the current date picker)
|
2633
|
-
*
|
2634
|
-
* @param date date A JavaScript date object representing the currently selected date
|
2635
|
-
*
|
2636
|
-
* @return void
|
2637
|
-
*
|
2638
|
-
* @access private
|
2639
|
-
*/
|
2640
|
-
var update_dependent = function(date) {
|
2641
|
-
|
2642
|
-
// if the pair element exists
|
2643
|
-
if (plugin.settings.pair) {
|
2644
|
-
|
2645
|
-
// iterate through the pair elements (as there may be more than just one)
|
2646
|
-
$.each(plugin.settings.pair, function() {
|
2647
|
-
|
2648
|
-
var $pair = $(this);
|
2649
|
-
|
2650
|
-
// chances are that in the beginning the pair element doesn't have the Zebra_DatePicker attached to it yet
|
2651
|
-
// (as the "start" element is usually created before the "end" element)
|
2652
|
-
// so we'll have to rely on "data" to send the starting date to the pair element
|
2653
|
-
|
2654
|
-
// therefore, if Zebra_DatePicker is not yet attached
|
2655
|
-
if (!($pair.data && $pair.data('Zebra_DatePicker')))
|
2656
|
-
|
2657
|
-
// set the starting date like this
|
2658
|
-
$pair.data('zdp_reference_date', date);
|
2659
|
-
|
2660
|
-
// if Zebra_DatePicker is attached to the pair element
|
2661
|
-
else {
|
2662
|
-
|
2663
|
-
// reference the date picker object attached to the other element
|
2664
|
-
var dp = $pair.data('Zebra_DatePicker');
|
2665
|
-
|
2666
|
-
// update the other date picker's starting date
|
2667
|
-
// the value depends on the original value of the "direction" attribute
|
2668
|
-
// (also, if the pair date picker does not have a direction, set it to 1)
|
2669
|
-
dp.update({
|
2670
|
-
'reference_date': date,
|
2671
|
-
'direction': dp.settings.direction === 0 ? 1 : dp.settings.direction
|
2672
|
-
});
|
2673
|
-
|
2674
|
-
// if the other date picker is always visible, update the visuals now
|
2675
|
-
if (dp.settings.always_visible) dp.show();
|
2676
|
-
|
2677
|
-
}
|
2678
|
-
|
2679
|
-
});
|
2680
|
-
|
2681
|
-
}
|
2682
|
-
|
2683
|
-
};
|
2684
|
-
|
2685
|
-
/**
|
2686
|
-
* Calculate the ISO 8601 week number for a given date.
|
2687
|
-
*
|
2688
|
-
* Code is based on the algorithm at http://www.tondering.dk/claus/cal/week.php#calcweekno
|
2689
|
-
*/
|
2690
|
-
var getWeekNumber = function(date) {
|
2691
|
-
|
2692
|
-
var y = date.getFullYear(),
|
2693
|
-
m = date.getMonth() + 1,
|
2694
|
-
d = date.getDate(),
|
2695
|
-
a, b, c, s, e, f, g, n, w;
|
2696
|
-
|
2697
|
-
// If month jan. or feb.
|
2698
|
-
if (m < 3) {
|
2699
|
-
|
2700
|
-
a = y - 1;
|
2701
|
-
b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
|
2702
|
-
c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
|
2703
|
-
s = b - c;
|
2704
|
-
e = 0;
|
2705
|
-
f = d - 1 + 31 * (m - 1);
|
2706
|
-
|
2707
|
-
// If month mar. through dec.
|
2708
|
-
} else {
|
2709
|
-
|
2710
|
-
a = y;
|
2711
|
-
b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
|
2712
|
-
c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
|
2713
|
-
s = b - c;
|
2714
|
-
e = s + 1;
|
2715
|
-
f = d + ((153 * (m - 3) + 2) / 5 | 0) + 58 + s;
|
2716
|
-
|
2717
|
-
}
|
2718
|
-
|
2719
|
-
g = (a + b) % 7;
|
2720
|
-
// ISO Weekday (0 is monday, 1 is tuesday etc.)
|
2721
|
-
d = (f + g - e) % 7;
|
2722
|
-
n = f + 3 - d;
|
2723
|
-
|
2724
|
-
if (n < 0) w = 53 - ((g - s) / 5 | 0);
|
2725
|
-
|
2726
|
-
else if (n > 364 + s) w = 1;
|
2727
|
-
|
2728
|
-
else w = (n / 7 | 0) + 1;
|
2729
|
-
|
2730
|
-
return w;
|
2731
|
-
|
2732
|
-
};
|
2733
|
-
|
2734
|
-
/**
|
2735
|
-
* Function to be called when the "onKeyUp" event occurs
|
2736
|
-
*
|
2737
|
-
* Why as a separate function and not inline when binding the event? Because only this way we can "unbind" it
|
2738
|
-
* if the date picker is destroyed
|
2739
|
-
*
|
2740
|
-
* @return void
|
2741
|
-
*
|
2742
|
-
* @access private
|
2743
|
-
*/
|
2744
|
-
var _keyup = function(e) {
|
2745
|
-
|
2746
|
-
// if the date picker is visible
|
2747
|
-
// and the pressed key is ESC
|
2748
|
-
// hide the date picker
|
2749
|
-
if (datepicker.css('display') == 'block' || e.which == 27) plugin.hide();
|
2750
|
-
|
2751
|
-
};
|
2752
|
-
|
2753
|
-
/**
|
2754
|
-
* Function to be called when the "onMouseDown" event occurs
|
2755
|
-
*
|
2756
|
-
* Why as a separate function and not inline when binding the event? Because only this way we can "unbind" it
|
2757
|
-
* if the date picker is destroyed
|
2758
|
-
*
|
2759
|
-
* @return void
|
2760
|
-
*
|
2761
|
-
* @access private
|
2762
|
-
*/
|
2763
|
-
var _mousedown = function(e) {
|
2764
|
-
|
2765
|
-
// if the date picker is visible
|
2766
|
-
if (datepicker.css('display') == 'block') {
|
2767
|
-
|
2768
|
-
// if the calendar icon is visible and we clicked it, let the onClick event of the icon to handle the event
|
2769
|
-
// (we want it to toggle the date picker)
|
2770
|
-
if (plugin.settings.show_icon && $(e.target).get(0) === icon.get(0)) return true;
|
2771
|
-
|
2772
|
-
// if what's clicked is not inside the date picker
|
2773
|
-
// hide the date picker
|
2774
|
-
if ($(e.target).parents().filter('.Zebra_DatePicker').length === 0) plugin.hide();
|
2775
|
-
|
2776
|
-
}
|
2777
|
-
|
2778
|
-
};
|
2779
|
-
|
2780
|
-
/**
|
2781
|
-
* Function to be called when the "onResize" event occurs
|
2782
|
-
*
|
2783
|
-
* Why as a separate function and not inline when binding the event? Because only this way we can "unbind" it
|
2784
|
-
* if the date picker is destroyed
|
2785
|
-
*
|
2786
|
-
* @return void
|
2787
|
-
*
|
2788
|
-
* @access private
|
2789
|
-
*/
|
2790
|
-
var _resize = function() {
|
2791
|
-
|
2792
|
-
// hide the date picker
|
2793
|
-
plugin.hide();
|
2794
|
-
|
2795
|
-
// we use timeouts so that we do not call the "update" method on *every* step of the resize event
|
2796
|
-
|
2797
|
-
// clear a previously set timeout
|
2798
|
-
clearTimeout(timeout);
|
2799
|
-
|
2800
|
-
// set timeout again
|
2801
|
-
timeout = setTimeout(function() {
|
2802
|
-
|
2803
|
-
// update the date picker
|
2804
|
-
plugin.update();
|
2805
|
-
|
2806
|
-
}, 100);
|
2807
|
-
|
2808
|
-
};
|
2809
|
-
|
2810
|
-
// since with jQuery 1.9.0 the $.browser object was removed, we rely on this piece of code from
|
2811
|
-
// http://www.quirksmode.org/js/detect.html to detect the browser
|
2812
|
-
var browser = {
|
2813
|
-
init: function () {
|
2814
|
-
this.name = this.searchString(this.dataBrowser) || '';
|
2815
|
-
this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || '';
|
2816
|
-
},
|
2817
|
-
searchString: function (data) {
|
2818
|
-
for (var i=0;i<data.length;i++) {
|
2819
|
-
var dataString = data[i].string;
|
2820
|
-
var dataProp = data[i].prop;
|
2821
|
-
this.versionSearchString = data[i].versionSearch || data[i].identity;
|
2822
|
-
if (dataString) {
|
2823
|
-
if (dataString.indexOf(data[i].subString) != -1)
|
2824
|
-
return data[i].identity;
|
2825
|
-
}
|
2826
|
-
else if (dataProp)
|
2827
|
-
return data[i].identity;
|
2828
|
-
}
|
2829
|
-
},
|
2830
|
-
searchVersion: function (dataString) {
|
2831
|
-
var index = dataString.indexOf(this.versionSearchString);
|
2832
|
-
if (index == -1) return;
|
2833
|
-
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
|
2834
|
-
},
|
2835
|
-
dataBrowser: [
|
2836
|
-
{
|
2837
|
-
string: navigator.userAgent,
|
2838
|
-
subString: 'Firefox',
|
2839
|
-
identity: 'firefox'
|
2840
|
-
},
|
2841
|
-
{
|
2842
|
-
string: navigator.userAgent,
|
2843
|
-
subString: 'MSIE',
|
2844
|
-
identity: 'explorer',
|
2845
|
-
versionSearch: 'MSIE'
|
2846
|
-
}
|
2847
|
-
]
|
2848
|
-
};
|
2849
|
-
|
2850
|
-
browser.init();
|
2851
|
-
|
2852
|
-
// initialize the plugin
|
2853
|
-
init();
|
2854
|
-
|
2855
|
-
};
|
2856
|
-
|
2857
|
-
$.fn.Zebra_DatePicker = function(options) {
|
2858
|
-
|
2859
|
-
// iterate through all the elements to which we need to attach the date picker to
|
2860
|
-
return this.each(function() {
|
2861
|
-
|
2862
|
-
// if element has a date picker already attached
|
2863
|
-
if (undefined !== $(this).data('Zebra_DatePicker'))
|
2864
|
-
|
2865
|
-
// remove the attached date picker
|
2866
|
-
$(this).data('Zebra_DatePicker').destroy();
|
2867
|
-
|
2868
|
-
// create an instance of the plugin
|
2869
|
-
var plugin = new $.Zebra_DatePicker(this, options);
|
2870
|
-
|
2871
|
-
// save a reference to the newly created object
|
2872
|
-
$(this).data('Zebra_DatePicker', plugin);
|
2873
|
-
|
2874
|
-
});
|
2875
|
-
|
2876
|
-
};
|
2877
|
-
|
2878
|
-
})(jQuery);
|
1
|
+
(function(c){c.Zebra_DatePicker=function(ga,ha){var ka={always_visible:!1,days:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),days_abbr:!1,direction:0,disabled_dates:!1,enabled_dates:!1,first_day_of_week:1,format:"Y-m-d",header_navigation:["«","»"],inside:!0,lang_clear_date:"Clear date",months:"January February March April May June July August September October November December".split(" "),months_abbr:!1,offset:[5,-5],pair:!1,readonly_element:!0,select_other_months:!1, show_clear_date:0,show_icon:!0,show_other_months:!0,show_select_today:"Today",show_week_number:!1,start_date:!1,strict:!1,view:"days",weekend_days:[0,6],zero_pad:!1,onChange:null,onClear:null,onSelect:null},t,h,w,C,D,G,H,S,T,N,Z,g,q,y,u,p,U,J,K,V,F,$,r,v,aa,O,W,la,ma,na,A,ia,ba,X,ca,oa,a=this;a.settings={};var d=c(ga),ra=function(e){if(!e){a.settings=c.extend({},ka,ha);for(var b in d.data())0===b.indexOf("zdp_")&&(b=b.replace(/^zdp\_/,""),void 0!==ka[b]&&(a.settings[b]=d.data("zdp_"+b)))}a.settings.readonly_element&& d.attr("readonly","readonly");b={days:["d","j","D"],months:["F","m","M","n","t"],years:["o","Y","y"]};var z=!1,f=!1,k=!1,E=null;for(E in b)c.each(b[E],function(c,b){-1<a.settings.format.indexOf(b)&&("days"==E?z=!0:"months"==E?f=!0:"years"==E&&(k=!0))});A=z&&f&&k?["years","months","days"]:!z&&f&&k?["years","months"]:z||f||!k?z||!f||k?["years","months","days"]:["months"]:["years"];-1==c.inArray(a.settings.view,A)&&(a.settings.view=A[A.length-1]);F=[];V=[];for(var n=0;2>n;n++)b=0===n?a.settings.disabled_dates: a.settings.enabled_dates,c.isArray(b)&&0<b.length&&c.each(b,function(){for(var a=this.split(" "),b=0;4>b;b++){a[b]||(a[b]="*");a[b]=-1<a[b].indexOf(",")?a[b].split(","):Array(a[b]);for(var e=0;e<a[b].length;e++)if(-1<a[b][e].indexOf("-")){var z=a[b][e].match(/^([0-9]+)\-([0-9]+)/);if(null!==z){for(var f=s(z[1]);f<=s(z[2]);f++)-1==c.inArray(f,a[b])&&a[b].push(f+"");a[b].splice(e,1)}}for(e=0;e<a[b].length;e++)a[b][e]=isNaN(s(a[b][e]))?a[b][e]:s(a[b][e])}0===n?F.push(a):V.push(a)});b=new Date;var m= a.settings.reference_date?a.settings.reference_date:d.data("zdp_reference_date")&&void 0!==d.data("zdp_reference_date")?d.data("zdp_reference_date"):b,l,L;v=r=void 0;g=m.getMonth();T=b.getMonth();q=m.getFullYear();N=b.getFullYear();y=m.getDate();Z=b.getDate();if(!0===a.settings.direction)r=m;else if(!1===a.settings.direction)v=m,W=v.getMonth(),O=v.getFullYear(),aa=v.getDate();else if(!c.isArray(a.settings.direction)&&Y(a.settings.direction)&&0<s(a.settings.direction)||c.isArray(a.settings.direction)&& ((l=da(a.settings.direction[0]))||!0===a.settings.direction[0]||Y(a.settings.direction[0])&&0<a.settings.direction[0])&&((L=da(a.settings.direction[1]))||!1===a.settings.direction[1]||Y(a.settings.direction[1])&&0<=a.settings.direction[1]))r=l?l:new Date(q,g,y+(c.isArray(a.settings.direction)?s(!0===a.settings.direction[0]?0:a.settings.direction[0]):s(a.settings.direction))),g=r.getMonth(),q=r.getFullYear(),y=r.getDate(),L&&+L>=+r?v=L:!L&&!1!==a.settings.direction[1]&&c.isArray(a.settings.direction)&& (v=new Date(q,g,y+s(a.settings.direction[1]))),v&&(W=v.getMonth(),O=v.getFullYear(),aa=v.getDate());else if(!c.isArray(a.settings.direction)&&Y(a.settings.direction)&&0>s(a.settings.direction)||c.isArray(a.settings.direction)&&(!1===a.settings.direction[0]||Y(a.settings.direction[0])&&0>a.settings.direction[0])&&((l=da(a.settings.direction[1]))||Y(a.settings.direction[1])&&0<=a.settings.direction[1]))v=new Date(q,g,y+(c.isArray(a.settings.direction)?s(!1===a.settings.direction[0]?0:a.settings.direction[0]): s(a.settings.direction))),W=v.getMonth(),O=v.getFullYear(),aa=v.getDate(),l&&+l<+v?r=l:!l&&c.isArray(a.settings.direction)&&(r=new Date(O,W,aa-s(a.settings.direction[1]))),r&&(g=r.getMonth(),q=r.getFullYear(),y=r.getDate());else if(c.isArray(a.settings.disabled_dates)&&0<a.settings.disabled_dates.length)for(var P in F)if("*"==F[P][0]&&"*"==F[P][1]&&"*"==F[P][2]&&"*"==F[P][3]){var fa=[];c.each(V,function(){"*"!=this[2][0]&&fa.push(parseInt(this[2][0]+("*"==this[1][0]?"12":x(this[1][0],2))+("*"==this[0][0]? "*"==this[1][0]?"31":(new Date(this[2][0],this[1][0],0)).getDate():x(this[0][0],2)),10))});fa.sort();if(0<fa.length){var Q=(fa[0]+"").match(/([0-9]{4})([0-9]{2})([0-9]{2})/);q=parseInt(Q[1],10);g=parseInt(Q[2],10)-1;y=parseInt(Q[3],10)}break}if(B(q,g,y)){for(;B(q);)r?(q++,g=0):(q--,g=11);for(;B(q,g);)r?(g++,y=1):(g--,y=(new Date(q,g+1,0)).getDate()),11<g?(q++,g=0,y=1):0>g&&(q--,g=11,y=(new Date(q,g+1,0)).getDate());for(;B(q,g,y);)r?y++:y--,b=new Date(q,g,y),q=b.getFullYear(),g=b.getMonth(),y=b.getDate(); b=new Date(q,g,y);q=b.getFullYear();g=b.getMonth();y=b.getDate()}(l=da(d.val()||(a.settings.start_date?a.settings.start_date:"")))&&a.settings.strict&&B(l.getFullYear(),l.getMonth(),l.getDate())&&d.val("");e||pa(r);if(!a.settings.always_visible&&(e||(a.settings.show_icon?("firefox"==M.name&&d.is('input[type="text"]')&&"inline"==d.css("display")&&d.css("display","inline-block"),l=jQuery('<span class="Zebra_DatePicker_Icon_Wrapper"></span>').css({display:d.css("display"),position:"static"==d.css("position")? "relative":d.css("position"),"float":d.css("float"),top:d.css("top"),right:d.css("right"),bottom:d.css("bottom"),left:d.css("left")}),d.wrap(l).css({position:"relative",top:"auto",right:"auto",bottom:"auto",left:"auto"}),w=jQuery('<button type="button" class="Zebra_DatePicker_Icon'+("disabled"==d.attr("disabled")?" Zebra_DatePicker_Icon_Disabled":"")+'">Pick a date</button>'),a.icon=w,ia=w.add(d)):ia=d,ia.bind("click",function(b){b.preventDefault();d.attr("disabled")||("none"!=h.css("display")?a.hide(): a.show())}),void 0!==w&&w.insertAfter(d)),void 0!==w)){w.attr("style","");a.settings.inside&&w.addClass("Zebra_DatePicker_Icon_Inside");l=d.outerWidth();L=d.outerHeight();P=parseInt(d.css("marginLeft"),10)||0;b=parseInt(d.css("marginTop"),10)||0;var m=w.outerWidth(),qa=w.outerHeight(),ua=parseInt(w.css("marginLeft"),10)||0,va=parseInt(w.css("marginRight"),10)||0;a.settings.inside?w.css({top:b+(L-qa)/2,left:P+(l-m-va)}):w.css({top:b+(L-qa)/2,left:P+l+ua})}ca=!1!==a.settings.show_select_today&&-1<c.inArray("days", A)&&!B(N,T,Z)?a.settings.show_select_today:!1;e||(c(window).bind("resize.Zebra_DatePicker",function(){a.hide();void 0!==w&&(clearTimeout(oa),oa=setTimeout(function(){a.update()},100))}),h=c('<div class="Zebra_DatePicker"><table class="dp_header"><tr><td class="dp_previous">'+a.settings.header_navigation[0]+'</td><td class="dp_caption"> </td><td class="dp_next">'+a.settings.header_navigation[1]+'</td></tr></table><table class="dp_daypicker"></table><table class="dp_monthpicker"></table><table class="dp_yearpicker"></table><table class="dp_footer"><tr><td class="dp_today"'+ (!1!==a.settings.show_clear_date?' style="width:50%"':"")+">"+ca+'</td><td class="dp_clear"'+(!1!==ca?' style="width:50%"':"")+">"+a.settings.lang_clear_date+"</td></tr></table></div>"),a.datepicker=h,C=c("table.dp_header",h),D=c("table.dp_daypicker",h),G=c("table.dp_monthpicker",h),H=c("table.dp_yearpicker",h),X=c("table.dp_footer",h),ba=c("td.dp_today",X),S=c("td.dp_clear",X),a.settings.always_visible?d.attr("disabled")||(a.settings.always_visible.append(h),a.show()):c("body").append(h),h.delegate("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)", "mouseover",function(){c(this).addClass("dp_hover")}).delegate("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)","mouseout",function(){c(this).removeClass("dp_hover")}),wa(c("td",C)),c(".dp_previous",C).bind("click",function(){c(this).hasClass("dp_blocked")||("months"==t?p--:"years"==t?p-=12:0>--u&&(u=11,p--),R())}),c(".dp_caption",C).bind("click",function(){t="days"==t?-1<c.inArray("months",A)?"months":-1<c.inArray("years",A)?"years":"days":"months"==t? -1<c.inArray("years",A)?"years":-1<c.inArray("days",A)?"days":"months":-1<c.inArray("days",A)?"days":-1<c.inArray("months",A)?"months":"years";R()}),c(".dp_next",C).bind("click",function(){c(this).hasClass("dp_blocked")||("months"==t?p++:"years"==t?p+=12:12==++u&&(u=0,p++),R())}),D.delegate("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_week_number)","click",function(){a.settings.select_other_months&&null!==(Q=c(this).attr("class").match(/date\_([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/))? ea(Q[1],Q[2]-1,Q[3],"days",c(this)):ea(p,u,s(c(this).html()),"days",c(this))}),G.delegate("td:not(.dp_disabled)","click",function(){var b=c(this).attr("class").match(/dp\_month\_([0-9]+)/);u=s(b[1]);-1==c.inArray("days",A)?ea(p,u,1,"months",c(this)):(t="days",a.settings.always_visible&&d.val(""),R())}),H.delegate("td:not(.dp_disabled)","click",function(){p=s(c(this).html());-1==c.inArray("months",A)?ea(p,1,1,"years",c(this)):(t="months",a.settings.always_visible&&d.val(""),R())}),c(ba).bind("click", function(b){b.preventDefault();ea(N,T,Z,"days",c(".dp_current",D));a.settings.always_visible&&a.show();a.hide()}),c(S).bind("click",function(b){b.preventDefault();d.val("");a.settings.always_visible?(K=J=U=null,c("td.dp_selected",h).removeClass("dp_selected")):p=u=K=J=U=null;a.hide();if(a.settings.onClear&&"function"==typeof a.settings.onClear)a.settings.onClear(d)}),a.settings.always_visible||c(document).bind({"mousedown.Zebra_DatePicker":function(b){if("block"==h.css("display")){if(a.settings.show_icon&& c(b.target).get(0)===w.get(0))return!0;0===c(b.target).parents().filter(".Zebra_DatePicker").length&&a.hide()}},"keyup.Zebra_DatePicker":function(b){"block"!=h.css("display")&&27!=b.which||a.hide()}}),R())};a.destroy=function(){void 0!==a.icon&&a.icon.remove();a.datepicker.remove();c(document).unbind("keyup.Zebra_DatePicker");c(document).unbind("mousedown.Zebra_DatePicker");c(window).unbind("resize.Zebra_DatePicker");d.removeData("Zebra_DatePicker");delete a};a.hide=function(){a.settings.always_visible|| (sa("hide"),h.hide())};a.show=function(){t=a.settings.view;var e=da(d.val()||(a.settings.start_date?a.settings.start_date:""));e?(J=e.getMonth(),u=e.getMonth(),K=e.getFullYear(),p=e.getFullYear(),U=e.getDate(),B(K,J,U)&&(a.settings.strict&&d.val(""),u=g,p=q)):(u=g,p=q);R();if(a.settings.always_visible)h.show();else{var e=h.outerWidth(),b=h.outerHeight(),z=(void 0!==w?w.offset().left+w.outerWidth(!0):d.offset().left+d.outerWidth(!0))+a.settings.offset[0],f=(void 0!==w?w.offset().top:d.offset().top)- b+a.settings.offset[1],k=c(window).width(),E=c(window).height(),n=c(window).scrollTop(),m=c(window).scrollLeft();z+e>m+k&&(z=m+k-e);z<m&&(z=m);f+b>n+E&&(f=n+E-b);f<n&&(f=n);h.css({left:z,top:f});h.fadeIn("explorer"==M.name&&9>M.version?0:150,"linear");sa()}};a.update=function(e){a.original_direction&&(a.original_direction=a.direction);a.settings=c.extend(a.settings,e);ra(!0)};var da=function(e){e+="";if(""!==c.trim(e)){for(var b=a.settings.format.replace(/([-.,*+?^${}()|[\]\/\\])/g,"\\$1"),z="dDjlNSwFmMnYy".split(""), f=[],k=[],E=null,n=null,m=0;m<z.length;m++)-1<(E=b.indexOf(z[m]))&&f.push({character:z[m],position:E});f.sort(function(a,b){return a.position-b.position});c.each(f,function(a,b){switch(b.character){case "d":k.push("0[1-9]|[12][0-9]|3[01]");break;case "D":k.push("[a-z]{3}");break;case "j":k.push("[1-9]|[12][0-9]|3[01]");break;case "l":k.push("[a-z]+");break;case "N":k.push("[1-7]");break;case "S":k.push("st|nd|rd|th");break;case "w":k.push("[0-6]");break;case "F":k.push("[a-z]+");break;case "m":k.push("0[1-9]|1[012]+"); break;case "M":k.push("[a-z]{3}");break;case "n":k.push("[1-9]|1[012]");break;case "Y":k.push("[0-9]{4}");break;case "y":k.push("[0-9]{2}")}});if(k.length&&(f.reverse(),c.each(f,function(a,c){b=b.replace(c.character,"("+k[k.length-a-1]+")")}),k=RegExp("^"+b+"$","ig"),n=k.exec(e))){e=new Date;var l=e.getDate(),d=e.getMonth()+1,p=e.getFullYear(),g="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),h="January February March April May June July August September October November December".split(" "), q,u=!0;f.reverse();c.each(f,function(b,e){if(!u)return!0;switch(e.character){case "m":case "n":d=s(n[b+1]);break;case "d":case "j":l=s(n[b+1]);break;case "D":case "l":case "F":case "M":q="D"==e.character||"l"==e.character?a.settings.days:a.settings.months;u=!1;c.each(q,function(a,c){if(u)return!0;if(n[b+1].toLowerCase()==c.substring(0,"D"==e.character||"M"==e.character?3:c.length).toLowerCase()){switch(e.character){case "D":n[b+1]=g[a].substring(0,3);break;case "l":n[b+1]=g[a];break;case "F":n[b+ 1]=h[a];d=a+1;break;case "M":n[b+1]=h[a].substring(0,3),d=a+1}u=!0}});break;case "Y":p=s(n[b+1]);break;case "y":p="19"+s(n[b+1])}});if(u&&(f=new Date(p,(d||1)-1,l||1),f.getFullYear()==p&&f.getDate()==(l||1)&&f.getMonth()==(d||1)-1))return f}return!1}},wa=function(a){"firefox"==M.name?a.css("MozUserSelect","none"):"explorer"==M.name?a.bind("selectstart",function(){return!1}):a.mousedown(function(){return!1})},ta=function(){var e=(new Date(p,u+1,0)).getDate(),b=(new Date(p,u,1)).getDay(),z=(new Date(p, u,0)).getDate(),b=b-a.settings.first_day_of_week,b=0>b?7+b:b;ja(a.settings.months[u]+", "+p);var f="<tr>";a.settings.show_week_number&&(f+="<th>"+a.settings.show_week_number+"</th>");for(var k=0;7>k;k++)f+="<th>"+(c.isArray(a.settings.days_abbr)&&void 0!==a.settings.days_abbr[(a.settings.first_day_of_week+k)%7]?a.settings.days_abbr[(a.settings.first_day_of_week+k)%7]:a.settings.days[(a.settings.first_day_of_week+k)%7].substr(0,2))+"</th>";f+="</tr><tr>";for(k=0;42>k;k++){0<k&&0===k%7&&(f+="</tr><tr>"); if(0===k%7&&a.settings.show_week_number){var d=new Date(p,u,k-b+1),n=d.getFullYear(),m=d.getMonth()+1,d=d.getDate(),l=void 0,g=void 0,h=void 0,s=h=void 0,q=void 0,h=g=l=void 0;3>m?(l=n-1,g=(l/4|0)-(l/100|0)+(l/400|0),h=((l-1)/4|0)-((l-1)/100|0)+((l-1)/400|0),h=g-h,s=0,q=d-1+31*(m-1)):(l=n,g=(l/4|0)-(l/100|0)+(l/400|0),h=((l-1)/4|0)-((l-1)/100|0)+((l-1)/400|0),h=g-h,s=h+1,q=d+((153*(m-3)+2)/5|0)+58+h);l=(l+g)%7;d=(q+l-s)%7;g=q+3-d;h=0>g?53-((l-h)/5|0):g>364+h?1:(g/7|0)+1;f+='<td class="dp_week_number">'+ h+"</td>"}n=k-b+1;if(a.settings.select_other_months&&(k<b||n>e))var r=new Date(p,u,n),v=r.getFullYear(),t=r.getMonth(),w=r.getDate(),r=v+x(t+1,2)+x(w,2);k<b?f+='<td class="'+(a.settings.select_other_months&&!B(v,t,w)?"dp_not_in_month_selectable date_"+r:"dp_not_in_month")+'">'+(a.settings.select_other_months||a.settings.show_other_months?x(z-b+k+1,a.settings.zero_pad?2:0):" ")+"</td>":n>e?f+='<td class="'+(a.settings.select_other_months&&!B(v,t,w)?"dp_not_in_month_selectable date_"+r:"dp_not_in_month")+ '">'+(a.settings.select_other_months||a.settings.show_other_months?x(n-e,a.settings.zero_pad?2:0):" ")+"</td>":(m=(a.settings.first_day_of_week+k)%7,d="",B(p,u,n)?(d=-1<c.inArray(m,a.settings.weekend_days)?"dp_weekend_disabled":d+" dp_disabled",u==T&&p==N&&Z==n&&(d+=" dp_disabled_current")):(-1<c.inArray(m,a.settings.weekend_days)&&(d="dp_weekend"),u==J&&p==K&&U==n&&(d+=" dp_selected"),u==T&&p==N&&Z==n&&(d+=" dp_current")),f+="<td"+(""!==d?' class="'+c.trim(d)+'"':"")+">"+(a.settings.zero_pad? x(n,2):n)+"</td>")}D.html(c(f+"</tr>"));a.settings.always_visible&&(la=c("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked, .dp_week_number)",D));D.show()},xa=function(){ja(p);for(var e="<tr>",b=0;12>b;b++){0<b&&0===b%3&&(e+="</tr><tr>");var d="dp_month_"+b;B(p,b)?d+=" dp_disabled":!1!==J&&J==b?d+=" dp_selected":T==b&&N==p&&(d+=" dp_current");e+='<td class="'+c.trim(d)+'">'+(c.isArray(a.settings.months_abbr)&&void 0!==a.settings.months_abbr[b]?a.settings.months_abbr[b]:a.settings.months[b].substr(0, 3))+"</td>"}G.html(c(e+"</tr>"));a.settings.always_visible&&(ma=c("td:not(.dp_disabled)",G));G.show()},ya=function(){ja(p-7+" - "+(p+4));for(var e="<tr>",b=0;12>b;b++){0<b&&0===b%3&&(e+="</tr><tr>");var d="";B(p-7+b)?d+=" dp_disabled":K&&K==p-7+b?d+=" dp_selected":N==p-7+b&&(d+=" dp_current");e+="<td"+(""!==c.trim(d)?' class="'+c.trim(d)+'"':"")+">"+(p-7+b)+"</td>"}H.html(c(e+"</tr>"));a.settings.always_visible&&(na=c("td:not(.dp_disabled)",H));H.show()},sa=function(a){if("explorer"==M.name&&6==M.version){if(!$){var b= s(h.css("zIndex"))-1;$=jQuery("<iframe>",{src:'javascript:document.write("")',scrolling:"no",frameborder:0,allowtransparency:"true",css:{zIndex:b,position:"absolute",top:-1E3,left:-1E3,width:h.outerWidth(),height:h.outerHeight(),filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)",display:"none"}});c("body").append($)}switch(a){case "hide":$.hide();break;default:a=h.offset(),$.css({top:a.top,left:a.left,display:"block"})}}},B=function(e,b,d){if((void 0===e||isNaN(e))&&(void 0===b||isNaN(b))&& (void 0===d||isNaN(d)))return!1;if(c.isArray(a.settings.direction)||0!==s(a.settings.direction)){var f=s(I(e,"undefined"!=typeof b?x(b,2):"","undefined"!=typeof d?x(d,2):"")),k=(f+"").length;if(8==k&&("undefined"!=typeof r&&f<s(I(q,x(g,2),x(y,2)))||"undefined"!=typeof v&&f>s(I(O,x(W,2),x(aa,2))))||6==k&&("undefined"!=typeof r&&f<s(I(q,x(g,2)))||"undefined"!=typeof v&&f>s(I(O,x(W,2))))||4==k&&("undefined"!=typeof r&&f<q||"undefined"!=typeof v&&f>O))return!0}"undefined"!=typeof b&&(b+=1);var h=!1,n= !1;F&&c.each(F,function(){if(!h&&(-1<c.inArray(e,this[2])||-1<c.inArray("*",this[2]))&&("undefined"!=typeof b&&-1<c.inArray(b,this[1])||-1<c.inArray("*",this[1]))&&("undefined"!=typeof d&&-1<c.inArray(d,this[0])||-1<c.inArray("*",this[0]))){if("*"==this[3])return h=!0;var a=(new Date(e,b-1,d)).getDay();if(-1<c.inArray(a,this[3]))return h=!0}});V&&c.each(V,function(){if(!n&&(-1<c.inArray(e,this[2])||-1<c.inArray("*",this[2]))&&(n=!0,"undefined"!=typeof b))if(n=!0,-1<c.inArray(b,this[1])||-1<c.inArray("*", this[1])){if("undefined"!=typeof d){n=!0;if(-1<c.inArray(d,this[0])||-1<c.inArray("*",this[0])){if("*"==this[3])return n=!0;var a=(new Date(e,b-1,d)).getDay();if(-1<c.inArray(a,this[3]))return n=!0}n=!1}}else n=!1});return V&&n||!F||!h?!1:!0},Y=function(a){return(a+"").match(/^\-?[0-9]+$/)?!0:!1},ja=function(e){c(".dp_caption",C).html(e);if(c.isArray(a.settings.direction)||0!==s(a.settings.direction)||1==A.length&&"months"==A[0]){e=p;var b=u,d,f;if("days"==t)f=!B(0>b-1?I(e-1,"11"):I(e,x(b-1,2))), d=!B(11<b+1?I(e+1,"00"):I(e,x(b+1,2)));else if("months"==t){if(!r||r.getFullYear()<=e-1)f=!0;if(!v||v.getFullYear()>=e+1)d=!0}else if("years"==t){if(!r||r.getFullYear()<e-7)f=!0;if(!v||v.getFullYear()>e+4)d=!0}f?c(".dp_previous",C).removeClass("dp_blocked"):(c(".dp_previous",C).addClass("dp_blocked"),c(".dp_previous",C).removeClass("dp_hover"));d?c(".dp_next",C).removeClass("dp_blocked"):(c(".dp_next",C).addClass("dp_blocked"),c(".dp_next",C).removeClass("dp_hover"))}},R=function(){if(""===D.text()|| "days"==t){if(""===D.text()){a.settings.always_visible||h.css("left",-1E3);h.show();ta();var e=D.outerWidth(),b=D.outerHeight();G.css({width:e,height:b});H.css({width:e,height:b});C.css("width",e);X.css("width",e);h.hide()}else ta();G.hide();H.hide()}else"months"==t?(xa(),D.hide(),H.hide()):"years"==t&&(ya(),D.hide(),G.hide());a.settings.onChange&&"function"==typeof a.settings.onChange&&void 0!==t&&(e="days"==t?D.find("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)"):"months"== t?G.find("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)"):H.find("td:not(.dp_disabled, .dp_weekend_disabled, .dp_not_in_month, .dp_blocked)"),e.each(function(){if("days"==t)if(c(this).hasClass("dp_not_in_month_selectable")){var a=c(this).attr("class").match(/date\_([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/);c(this).data("date",a[1]+"-"+a[2]+"-"+a[3])}else c(this).data("date",p+"-"+x(u+1,2)+"-"+x(s(c(this).text()),2));else"months"==t?(a=c(this).attr("class").match(/dp\_month\_([0-9]+)/), c(this).data("date",p+"-"+x(s(a[1])+1,2))):c(this).data("date",s(c(this).text()))}),a.settings.onChange(t,e,d));X.show();!0===a.settings.show_clear_date||0===a.settings.show_clear_date&&""!==d.val()||a.settings.always_visible&&!1!==a.settings.show_clear_date?(S.show(),ca?(ba.css("width","50%"),S.css("width","50%")):(ba.hide(),S.css("width","100%"))):(S.hide(),ca?ba.show().css("width","100%"):X.hide())},ea=function(e,b,h,f,k){var g=new Date(e,b,h,12,0,0),n="days"==f?la:"months"==f?ma:na,m;m="";for(var l= g.getDate(),q=g.getDay(),s=a.settings.days[q],r=g.getMonth()+1,v=a.settings.months[r-1],t=g.getFullYear()+"",w=0;w<a.settings.format.length;w++){var y=a.settings.format.charAt(w);switch(y){case "y":t=t.substr(2);case "Y":m+=t;break;case "m":r=x(r,2);case "n":m+=r;break;case "M":v=c.isArray(a.settings.months_abbr)&&void 0!==a.settings.months_abbr[r-1]?a.settings.months_abbr[r-1]:a.settings.months[r-1].substr(0,3);case "F":m+=v;break;case "d":l=x(l,2);case "j":m+=l;break;case "D":s=c.isArray(a.settings.days_abbr)&& void 0!==a.settings.days_abbr[q]?a.settings.days_abbr[q]:a.settings.days[q].substr(0,3);case "l":m+=s;break;case "N":q++;case "w":m+=q;break;case "S":m=1==l%10&&"11"!=l?m+"st":2==l%10&&"12"!=l?m+"nd":3==l%10&&"13"!=l?m+"rd":m+"th";break;default:m+=y}}d.val(m);a.settings.always_visible&&(J=g.getMonth(),u=g.getMonth(),K=g.getFullYear(),p=g.getFullYear(),U=g.getDate(),n.removeClass("dp_selected"),k.addClass("dp_selected"),"days"==f&&k.hasClass("dp_not_in_month_selectable")&&a.show());a.hide();pa(g); if(a.settings.onSelect&&"function"==typeof a.settings.onSelect)a.settings.onSelect(m,e+"-"+x(b+1,2)+"-"+x(h,2),g,d);d.focus()},I=function(){for(var a="",b=0;b<arguments.length;b++)a+=arguments[b]+"";return a},x=function(a,b){for(a+="";a.length<b;)a="0"+a;return a},s=function(a){return parseInt(a,10)},pa=function(e){a.settings.pair&&c.each(a.settings.pair,function(){var a=c(this);a.data&&a.data("Zebra_DatePicker")?(a=a.data("Zebra_DatePicker"),a.update({reference_date:e,direction:0===a.settings.direction? 1:a.settings.direction}),a.settings.always_visible&&a.show()):a.data("zdp_reference_date",e)})},M={init:function(){this.name=this.searchString(this.dataBrowser)||"";this.version=this.searchVersion(navigator.userAgent)||this.searchVersion(navigator.appVersion)||""},searchString:function(a){for(var b=0;b<a.length;b++){var c=a[b].string,d=a[b].prop;this.versionSearchString=a[b].versionSearch||a[b].identity;if(c){if(-1!=c.indexOf(a[b].subString))return a[b].identity}else if(d)return a[b].identity}},searchVersion:function(a){var b= a.indexOf(this.versionSearchString);if(-1!=b)return parseFloat(a.substring(b+this.versionSearchString.length+1))},dataBrowser:[{string:navigator.userAgent,subString:"Firefox",identity:"firefox"},{string:navigator.userAgent,subString:"MSIE",identity:"explorer",versionSearch:"MSIE"}]};M.init();ra()};c.fn.Zebra_DatePicker=function(ga){return this.each(function(){void 0!==c(this).data("Zebra_DatePicker")&&c(this).data("Zebra_DatePicker").destroy();var ha=new c.Zebra_DatePicker(this,ga);c(this).data("Zebra_DatePicker", ha)})}})(jQuery);
|